fix(continuity): wire scratch-commit-before-release and rewrite bootstrap prompt (Phase 4 items 3, 5, 6)

Release now re-verifies every handoff Anchor.Dirty file hash (previously
unchecked after the top-level anchor SHA compare), snapshots dirty state
onto a per-task scratch branch before uploading, and rewrites the anchor
to the new commit so successor pickup collapses to a single HEAD compare.
ScratchCommit made idempotent for repeated rotations of the same task.

Bootstrap's prompt now points the agent at the scratch-branch commit
history instead of vague "read the handoff" prose, and does not claim a
GET /v1/artifacts/<ref> endpoint that doesn't exist.

MarkdownChanges had zero callers and zero tests; deleted per AUDIT.md's
explicit deletion option rather than half-wiring an undesigned feature.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W1rkJ2hBMybnJctPbcy4tT
This commit is contained in:
kami
2026-07-27 22:06:06 +04:00
parent 7bcad64398
commit 62bb17e05d
6 changed files with 504 additions and 55 deletions
+41
View File
@@ -99,6 +99,47 @@ Fixed so far:
named caveat: TASK.md hashing is best-effort and untested for the
herdr-hosted (`WorktreeCreator`) worktree path.
- **B5 (closed)** — `CLIAdapter.Release` previously just refused (no real
herdr method existed to call and there was nothing to validate against).
Now: reads the agent-authored `.orchestra-handoff.json` from the worktree
root, validates it with `continuity.Decode`, cross-checks its anchor SHA
against the worktree's real `HeadSHA` (never trusts the agent's self-report
outright), uploads it to CAS via `continuity.Save` to mint the
`handoff_ref`, and only then calls the real `pane.release_agent({pane_id,
source, agent})` to drop herdr's claim — sequenced last so a herdr-side
error can't strand an uploaded handoff. Any failure (missing file, invalid
schema, anchor mismatch, herdr error) is a refusal, which `rotate` already
treats as "retry next tick" rather than stranding the task. `herdr.Claude/
Codex/OpenCode` now take a `continuity.CAS` (main.go passes the existing
`*store.Store`). New tests in `internal/herdr/adapter_test.go` cover all
four paths against a real git worktree and a fake in-process herdr
listener. **Not done:** nothing yet makes the agent actually *write*
`.orchestra-handoff.json` (needs a stop-hook convention analogous to
`.orchestra-report.md`) — that and the rest of Phase 4 (ScratchCommit
before release, §6.2 bootstrap-prompt rewrite, `MarkdownChanges`) remain
open.
- **Phase 4 items 3, 5, 6** — `CLIAdapter.Release` now re-verifies every
`Anchor.Dirty` file hash (previously only the top-level `Anchor.GitSHA`
was checked; a file edited after the handoff was written but before
release would have gone through unnoticed), then, if there were dirty
entries, snapshots them atomically onto a per-task scratch branch
(`continuity.ScratchCommit`, made idempotent so a task can rotate more
than once) and rewrites the handoff's anchor to that new commit with
`Dirty` cleared before uploading — so the successor's pickup check is a
single HEAD compare, not N file rehashes. `CLIAdapter.Bootstrap`'s prompt
was rewritten to point the agent at `git log`/the scratch branch instead
of a vague "read the handoff" instruction, and deliberately avoids
claiming a `GET /v1/artifacts/<ref>` endpoint, since no such route exists
(`/v1/artifacts` is POST-only). `continuity.MarkdownChanges` (§6.3
adjacent-task notice) had zero callers and zero tests despite being
listed as implemented in an earlier snapshot — deleted rather than
half-wired, per AUDIT.md's explicit "delete and record the deviation"
option. New tests: `TestReleaseScratchCommitsDirtyFilesBeforeUpload`,
`TestReleaseRefusesOnStaleDirtyFile` (internal/herdr/adapter_test.go).
**Not done:** Phase 4 item 2 (handoff production for Codex/opencode —
nothing yet drives those harnesses to write `.orchestra-handoff.json`).
Not yet started: B7 (quota projection has no producer),
Codex/opencode completion producers, the turn-decision endpoint, S2S4,
S7S11. See `AUDIT.md` for the full plan.