Repository navigation
Description
The problem (CMO)
just finish accepts a review when review.toml names any reviewer that is not empty (sdk/extensionrepo/readiness.go line 30). The ledger accepts any change reviewer and readiness reviewer that are not empty (sdk/extensionrepo/ledger.go line 78). So the author of the code can name a reviewer and pass. The earned "Done when" of an extension depends on this review.
Unknown: how a build records the session ID of each author and of the reviewer without text that the agent types. Claude Code hooks and Codex hooks receive a session ID, and a Codex subagent hook reports the ID of its parent. No code records these IDs today (sdk/extensionrepo/records.go lines 49-92).
The outcome (FMO)
just finish fails when a session ID is missing, or when the reviewer ID is equal to an author ID. The texts call this proof "a different recorded session", not independent reasoning.
Stories
- Nobody knows how to record session IDs. (docs(decisions): record the session ID of each author and of the reviewer #450) · text
- Today: no decision says where each ID comes from.
- After: a decision names the source of each ID for Claude Code and Codex, proven in a scratch extension.
- No session ID is captured. (feat(sdk): the launcher captures the session ID of each author and reviewer from the harness hook #478) · code + tests
- Today: no code captures a session ID.
- After: a launcher and the
SessionStarthook write the emitted ID of each author and reviewer into a context file of the invocation.
- No commit names its author session. (feat(sdk): each commit of a round has an author receipt in Git notes #479) · code + tests
- Today: no receipt binds a commit to the session that wrote it.
- After: each commit of a round has an author receipt in the Git notes ref
refs/notes/nicely-sessions, and the publication pushes that ref.
- No review is bound to its range. (feat(sdk): the reviewer launcher writes a review receipt on the reviewed head #480) · code + tests
- Today: a review names no session and no range.
- After: a new root reviewer session writes a review receipt on the reviewed head.
- The reviewer declares itself. (feat(template): just finish and just signoff fail when a session receipt is missing or the reviewer is an author #451) · code + tests
- Today: a reviewer name that is not empty passes.
- After:
just finishand a detachedjust signofffail on a missing receipt or a matching session ID.
Done when
The decision of #450 is merged. The scenarios of #478, #479, #480 and #451 prove the success and failure examples, and a real build in a scratch extension records two different IDs.
Every Story has a documented disposition. The outcome has delivery evidence.
👨🏻🍳 For the agent
👨🏻🍳 Details
Out of this Epic
- The first real use of the loop: template: an existing extension adopts just finish after the update #427. It records the session IDs in its pull request by hand.
Blocked by
- feat(sdk): the launcher captures the session ID of each author and reviewer from the harness hook #478, feat(sdk): each commit of a round has an author receipt in Git notes #479, feat(sdk): the reviewer launcher writes a review receipt on the reviewed head #480 and feat(template): just finish and just signoff fail when a session receipt is missing or the reviewer is an author #451 are blocked by docs(decisions): record the session ID of each author and of the reviewer #450, because the design comes first. docs(decisions): record the session ID of each author and of the reviewer #450 merged on 2026-11-04 as D069.
- feat(sdk): each commit of a round has an author receipt in Git notes #479 and feat(sdk): the reviewer launcher writes a review receipt on the reviewed head #480 are blocked by feat(sdk): the launcher captures the session ID of each author and reviewer from the harness hook #478, because they read its capture.
- feat(template): just finish and just signoff fail when a session receipt is missing or the reviewer is an author #451 is blocked by feat(sdk): each commit of a round has an author receipt in Git notes #479 and feat(sdk): the reviewer launcher writes a review receipt on the reviewed head #480, because it checks their receipts.
- feat(template): just finish and just signoff fail when a session receipt is missing or the reviewer is an author #451 is blocked by fix(docs): links point to the release tag, and no private skill is named #446, because both change
template/AGENTS/rule-index/loop.md.jinja. fix(docs): links point to the release tag, and no private skill is named #446 merged on 2026-11-04.
Readiness
The refinement after #450 split #451 into four Stories, as D069 decides. Pascal approved it on 2026-11-04. Each Story is 1-ready-for-agent.
Approaches considered
- gitsign, attestations, or a GitHub App: refused. They prove a key, not an agent session.
- A trusted launcher where
just reviewstarts the reviewer: refused by Pascal on 2026-11-03 (3a chose recorded session IDs).
The launcher of D069 is different. It proves nothing by itself: it only carries the ID that the harness hook emits, and the emitted IDs decide the rule. Pascal approved this difference on 2026-11-04.
by Opus-5.5 via Claude Code
Activity