Skip to content

Epic 18 · The review record proves a different recorded session #458

Open
1 of 5 issues completed
Open

Description

@pascalandy

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

  1. 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.
  2. 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 SessionStart hook write the emitted ID of each author and reviewer into a context file of the invocation.
  3. 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.
  4. 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.
  5. 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 finish and a detached just signoff fail 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

Blocked by

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 review starts 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    3-pty:p2Normal planned work; default when no priority is established4-epicGroups Stories around a shared outcome through native sub-issues

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions