Ended · 38 subagents
Move issues to workspace-level Work items #155
Issues move out of repositories and become work items: workspace-level, any kind of work (feature, bug, chore), and able to span several repositories. Pull requests stay in repositories and do the change.
Decided (syntaqx, 2026-10-17)
- Name: work items, under a top-level Work entry in the rail, right after Home. "Issue" goes from every surface and internal name.
- No deprecated aliases. The one exception: existing links keep resolving: old
/:owner/:repo/issues/:nURLs,owner/repo#Nand#Nin existing text, andCloses #Nin history. - Migrate to the final state. Every existing issue becomes a work item in its repository's workspace. It keeps a permanent origin link to that repository, recording its old number, and every reference to it is rewritten.
- Numbering: one sequence per workspace, shared by work items and new pull requests, so
#Nis unambiguous from any repository. It starts above every number already used in the workspace. Existing pull requests keep their numbers. - Many repositories → one work item. Each link has a role:
origin(where it was filed),target(where the work should land) ortouched(where its work landed).Closes #Nmarks that repository as landed, and the item closes once every target has landed.Part of #Nlinks without closing. - Labels and milestones move to the workspace.
- Personal accounts: no special case. Every repository is in a workspace, and a person's own is their personal workspace.
- Visibility: workspace members see every work item. Anyone who can read the origin repository sees the items filed there, so public repositories' items stay public.
- Sessions relate to work items: a session is recorded against the checkout it runs in, and its work item belongs to the workspace.
Plan
- Contracts and the work service:
- the schema migration
- a backfill job that numbers items per workspace, needed because the work database doesn't know which workspace a repository is in
- workspace numbering, labels and milestones
- access
- closing across repositories
- claims, sessions and dependencies keyed by work item
- resolving old references
- API, MCP (the
work_itemtool) and CLI (g1t work …). - Web: the Work list, item and new pages; redirects from the old repository pages; Sessions moves to
/:owner/:repo/sessions. - Other services: search, inbox, integrations, webhooks (
work_item.*), Actions triggers (work_item,work_item_comment), security, deployments. - Docs and plugins (done on a branch: the work-on-item skill, the guides, the reference and a migration note).
Status
- Docs and plugins: done, not pushed yet.
- Contracts and the work service: in progress.
- Stages 2–4 start when stage 1 lands.
Repositories
No pull request for it here yet.
Discussion
Progress: stage 1 is done on the local work-items branch (not pushed yet).
- Contracts:
WorkItem,ItemRepowith origin, target and touched roles,Resolution,RefTarget, and workspace access throughitem_role. - Work service: migration
0049_work_items, plus a cron job that numbers existing issues in each workspace above every number already used there. It merges labels and renumbers milestones, and announces the moves withwork.migrated. - Closing:
Closes #Nmarks that repository as landed. The item closes when every target has landed.Part of #Nlinks without closing. - Tests: contracts 337 and work 223 passed. They cover colliding numbers, numbering order, resolving old references, closing across several targets, and pull request numbers after a transfer.
- Docs and plugins: done (the
work-on-itemskill, the guides, the reference, and a migration note).
Stage 2 is running in parallel:
- API, MCP (
work_item) and the CLI (g1t work …) - web: Work in the rail after Home, mobile tabs Home, Work, Chat, Notifications and More, and redirects from the old issue pages
- the native mobile app
- the other services: search, inbox, integrations, webhooks, Actions triggers
work_itemandwork_item_comment, security and the rest
One decision changed from the plan: while the backfill job runs, opening work items and editing labels or milestones are refused with still_moving. That avoids numbering collisions during the short window after deploy.
Decision: where work items live in the code. Work items become their own bounded part of the code: their own contracts module (work/items.rs, work/refs.rs) and their own module in the work service, reached through a small interface. They are not a separate worker with its own database yet.
Why: merging a pull request and landing it on its work item happen in one write, in the database the pull requests already use. Splitting now would mean copying the data between two databases during the migration, and closing on merge would turn into an event that can arrive late or not at all. The boundary is drawn so that a later split only moves that module and swaps its interface for RPC calls.
Also: 1Password commit signing is failing on this machine, so stage 2 is being integrated and tested uncommitted on work-items. Each part's patch and commit messages are kept so it can be committed in its intended split once signing works.
Status: 42 signed commits on the local work-items branch, not pushed. That covers stage 1, stage 2, the items module, the gap fixes and the docs. Final checks:
- 2964 Rust tests pass, and every worker passes its wasm check.
- Web 1046, mobile 16, plugins 60 and scripts 32 tests pass. Three failures predate this branch and fail the same way on
main. - Every migration applies on fresh databases, and a work database seeded with old-shape issues migrates correctly.
- The docs build with no broken links.
Decided by syntaqx:
- The rail has Work (work items: the list, a board, labels and milestones) and, right after it, Sessions: everything cooking across the workspace, whatever started it (Claude Code, Codex and others, sessions started on g1t, subagents).
- Sessions replaces the repository's old Work page, and the old repository pages go with no redirects.
- Old issue links,
#Nandowner/repo#Nstill resolve.
Also in progress: session titles settle on the whole of the work, instead of chasing the latest prompt. g1t settles them from the session's record, using the workspace's AI or a fallback. A person's title is never replaced, and the hook stops nudging agents to retitle every few prompts.
Sessions and session titles are built and verified on work-items.
Not committed yet: 1Password is locked, so nothing can be signed. The state is pinned as refs/wip/work-items-final, and a script makes the six signed commits once it unlocks.
What's in it:
- Sessions is in the rail right after Work. It shows everything going on in the workspace, whatever started it: Live now, the merge queues, just landed, what happened, and each session's own page.
- The repository's old Sessions and Work pages are deleted, with no redirects.
- Work gains a Board (Backlog, In progress, In review, Landing, Done) and a Cooking now strip.
- On a phone, Sessions is first in More. The native app has Items and Board, plus Sessions.
- Titles settle on the whole of the work instead of the latest prompt. g1t names them with the workspace's AI provider, or falls back to the work item, then the pull request, then the most telling prompt. A title someone sets is never replaced.
Checks:
- Rust: 2993 passed, 0 failed, and the wasm checks pass.
- Web 1054/1054, mobile 30/30, contracts 48/48, plugin hooks 57/57.
- 2832 docs links checked, all resolve.
ses_01m560bz6eeqc8v1hrrha03pap· Shipped: on main at 4a47b56d and deployed by Deploy #428 (migrations, every Worker, smoke test). Old links redirect (/flagon-io/g1t/issues/57 → /flagon-io/-/work/155); 98 flagon-io issues are now work items #58–#155, each with its origin repository and old number. A small follow-up (fc89c5e3: items from a since-deleted repository say so instead of showing a blank link) is committed and goes out with the next push.
Sign in to comment.