fix(implement-loop): stamp a repo-root anchor into every stage prompt

In worktree sessions a dispatched agent's cwd can resolve to the
primary checkout instead of the loop's working tree — observed as a
per-dispatch race: 6/9 quality dispatches returning infra_blocked with
the sha256-of-empty fingerprint over a real diff, and a tree-check
counting the primary checkout's clean tree into a false no-op BLOCKED
on a genuinely-DONE iteration.

Remedy (validated in the field on the reporting run): the carrier
gains repo_root, stamped into every stage prompt as an explicit
'git -C <root>' anchor with a wrong-directory tripwire (an empty diff
or unexpected HEAD sha = wrong cwd, re-run against the anchor). When
the carrier omits it, the first dispatched stage (mini preflight /
standard plan-index) probes 'git rev-parse --show-toplevel' as a
fallback — itself subject to the same race, so SKILL.md documents the
field as effectively required in worktree sessions.
compiler-driven-edit gets the same carrier field (same defect class,
carrier-only). agent-template stage list updated in passing
(plan-extract[-all], end-verify).

closes #25
This commit is contained in:
2026-07-17 15:35:11 +02:00
parent f5ba8c3747
commit 1cb52fb821
4 changed files with 92 additions and 26 deletions
+12 -2
View File
@@ -210,7 +210,8 @@ Workflow({ name: "implement-loop", args: {
mode: "standard",
iter_id: "<iter_id>",
plan_path: "<path under docs/plans>",
task_range: [3, 8] // optional
task_range: [3, 8], // optional
repo_root: "<abs path of the working tree>" // strongly recommended; effectively required in worktree sessions (issue #25)
}})
```
@@ -222,10 +223,19 @@ Workflow({ name: "implement-loop", args: {
iter_id: "bugfix-<short-symptom>", // tdd: "feat-<short-behaviour>"
red_test_path: "<absolute path>",
cause_summary: "<1-2 sentences from debugger>", // tdd: the desired-behaviour line
constraint: "minimal fix, no surrounding cleanup" // tdd: "minimal feature, no surrounding scope"
constraint: "minimal fix, no surrounding cleanup", // tdd: "minimal feature, no surrounding scope"
repo_root: "<abs path of the working tree>" // strongly recommended; effectively required in worktree sessions (issue #25)
}})
```
`repo_root` is stamped into every stage prompt as a `git -C` anchor:
in worktree sessions a dispatched agent's cwd can resolve to the
primary checkout and review the wrong tree (false `infra_blocked`
quality reviews, a false no-op `BLOCKED` from the end-verify — issue
#25). Without the field the first dispatched stage probes
`git rev-parse --show-toplevel` as a fallback, which is subject to the
same race — pass the field.
The carrier fields are defined authoritatively at the top of
`workflows/implement-loop.js`. The load-bearing `iter_id` rule is there
too: it names the scratch dir and the stats filename, NOT a branch