Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

254 linesCodeBlameRaw
1---
2title: Claims and dependencies
3description: How people and coding agents work on the same work items without colliding. Advisory claims and hand-offs, what a work item is blocked by, overlapping changes, the coordination updates each session receives, and the events behind them.
4---
5
6When several agents and people work in one workspace at once, each needs
7to know what the others are doing. g1t keeps that around the
8[work item](/work/work-items/), the unit of work, and around the
9[sessions](/work/sessions/) working on it:
10
11- **Claims**: an advisory, expiring "I'm working on #12". Never a lock.
12- **Hand-offs**: "I'm stopping; here is where it stands".
13- **Dependencies**: the work items that have to land before this one.
14- **Overlaps**: two pull requests, or two sessions, changing the same files.
15
16Each change is announced as an event, and as a
17[coordination update](#coordination-updates) to the sessions it concerns,
18so an agent hears about it between steps instead of finding out at merge
19time.
20
21## Claims
22
23A claim says you are working on a work item. It is advisory: anyone may
24claim a work item someone else has, and is told about them, so two agents
25can decide between themselves rather than collide. Nothing is refused
26because of a claim. A claim is the workspace's, whichever repository the
27session that holds it is checked out in, so sessions in different
28repositories see each other's claims on the same work item.
29
30- **Claim** an open work item with `work_item` `claim`, `g1t work claim 12`
31 (with `--note` to say what you are taking), or
32 [`POST /workspaces/{workspace}/work/{number}/claim`](/reference/api/work-items/claim-work-item/).
33 Give your `session_id`, so that two of your sessions, such as sibling
34 subagents, hold claims of their own and each is told of the other's. The
35 answer has your `claim`, the `others` already on the work item, and
36 `blocked_by`: each work item this one waits on, with its claims and pull
37 requests. A closed work item cannot be claimed (`409`).
38- **File a work item and claim it** in one step, for work that has no work
39 item yet: `work_item` `claim` with `title` (and `body`) and no `number`,
40 `g1t work claim --title "…"`, or
41 [`POST /workspaces/{workspace}/claims`](/reference/api/work-items/claim-new-work-item/).
42 The work item is filed (a `work_item.opened` event), with the session's
43 repository as its origin when you give `repo`, then claimed, and the
44 session named by `session_id` is attached to it. The answer also has
45 `item`, the work item filed. The session is checked first: a claim that
46 would be refused for it files nothing.
47- **Renew** it by claiming again, or give the `session_id` of your session
48 when you claim, and that session's heartbeats renew it.
49- **Release** it with `work_item` `release`, `g1t work release 12`, or
50 [`POST /workspaces/{workspace}/work/{number}/release`](/reference/api/work-items/release-claim/),
51 with an optional `reason`.
52- **Hand it off** with `work_item` `handoff`, `g1t work handoff 12 --note
53 "…"`, or
54 [`POST /workspaces/{workspace}/work/{number}/handoff`](/reference/api/work-items/hand-off-work-item/),
55 with a `note` on where the work stands, for `to` (a username) or anyone.
56 When whoever it was for claims the work item, their `work.claimed` event
57 names the hand-off in `took_over`.
58
59```sh
60curl -X POST https://api.g1t.sh/workspaces/acme/work/12/claim \
61 -H "Authorization: Bearer $G1T_TOKEN" \
62 -H "Content-Type: application/json" \
63 -d '{"session_id": "ses_01m4b2c3d4e5f6g7h8j9k0m1n2", "note": "Taking the argument parsing first."}'
64
65curl -X POST https://api.g1t.sh/workspaces/acme/claims \
66 -H "Authorization: Bearer $G1T_TOKEN" \
67 -H "Content-Type: application/json" \
68 -d '{"session_id": "ses_01m4b2c3d4e5f6g7h8j9k0m1n2", "repo": "acme/web", "title": "Preview builds time out on large repositories"}'
69```
70
71| | |
72| --- | --- |
73| How long a claim lasts | `ttl_minutes`: 30 unless you say, at most 240 (`--ttl 2h` on the CLI). |
74| Filing its work item | `title` (and `body`) instead of `number`. Giving both is refused with `422`. |
75| When it ends | Released, handed off, its work item closed (`reason` `item_closed`), or not renewed in time (`expired`). |
76| States | `active`, `released`, `expired`, `handed_off`. |
77
78See who is on what with `work_item` `list_claims`, `g1t work status`, or
79[`GET /repos/{owner}/{name}/claims`](/reference/api/work-items/list-claims/):
80active claims unless `state` says otherwise, and `item` for one work
81item's. On the site, a work item's **Work** panel lists its claims: who,
82from which harness, since when and when each lapses, with those released,
83expired or handed off lately dimmed. A work item with nobody on it says
84how to claim it.
85
86## Dependencies
87
88A work item's `blocked_by` lists the work items of the same workspace that
89have to land before it. On its page, **Edit** beside **Blocked by** in the
90Work panel changes it. From the CLI:
91
92```sh
93g1t work block 12 --by 9 --by 10
94g1t work unblock 12 --by 10
95```
96
97Over MCP and the API, `work_item` `update` or
98[`PATCH /workspaces/{workspace}/work/{number}`](/reference/api/work-items/update-work-item/)
99replaces the whole list:
100
101```sh
102curl -X PATCH https://api.g1t.sh/workspaces/acme/work/12 \
103 -H "Authorization: Bearer $G1T_TOKEN" \
104 -H "Content-Type: application/json" \
105 -d '{"blocked_by": [9, 10]}'
106```
107
108A list is refused with `422` when a number is not a work item of the
109workspace, names the work item itself, or would make a cycle (the answer
110shows the cycle, such as `#12 → #9 → #12`). Up to 50 work items. Changing
111it notes the change in the work item's conversation (**marked this as
112blocked by #9**) and needs what editing the work item does: being its
113owner, or the Triage role.
114
115The Work panel shows what a work item is blocked by and where each of
116those stands, and the work items it blocks. g1t says when a dependency
117moves, as a `dependency.changed` event on the blocked work item: when its
118list changes, and when one of its blockers closes or has a pull request
119merged into the default branch. `remaining` lists the blockers still open;
120when it is empty, the work item is unblocked.
121
122## Overlaps
123
124Opening a pull request, and each push to it, works out which files it
125changes. When it starts changing files another open or draft pull request
126changes, g1t sends `overlap.detected` once for each of the two, naming the
127other and the files. A pair is announced once, and again only after it
128stopped overlapping. A pull request's `overlaps`, in `pull_request` `get`
129and in the work item's [work context](/work/agents/#pick-up-a-work-item),
130show current overlaps whenever you look.
131
132Sessions overlap too, before there is a pull request: when a session says
133it touched a file that another active session touched (outside its own
134parents and subagents), each gets `overlap.detected` with `session_id`,
135`other_session_id`, `other_actor` and `files`, once per pair, and again
136with the new `files` when another file in common joins.
137
138An overlap with a pull request for a different work item will become a
139conflict for whichever merges second: narrow the change, agree an order,
140or say so in the pull request.
141
142## Coordination updates
143
144Each session has an inbox of coordination updates: the claims, releases,
145hand-offs and expiries, overlaps, dependency changes, decisions,
146merge-queue results and sessions starting and ending that concern it. They
147work the same with Claude Code, Codex or any other harness:
148
149```sh
150g1t session updates --json
151g1t session acknowledge upd_ID --note "My scope is separate; no plan change"
152```
153
154They use `G1T_SESSION` (or the working copy's remembered session).
155`session updates`, `session acknowledge` and `session heartbeat` first say
156which files the working copy has changed (from `git status`), as
157`session touch --file` would, so overlapping edits are noticed whichever
158harness makes them; `G1T_TOUCH=0` turns that off. In a shared checkout,
159`updates SESSION_ID` and `acknowledge --session SESSION_ID` name the
160session. Over MCP, `session` `get` returns up to 100 pending `updates`,
161oldest first, separately from the session's entries; the API's
162`get_session` does the same (give `after=4294967295` to leave the entries
163out).
164
165An active session receives the updates that concern it:
166
167| The session is | It receives |
168| --- | --- |
169| Attached to a work item or pull request, or tied to one (a claim, its branch, a `#N` it named) | Updates about that work item or pull request: its claims, decisions, overlaps, dependency changes and merge-queue results, and those that name it, such as an integration failure listing it as a suspect or a work item newly blocked by it |
170| Not on anything yet | Every update, so it can find who else is working and on what |
171| Either | Updates about nothing in particular, such as a session starting without a work item; and an overlap between its own files and another session's, which goes only to the two sessions |
172
173A session does not receive its own start or end, or the claims it made,
174released or handed off. It does hear when its claim expires. A new session
175should still load the work item's context: an inbox is not a replay of
176what happened before the session started.
177
178Reading does not clear an update. After considering it, and recording any
179change of plan, the session acknowledges the exact IDs it considered:
180`g1t session acknowledge`, the MCP `session` tool's `record` with
181`acknowledge`, or
182
183```sh
184g1t api record_session_entries -f id=SESSION_ID -f 'acknowledge[]=UPDATE_ID'
185```
186
187Repeat the field for more IDs, at most 100 a request, then read again for
188the next page. Acknowledging is idempotent and scoped to that session. It
189means considered, not resolved. The answer's `acknowledged` says how many
190of the IDs name updates of that session, so a mistyped ID or one from
191another session shows up as a shortfall (the CLI warns). A session's page
192shows what it has not acknowledged.
193
194The [Claude Code plugin](/guides/claude-code-plugin/)'s hooks fetch
195updates in the background, at most once every ten seconds, and at once
196after an acknowledgement. Every prompt shows what is pending; before a
197tool, pending updates are shown when they change and again every two
198minutes, until acknowledged. Other harnesses, including sessions g1t runs,
199read them between work steps, as the coordinate skill says. Neither a
200disconnected harness nor an idle session is interrupted.
201
202An update is written in the same transaction as the change it announces:
203a claim, release, hand-off, expiry, session start or end, overlap,
204decision or change to what a work item is blocked by is never kept without
205its updates, and updates never announce a change that was not made. Each
206update's ID is derived from its change, so a retried request, or two
207requests making the same change at once, delivers it once. The one
208exception is the notice that a work item's blocker closed or merged, which
209follows the close or merge: it is written right after, once per close or
210merge. Updates are still a summary: read the work item and pull request
211again before acting on one.
212
213Acknowledged updates are kept as receipts for 30 days. Pending updates
214stay until acknowledged, including those of a session that ended, so
215whoever takes over its work can see what it never considered.
216
217## Events
218
219Coordination is published as events, which [webhooks](/guides/webhooks/)
220deliver and Sessions' **What happened** lists. Each carries `number` (the
221work item or pull request it is about) and `item` (the work item's number
222in the workspace) where there is one.
223
224| Event | When |
225| --- | --- |
226| `session.started` | A session (or a subagent) starts, or one that ended starts again. Not on a repeated start. |
227| `session.ended` | A session ends, or times out after 30 minutes without a heartbeat. |
228| `session.progressed` | A session recorded more: at most every 5 seconds for each, with `session_id` (and `root_id` for a subagent), never what it recorded. Pages showing the session follow it with this. |
229| `work.claimed` | Someone claims a work item. `others` lists the claims already on it; `took_over` names a hand-off it takes. |
230| `work.released` | A claim is released, or its work item closed (`reason` `item_closed`). |
231| `work.claim_expired` | A claim was not renewed in time. |
232| `work.handoff_requested` | Someone hands a work item off: `from`, `to` (absent for anyone) and `note`. |
233| `dependency.changed` | A work item's `blocked_by` changed (`added`, `removed`), or a blocker closed or had its pull request merged (`cleared`). `remaining` lists the blockers still open. |
234| `overlap.detected` | A pull request started changing files another open one changes: `pull`, `other_pull`, `files`, `item` and `other_item`. Or a session touched files another active session touched: `session_id`, `other_session_id`, `other_actor`, `files`. |
235
236A session or claim that went quiet is announced as ended or expired when
237the repository's sessions or claims are next read or changed, not at the
238minute it lapsed.
239
240## Who may do what
241
242| To | You need |
243| --- | --- |
244| Read sessions and claims | To be able to read the repository. Public repositories need no token. What a session shows depends on who you are: see [who sees what](/work/sessions/#who-sees-what). |
245| Read a workspace's **Sessions** | It lists the sessions of the workspace's repositories you can read; g1t's own agent's sessions only for members. |
246| Read a work item's context | To be able to see the work item: see [who sees a work item](/work/work-items/#who-sees-a-work-item). |
247| Start a session, claim a work item, file one by claiming it | A confirmed email address and a role that may file work items; the repository must not be archived. |
248| Update, record in or end a session | To be the person whose token started it. Ending one by hand: also anyone with write access. |
249| Release a claim or hand it off | To be the person who made it. |
250| Set `blocked_by` | To be the work item's owner, or the Triage role. |
251
252With an access token, sessions need `pull_requests:read` or
253`pull_requests:write`, and claims and the work context need `work:read` or
254`work:write`, as [scopes](/guides/authentication/#scopes) say.