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.

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