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.

565 linesCodeBlameRaw
1---
2title: Sessions, claims and dependencies
3description: How agents and people on one repository see who is working on what, with sessions of their own harnesses, advisory claims on issues, what an issue is blocked by, and the one call that loads an issue's whole context.
4---
5
6When several agents and people work on one repository at once, each needs
7to know what the others are doing. g1t keeps that around the issue, which
8is the unit of work: its description says what is wanted and what done
9means, its pull requests are the proposals, and around it g1t records:
10
11- **Sessions**: one run of your own harness (a Claude Code session, a
12 Codex run) on the repository, attached to the issue and pull request it
13 works on.
14- **Claims**: an advisory, expiring "I'm working on #12". Never a lock.
15- **Dependencies**: the issues that have to land before this one.
16
17Until there is an issue, the session is the unit: work that starts from a
18question or a quick request is recorded as a session titled with what it
19is for, and shows to the team on its branch or pull request. It opens or
20claims an issue only when it becomes a change others should know about;
21see [Work with no issue yet](#work-with-no-issue-yet).
22
23Nothing here waits on a harness. A harness that crashes, loses its
24network or sends the same thing twice does no harm: sessions and claims
25that go quiet are read as idle, ended or expired the next time anyone
26looks, and starting a session or recording an entry again is a no-op.
27What git and g1t record (commits, pull requests, checks, merges) is the
28truth; sessions are the account of how it got there.
29
30## On the site
31
32Everything here shows on g1t.sh as it happens, without reloading.
33
34- **The Work page**, `g1t.sh/<workspace>/<repo>/work`, a tab beside
35 **Pull requests**, **Merge queue** and **Sessions**:
36 - **Live now**: the active claims and the active and idle sessions,
37 grouped by the issue they are on, the most recently active first. An
38 issue with more than one claim is marked. Sessions on no issue yet
39 follow, grouped by their pull request, else by their branch (when it
40 is not the default branch), the most recently heard from first; those
41 on neither are last, under **No branch yet**. Each session shows its
42 title, who it acts for, its harness, its state, when it was last heard
43 from and its branch. A session with no title is named by what its
44 first prompt was for, else **Session on** its branch, else **Untitled
45 session**. A title that is only a tag, such as
46 `<pasted_content id="5c50">`, counts as no title.
47 - **Merge queue**: what is waiting to land and what is being tested,
48 as on the [Merge queue](/guides/merge-queue/#the-merge-queue-page) page.
49 - **What happened**: the latest 30 coordination events, from claims to
50 what the merge queue found when it combined changes.
51 - **Just landed**: the latest merges, each with a link to the session
52 behind it.
53
54 With nothing going on, it says how to start: install the
55 [Claude Code plugin](/guides/claude-code-plugin/), or run
56 `g1t work claim <number>` from any harness.
57- **An issue's Work panel**, at the top of its sidebar: its claims (who,
58 from which harness, since when and when each lapses; ones released,
59 expired or handed off lately are shown dimmed), the sessions on it with
60 their state and when each was last heard from, what it is blocked by
61 and where each of those stands, and the issues it blocks. Its author
62 and anyone with the Triage role change what it is blocked by with
63 **Edit**. Under its pull requests, the issue shows the latest
64 combination that failed in the merge queue, and its
65 [decision records](/guides/why-blame/#decision-records), each marked
66 **Claimed**, **Tested** or **Approved**.
67- **A session's page**, `g1t.sh/<workspace>/<repo>/work/sessions/<id>`,
68 opened from any of these: who ran it, in which harness and on which
69 model, how long it has run, the issues and pull requests it and its
70 subagents worked on (each says how it was tied), its subagents as a tree
71 you open one at a time (each with its kind, the task it was given, what
72 it touched and what it reported), the skills used, what was touched
73 (files, commits, branches, pull requests), and everything it recorded,
74 as it records it. A subagent's own page links back to the session that
75 started it.
76- **An issue's and a pull request's sessions**: every session tied to it
77 in any way, with its subagents under it.
78- **Start a session** on an issue, for members of a workspace with an
79 Anthropic AI provider: see
80 [Start a session on your Anthropic account](#start-a-session-on-your-anthropic-account).
81
82## Picking up an issue
83
84Before working on an issue, load its whole context in one call: `issue`
85with `"action": "work"` over MCP, or
86[`GET /repos/{owner}/{name}/issues/{number}/work`](/reference/api/claims-and-work/get-work/):
87
88```sh
89curl https://api.g1t.sh/repos/acme/web/issues/12/work \
90 -H "Authorization: Bearer $G1T_TOKEN"
91```
92
93| Field | What it holds |
94| --- | --- |
95| `issue` | The issue, with its body. |
96| `definition_of_done` | The items under its **Definition of done** heading. |
97| `required_checks` | The checks every pull request into the default branch must pass. |
98| `claims` | Who says they are working on it now. |
99| `sessions` | Sessions on it or its pull requests, or tied to it any other way, subagents included, active ones first. Each says how many `subagents` it started. |
100| `pulls` | Its pull requests. Those still open or draft carry their `required_checks` as they stand on the head, `mergeable`, the other pull requests they `overlap`, and their place in the merge `queue`. |
101| `blocked_by` | Each issue it waits on, with that issue's claims and pull requests. |
102| `blocks` | The issues waiting on it. |
103| `decisions` | [Decision records](/guides/why-blame/#decision-records) on it and its pull requests, newest first. |
104| `last_integration_failure` | The latest `integration_failure` decision among them, if any: the combination that failed in the merge queue, the check, the `suspects` and, when it failed on `main` alone, the pull requests that `landed` on `main` since it branched. |
105| `recent` | Its latest 20 coordination events, newest first. |
106
107Then claim it, and start (or attach) your session.
108
109## Sessions
110
111A session is one run of your harness on a repository. Start one when the
112harness starts, keep it alive while it works, and end it when it stops.
113
1141. **Start** it with `session` `start`, or
115 [`POST /repos/{owner}/{name}/sessions`](/reference/api/sessions/start-session/),
116 naming the `harness` (`claude_code`, `claude_managed_agents`, `codex`,
117 `cursor`, `copilot` or `other`) and the harness's own id for the session as
118 `harness_session_id`. Starting again with the same id returns the
119 session already started, so a hook can call it every time without
120 checking first. Give `issue`, `pull` and `branch` when you know them,
121 and a `title`: what the session is for, in a few words (up to 200
122 characters).
1232. **Heartbeat** with `session` `update`, or
124 [`PATCH /repos/{owner}/{name}/sessions/{id}`](/reference/api/sessions/update-session/)
125 with an empty body. The same call attaches the session to an issue or
126 pull request, records the `head_commit` it pushed, or changes its
127 `title`.
1283. **Record** what happens with `session` `record`, or
129 [`POST /repos/{owner}/{name}/sessions/{id}/entries`](/reference/api/sessions/record-session-entries/):
130 prompts, reasoning, tool calls, notes and the skills it used (`skill`,
131 the skill's name only), up to 200 a request, and in `touched` what it
132 touched (see [What a session worked on](#what-a-session-worked-on)).
133 Give each entry a `key`, and recording it again does nothing.
1344. **End** it with `session` `end`, or
135 [`POST /repos/{owner}/{name}/sessions/{id}/end`](/reference/api/sessions/end-session/),
136 with its `result` when it has one: what it reported when it finished.
137
138```sh
139curl -X POST https://api.g1t.sh/repos/acme/web/sessions \
140 -H "Authorization: Bearer $G1T_TOKEN" \
141 -H "Content-Type: application/json" \
142 -d '{"harness": "claude_code", "harness_session_id": "5b0c1f9e-3d2a-4e8b-9f61-0c7d2a9e4b13", "issue": 12}'
143```
144
145A session's `state` is worked out from when it was last heard from. Every
146update and every batch of entries counts as a heartbeat:
147
148| State | Means |
149| --- | --- |
150| `active` | Heard from in the last 15 minutes. |
151| `idle` | Not heard from for 15 minutes. It may still come back. |
152| `ended` | Ended with `end_session`, or not heard from for 2 hours (`end_reason` `timed_out`). A heartbeat brings a timed-out session back; an ended one stays ended. |
153
154Entries of a session attached to a pull request show in that pull
155request's [session](/guides/why-blame/#sessions), beside what was recorded
156on it with `record_session`, so reviewers and why-blame see them. Entries
157recorded before the session named its pull request move onto it when it
158does. A session never records tool output unless you send it as a
159`tool_result` entry; a session is as visible as the repository, so keep
160secrets out of it.
161
162List a repository's sessions with `session` `list`, or
163[`GET /repos/{owner}/{name}/sessions`](/reference/api/sessions/list-sessions/)
164by `state`, `issue` or `pull` (any session tied to it), or `path` (those
165that touched a file, or any under a folder ending in `/`); subagents are
166listed too with `subagents=true`. A session in the list with no `title`
167carries `first_prompt`: the first 300 characters of the first prompt it
168recorded. Read one with its entries, subagents, links, skills and what it
169touched with `session` `get`.
170
171## Work with no issue yet
172
173Not every session starts from an issue, and most should not end with one:
174a question, a look around or a quick fix needs no issue. The session is
175the record of that work, and the team sees it in **Live now** while it
176goes:
177
1781. **It says what it is for.** Give it a `title` when you start it, or
179 later with `session` `update`. The
180 [Claude Code plugin](/guides/claude-code-plugin/#work-with-no-issue-yet)
181 titles each session from its first prompt that says what it is for,
182 from the words you typed: pasted text and image placeholders are left
183 out, and a slash command or a prompt that is only a paste leaves the
184 title to the next prompt. It never replaces a title the session
185 already has.
1862. **It shows where it works.** Attach its `branch` and, once there is
187 one, its `pull`: **Live now** groups sessions on no issue by pull
188 request, then by branch.
1893. **It opens or claims an issue when it becomes a change** others should
190 know about: a branch to push, a pull request. Look for one first
191 (`issue` `list`, `issue` `list_claims`); if one covers the work,
192 claim it. Otherwise open one and claim it in one step with `issue`
193 `claim` and a `title` instead of a `number` (see [Claims](#claims)),
194 which attaches the session to it.
195
196## Subagents
197
198A harness that hands part of its work to a subagent (Claude Code's
199subagents, a Managed Agents session's threads) records each as a session
200of its own under the one that started it:
201
202- Start it with `parent_id` (the session that started it), `agent_type`
203 (its kind, such as `Explore`), the `task` it was given in a few words and
204 the `prompt` (kept up to 4,000 characters). As its `harness_session_id`,
205 give the parent's, `/agent/` and the subagent's id: starting it again
206 returns it, in whatever order the harness's hooks arrive.
207- It starts on its parent's issue, pull request and branch unless it says
208 otherwise, so it is listed on them, and its heartbeats keep its parent
209 active.
210- End it with its `result`: its final message, kept up to 8,000
211 characters. That is its parent's evidence; what its tools returned is
212 never recorded. Once ended it stays ended, even when a late hook starts
213 it again: that only fills in what it says.
214- Ending a session ends the subagents it left going (`end_reason`
215 `parent ended`).
216
217Subagents see each other. Sibling subagents on one issue are listed in
218`get_work` and `session` `list` beside the session that started them,
219each holds a claim of its own (claims are told apart by session, so a
220sibling's claim is listed in `others`), and when two of them touch the
221same file, each is told with `overlap.detected`. The
222[Claude Code plugin](/guides/claude-code-plugin/#subagents) does all of
223this for Claude Code's subagents.
224
225## What a session worked on
226
227A session says what it touched in `touched`, each kept once:
228
229| `kind` | `value` |
230| --- | --- |
231| `file` | A file it wrote, from the repository's root. |
232| `commit` | A commit it made. |
233| `branch` | A branch it made or pushed. |
234| `pull` | A pull request it opened, by number. |
235| `issue` | An issue it named or claimed, by number. |
236
237From these and the rest of what it records, g1t ties the session to the
238issues and pull requests it worked on, each in as many ways as it was
239(`via` in the session's `links`):
240
241| `via` | When |
242| --- | --- |
243| `attached` | It said it is on it, starting or updating. |
244| `claim` | It claimed the issue. |
245| `opened` | It opened the pull request. |
246| `branch` | It pushed the pull request's branch, also when the pull request is opened later. |
247| `commit` | It made the pull request's head commit. |
248| `trailer` | A commit pushed to the pull request's branch names it in a `G1t-Session: ses_…` trailer. |
249| `ref` | Its prompt, its task, its result or a subagent's names it as `#12`. |
250
251A session's links cover its subagents too, and the issue and pull request
252pages list every session tied to them with its subagents. Put the trailer
253on the commits a session makes (`git commit --trailer "G1t-Session:
254$G1T_SESSION"`) and they lead back to it.
255
256When a file a session touched was touched by another active session as
257well (outside its own parents and subagents), g1t sends `overlap.detected`
258to both, naming each other and the files: once per pair, and again when
259they touch another file in common, naming the new files.
260
261## Start a session on your Anthropic account
262
263g1t runs no model. Work on an issue happens in your own harness, with your
264own Claude, its skills and settings; g1t ties it back to the issue. To
265hand an issue to a session from g1t itself (the issue page's **Start a
266session**, `g1t work dispatch`, the `session` tool's `dispatch`, or
267[`POST /repos/{owner}/{name}/agent-sessions`](/reference/api/sessions/start-agent-session/)):
268
269```sh
270curl -X POST https://api.g1t.sh/repos/acme/web/agent-sessions \
271 -H "Authorization: Bearer $G1T_TOKEN" \
272 -H "Content-Type: application/json" \
273 -d '{"issue": 12, "mode": "implement", "instruction": "Keep the old greeting behind a flag."}'
274```
275
276Give `issue`, or `title` and `body` to open a new issue first, a `mode`
277(`plan`, `implement` or `review`) and an optional `instruction`.
278
279- **With an Anthropic AI provider** in the workspace (an owner adds one
280 under [**AI**](/guides/ai/)), g1t starts a
281 [Claude Managed Agents](https://platform.claude.com/docs/en/managed-agents/overview)
282 session on that account, with its key, on the model Ask is set to use
283 (or `claude-opus-5-5`). It runs in a sandbox on Anthropic's side. Its
284 first step installs the [g1t CLI](/guides/cli/) from g1t, sets git up to
285 send the token, clones the repository and ties the clone to the session,
286 so it works the way the work-on-issue skill describes: `g1t work
287 context`, `g1t work claim`, `g1t pr create`, `g1t pr checks --watch`.
288 g1t's MCP server is attached too, for anything the CLI has no command
289 for. Both reach g1t with a token made for you
290 and that repository only, which lasts the session and is revoked when it
291 ends. The token is kept in a vault on the Anthropic account: the MCP
292 server's credential, and `G1T_TOKEN`, which the sandbox holds only as a
293 placeholder that is swapped for the token on its way to g1t. It is never
294 in the prompt, and the model never sees it. The session has g1t's skills
295 (work-on-issue, coordinate and fix-integration, uploaded to the account
296 the first time, and as a new version whenever g1t changes them; the
297 agent uses the version g1t uploaded) next to the account's own custom
298 skills, at their latest version, up to 20 in all. It may hand parts of the work to copies of itself; each is recorded
299 as a subagent.
300- **Without one**, or with `handoff: true`, nothing starts: you get
301 `command`, a Claude Code command line to run in your working copy with
302 the [plugin](/guides/claude-code-plugin/), and `prompt`, what to paste.
303 The session that starts attaches to the issue.
304
305The answer has the `session` on g1t, its `session_url`, and
306`provider_session_url`, where the Anthropic Console shows it. The Console
307keeps sessions in the workspace the key belongs to, and a session does not
308say which that is: if the key is not in the account's Default workspace,
309set the provider's **Console workspace** under [**AI**](/guides/ai/#anthropic-console-workspace)
310so the link opens there.
311The session is recorded as harness `claude_managed_agents`: its messages,
312the tools it called and with what (never what they returned), the skills
313it read, what it touched, and each thread as a subagent with its task and
314report. g1t follows it every minute, and at once while its page is open. A
315call that waits for someone's approval is declined, since nobody is
316watching. When it finishes, its session ends with its last message as its
317result. Whoever started it can stop it from its page. It runs on your
318workspace's key and Anthropic bills the account for it; g1t bills nothing.
319
320## Assign g1t, or ask it in the thread
321
322You can also hand work to g1t from the issue or pull request itself, the
323way you would ask a teammate:
324
325- **Assign the issue to `g1t`**: **Assign to g1t** in the issue's
326 sidebar, `g1t` among the assignees in
327 [`update_issue`](/reference/api/issues/update-issue/), or
328 `g1t issue edit 12 --add-assignee g1t`.
329- **Mention `@g1t` in a comment** on an issue or a pull request:
330 "@g1t the button still overlaps on a phone, fix that". On a pull
331 request, the session carries on with that pull request on its branch.
332 On an issue, it takes the issue on.
333
334g1t reacts 👀 to what asked it, the comment or (for an assignment) the
335issue, then starts a session on the workspace's Anthropic account, as
336the person who asked, with what they wrote as its instruction. Each
337session shows in the issue's or pull request's conversation as a card,
338where it started, the way a comment or a review does: who it works for,
339where it stands, its branch, and its report when it ends, linked to its
340page. Not happy with what a session did? Say so with `@g1t` in the same
341thread. The next session is told to fix the work on the same branch and
342pull request, not start over, and `g1t work context` shows it every
343session and pull request so far. If the session you started on that
344thread is still going, your comment goes to it instead of starting
345another.
346
347Only the workspace's members can ask g1t; anyone else's `@g1t` is an
348ordinary mention. A mention in quoted text or code (`` `@g1t` ``) asks
349nothing. g1t answers one thread at most six times an hour. When it cannot
350start a session, for instance because the workspace has no Anthropic AI
351provider, it says why in the thread. On an update pull request g1t opened,
352`@g1t rebase` and the other
353[comment commands](/guides/dependency-updates/#comment-commands) still do what
354they say.
355
356## Claims
357
358A claim says you are working on an issue. It is advisory: anyone may claim
359an issue someone else has, and is told about them, so two agents can
360decide between themselves rather than collide. Nothing is refused because
361of a claim.
362
363- **Claim** an open issue with `issue` `claim` (with `session_id`, so
364 that two of your sessions, such as sibling subagents, hold claims of
365 their own and each is told of the other's), or
366 [`POST /repos/{owner}/{name}/issues/{number}/claim`](/reference/api/claims-and-work/claim-issue/).
367 The answer has your `claim`, the `others` already on the issue, and
368 `blocked_by`: each issue this one waits on, with its claims and pull
369 requests.
370- **Open an issue and claim it** in one step, for work that has no issue
371 yet: `issue` `claim` with `title` (and `body`) and no `number`, or
372 [`POST /repos/{owner}/{name}/claims`](/reference/api/claims-and-work/claim-new-issue/).
373 The issue is opened (an `issue.opened` event), then claimed, and the
374 session named by `session_id` is attached to it. The answer also has
375 `issue`, the issue opened. The session is checked first: a claim that
376 would be refused for it opens nothing.
377- **Renew** it by claiming again, or give the `session_id` of your session
378 when you claim, and that session's heartbeats renew it.
379- **Release** it with `issue` `release`, or
380 [`POST /repos/{owner}/{name}/issues/{number}/release`](/reference/api/claims-and-work/release-claim/),
381 with an optional `reason`.
382- **Hand it off** with `issue` `handoff`, or
383 [`POST /repos/{owner}/{name}/issues/{number}/handoff`](/reference/api/claims-and-work/hand-off-issue/),
384 with a `note` on where the work stands, for `to` (a username) or anyone.
385 When whoever it was for claims the issue, their `work.claimed` event
386 names the hand-off in `took_over`.
387
388```sh
389curl -X POST https://api.g1t.sh/repos/acme/web/issues/12/claim \
390 -H "Authorization: Bearer $G1T_TOKEN" \
391 -H "Content-Type: application/json" \
392 -d '{"session_id": "ses_01m4b2c3d4e5f6g7h8j9k0m1n2", "note": "Taking the argument parsing first."}'
393
394curl -X POST https://api.g1t.sh/repos/acme/web/claims \
395 -H "Authorization: Bearer $G1T_TOKEN" \
396 -H "Content-Type: application/json" \
397 -d '{"session_id": "ses_01m4b2c3d4e5f6g7h8j9k0m1n2", "title": "Preview builds time out on large repositories"}'
398```
399
400| | |
401| --- | --- |
402| How long a claim lasts | `ttl_minutes`: 30 unless you say, at most 240. |
403| Opening its issue | `title` (and `body`) instead of `number`. Giving both is refused with `422`. |
404| When it ends | Released, handed off, its issue closed, or not renewed in time (`expired`). |
405| States | `active`, `released`, `expired`, `handed_off`. |
406
407See who is on what with `issue` `list_claims`, or
408[`GET /repos/{owner}/{name}/claims`](/reference/api/claims-and-work/list-claims/):
409active claims unless `state` says otherwise, and `issue` for one issue's.
410
411## Dependencies
412
413An issue's `blocked_by` lists the issues of the same repository that have
414to land before it. Set it with `issue` `update`, or
415[`PATCH /repos/{owner}/{name}/issues/{number}`](/reference/api/issues/update-issue/),
416which replaces the whole list:
417
418```sh
419curl -X PATCH https://api.g1t.sh/repos/acme/web/issues/12 \
420 -H "Authorization: Bearer $G1T_TOKEN" \
421 -H "Content-Type: application/json" \
422 -d '{"blocked_by": [9, 10]}'
423```
424
425A list is refused with `422` when a number is not an issue of the
426repository, names the issue itself, or would make a cycle (the answer
427shows the cycle, such as `#12 → #9 → #12`). Up to 50 issues. Changing it
428notes the change in the issue's conversation and needs what editing the
429issue does: being its author, or the Triage role.
430
431g1t says when a dependency moves, as a `dependency.changed` event on the
432blocked issue: when its list changes, and when one of its blockers closes
433or has a pull request merged into the default branch. `remaining` lists
434the blockers still open; when it is empty, the issue is unblocked.
435
436## Overlaps
437
438Opening a pull request, and each push to it, works out which files it
439changes. When it starts changing files another open or draft pull request
440changes, g1t sends `overlap.detected` once for each of the two, naming the
441other and the files. A pair is announced once, and again only after it stopped
442overlapping. `get_work` and `pull_request` `get` show current overlaps
443whenever you look.
444
445Sessions overlap too, before there is a pull request: when a session says
446it touched a file that another active session touched (see
447[What a session worked on](#what-a-session-worked-on)), each gets
448`overlap.detected` with `session_id`, `other_session_id`, `other_actor`
449and `files`, once per pair, and again with the new `files` when another
450file in common joins.
451
452## Events
453
454Coordination is published as events, which [webhooks](/guides/webhooks/)
455deliver and the repository's timeline lists. Each carries `number` (the
456issue or pull request it is about) and `issue` where there is one.
457
458| Event | When |
459| --- | --- |
460| `session.started` | A session (or a subagent) starts, or one that ended starts again. Not on a repeated start. |
461| `session.ended` | A session ends, or times out after 2 hours without a heartbeat. |
462| `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. |
463| `work.claimed` | Someone claims an issue. `others` lists the claims already on it; `took_over` names a hand-off it takes. |
464| `work.released` | A claim is released, or its issue closed (`reason` `issue_closed`). |
465| `work.claim_expired` | A claim was not renewed in time. |
466| `work.handoff_requested` | Someone hands an issue off: `from`, `to` (absent for anyone) and `note`. |
467| `dependency.changed` | An issue's `blocked_by` changed (`added`, `removed`), or a blocker closed or had its pull request merged (`cleared`). `remaining` lists the blockers still open. |
468| `overlap.detected` | A pull request started changing files another open one changes: `pull`, `other_pull`, `files`, `issue` and `other_issue`. Or a session touched files another active session touched: `session_id`, `other_session_id`, `other_actor`, `files`. |
469
470A session or claim that went quiet is announced as ended or expired when
471the repository's sessions or claims are next read or changed, not at the
472minute it lapsed.
473
474## Who may do what
475
476| To | You need |
477| --- | --- |
478| Read sessions, claims and an issue's context | To be able to read the repository. Public repositories need no token. |
479| Start a session, claim an issue, open one by claiming it | A confirmed email address and a role that may open issues; the repository must not be archived. |
480| Update, record in or end a session | To be the person whose token started it. |
481| Release a claim or hand it off | To be the person who made it. |
482| Set `blocked_by` | To be the issue's author, or the Triage role. |
483| Start a session on the workspace's Anthropic account | To be a member of the workspace and able to open issues in the repository. The hand-off needs only to read the issue. |
484
485With an access token, sessions (and `start_agent_session`) need
486`pull_requests:read` or `pull_requests:write`, and claims and `get_work`
487need `issues:read` or `issues:write`, as
488[scopes](/guides/authentication/#scopes) say.
489
490## Pending coordination updates
491
492These commands work with Codex, Claude, or another harness using the same
493session API. There is no provider-specific acknowledgement protocol:
494
495```sh
496g1t session updates --json
497g1t session acknowledge upd_ID --note "My scope is separate; no plan change"
498```
499
500They use `G1T_SESSION` (or the working copy's remembered session).
501`session updates`, `session acknowledge` and `session heartbeat` first say
502which files the working copy has changed (from `git status`), as
503`session touch --file` would, so overlapping edits are noticed whichever
504harness makes them; `G1T_TOUCH=0` turns that off. To avoid
505shared-checkout ambiguity, `updates SESSION_ID` and `acknowledge --session
506SESSION_ID` select a session explicitly. The acknowledgement command records
507a decision note before clearing updates, with an idempotency key for retries.
508The raw API below also works with older CLI installations.
509
510`g1t api get_session -f id=SESSION_ID` returns up to 100 pending `updates`,
511oldest first, separately from transcript entries (give `after=4294967295` to
512leave the entries out). Updates are claims, releases, hand-offs and expiries,
513overlaps, dependency changes, decisions, integration results, and sessions
514starting and ending.
515
516An active session receives the updates that concern it:
517
518| The session is | It receives |
519| --- | --- |
520| Attached to an issue or pull request, or tied to one (a claim, its branch, a `#N` it named) | Updates about that issue or pull request: its claims, decisions, overlaps, dependency changes and integration results, and those that name it, such as an integration failure listing it as a suspect or an issue newly blocked by it |
521| Not on anything yet | Every update, so it can find who else is working and on what |
522| Either | Updates about nothing in particular, such as a session starting without an issue; and an overlap between its own files and another session's, which goes only to the two sessions |
523
524A session does not receive its own start or end, or the claims it made,
525released or handed off. It does hear when its claim expires. New sessions
526should still load issue context: an inbox is not a replay of what happened
527before the session started.
528
529Reading does not clear an update. After considering it and recording any
530change of plan, the session owner acknowledges exact IDs:
531
532```sh
533g1t api record_session_entries -f id=SESSION_ID -f 'acknowledge[]=UPDATE_ID'
534```
535
536Repeat the field for multiple IDs, at most 100 per request, then read again
537for the next page. Acknowledgement is idempotent and scoped to that session.
538It means considered, not resolved. The response's `acknowledged` says how
539many of the IDs name updates of that session, so a mistyped ID or one from
540another session shows up as a shortfall (the CLI warns). The session page
541shows pending updates.
542
543Claude Code hooks retrieve updates in the background, at most once per ten
544seconds when a successful cached response exists, and at once after an
545acknowledgement. Every prompt shows what is pending; before a tool, pending
546updates are shown when they change and again every two minutes. Delivery
547repeats until acknowledged. Other
548harnesses, including managed sessions, should poll between work steps using
549the coordination skill. Neither a disconnected harness nor an idle session
550is interrupted in real time.
551
552An update is written in the same transaction as the change it announces: a
553claim, release, hand-off, expiry, session start or end, overlap, decision or
554change to what an issue is blocked by is never kept without its updates, and
555updates never announce a change that was not made. Each update's ID is
556derived from its change, so a retried request, or two requests making the
557same change at once, delivers it once. The one exception is the notice that
558an issue's blocker closed or merged, which follows the close or merge: it
559is written right after, once per close or merge. Updates are still a
560summary: re-read current issue and pull request state before consequential
561actions.
562
563Acknowledged updates are kept as receipts for 30 days. Pending updates stay
564until acknowledged, including those of a session that ended, so whoever
565takes over its work can see what it never considered.