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.

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