Files
ersatztv/docs/decisions/records/process/orchestrated-session.md
T
timothyandClaude Fable 5.1 595c819de1 fix(916): a failed substitute is an error, not a landed claim; head_sha described in both schemas; the issue's box says what the code does
The runner-beside-the-lenses design is now what Done-when box 1 asks for (body
amended). A rubric round whose runner and worktree fallback both fail returns
an error before the push instead of landing a PR whose body claims a substitute
reviewed it. The harness records lens count at the runner's start too (expects
0, so a re-serialised runner reddens), resets its counter per round, and has a
case for the double failure.

Decisions-Edit: yes
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QqCpYFsKgnAnx6jVwrKiV
2026-09-05 13:14:09 +02:00

3.4 KiB

key, title, status, since, supersedes, superseded-by, rule, signals, mechanics
key title status since supersedes superseded-by rule signals mechanics
process.orchestrated-session 2026-09-04 — An orchestrated session runs several issue slots under one referee, and each slot is still a whole kickoff session (#907) active 2026-09-04 none none A session may run several issues at once only as an orchestrated session — an orchestrator that never picks, claims, codes or pushes; one worktree per issue under `~/orca/workspaces/ersatztv/`; the local gate and cold review inside the worktree BEFORE the single push; the referee alone ticks `## Done-when` boxes and posts the verdict. Two scopings hold across every slot — a rebase onto `origin/main` pushed with `--force-with-lease` is the ONE sanctioned rewrite of a pushed branch (the commits are unchanged, only the base moved; H11 refuses the alternative and merging main in is forbidden), and it voids the verdict, so the rebased head is re-reviewed. Live-E2E needs no machine-wide lock — the launcher's conflict is its per-worktree `wwwroot`, so slots run on distinct ports and the launcher's pre-flight refuses a busy one. orchestrator · referee · slots · parallel issues · worktree per issue · force-with-lease · rebase voids verdict · who ticks Done-when · E2E per worktree port · paths: `docs/handoffs/orchestration.md`, `docs/handoffs/orchestrator-prompt.md`, `.claude/workflows/ersatztv-issue-build.js` · issues: #907 `docs/handoffs/orchestration.md` owns roles, isolation and the landing order; the Workflow scripts under `.claude/workflows/` encode it. Box-ticking: the implementer writes the evidence per box into the `## Closing record`; the orchestrator ticks after reading it and the review evidence, then `scripts/post-review-verdict.sh`.

The kickoff (docs/handoffs/chicorytv-issue-queue.md) binds a session that closes one issue. Running several at once does not relax any of it; what it adds is a referee, and two places where the single-session rules needed a stated scope rather than a contradiction.

Force-with-lease. process.pr-routine-sequence forbids amending or force-pushing a pushed branch; release.format-as-you-touch-rebase (H11) refuses to push a branch behind origin/main and forbids merging main in. With several slots merging, a pushed branch is behind main as the normal case, so the only path that satisfies both is a rebase whose commits are byte-for-byte the reviewed ones, pushed with --force-with-lease. That is not the rewrite the first rule targets, which is a fix folded into an already-pushed commit. The cost is the verdict: review-verdict/h10 binds to a sha, so the rebased head is reviewed again before a new verdict is posted. Rebase once, right after the review loop, and git patch-id --stable before and after proves the patch did not change.

Who ticks the boxes. release.merge-consent-autogrant derives consent from the ticked boxes, so a box ticked by the agent whose work it certifies is self-consent. The implementer supplies the evidence per box; the referee ticks.

No E2E lock. A mkdir lock around scripts/e2e-local.sh was tried and rejected 2026-09-04: the script is a launcher that returns with the server still running, so the lock released before the assertions ran, and its stale-holder path double-acquired in 4 of 91 measured races. The conflict the launcher documents is its wwwroot under the repo root, which is per worktree; two worktrees on two ports do not share it.