stop the handoff outranking the log, and gate the pointers into it

A session picked up work from .scratch/continue.md and offered the human a doc
trim that was already in HEAD. The handoff was written at 01:06 saying the trim
awaited a yes; the commit containing the trim was amended at 01:12, underneath
it. Five defects made that possible, and four of them are the harness's.

The read order inverted trust: docs/README.md sent the next session to the
handoff "if present, otherwise git log" — consulting the one ungated file
instead of the record that cannot lie, which is backwards from every other rule
here, where the code beats state.md and generated surface.md beats memory. The
handoff is now step 4 of CLAUDE.md's read order, explicitly after the harness
and never instead of it, and anything it calls pending is checked with
git log -- <path> first.

The tick fired too early. "A planned item completed → tick it in continue.md"
sat in the Document step, so it recorded the plan's version of events while the
commit could still move; an amend, a squash or a late fix moves it. Reconciling
now happens after the commit exists, and a completed item is deleted rather than
ticked, because a ticked item still reads as an item.

HARNESS.md authorised the drift outright — it said the file holds "what is
done", which is exactly what continue.md's own header promises it never records.
It is now described as what it is: a temporary handoff, uncommitted, ungated,
discardable, holding the continuation point and the carried findings.

state.md still pointed at .scratch/build-queue.md, replaced two commits earlier.
The dangling-path gate missed it because .scratch was absent from its
alternation, so no pointer into the handoff directory was ever checked. It is
included now, guarded on the directory existing — a fresh clone has no handoff
and must stay green. Both directions were run: present with a stale pointer
fails, absent with docs naming it passes. The gate then flagged its own
explanatory comment, which is why that one path is written without backticks.

No gate can compare an uncommitted file against anything, so the file's job is
narrowed instead of enforced, and HARNESS.md now says which mechanism stands in
for the missing gate rather than implying one exists.

6 files, +47/-9. No rule, threshold or counter moved. CLAUDE.md 138 → 142 of 150.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-02 16:53:58 +06:00
co-authored by Claude Opus 5
parent 1510a5ff7a
commit 8f5d479f06
6 changed files with 47 additions and 9 deletions
+14 -2
View File
@@ -8,8 +8,10 @@ constitution (always loaded). `docs/` is what the agent needs to build the
engine — anything in it may be pulled into context on demand. `ideas/` and `reference/` sit outside
`docs/` deliberately: storage, opened only when you name a file, swept by nothing.
`.claude/` holds the feature-loop skill (`skills/feature-loop/`), the commands, and `launch.json`.
`scripts/` holds the gate. `.scratch/continue.md` is uncommitted and holds the plan: what is done, what is
next, and the findings worth carrying that no doc owns.
`scripts/` holds the gate. `.scratch/continue.md` is a **temporary** handoff — uncommitted, ungated,
discardable — holding the continuation point and the findings worth carrying that no doc owns. It is read
after the harness rather than instead of it (`CLAUDE.md` §1), and never records what landed: that is
`git log`'s alone, for the reason under "Why the pieces exist".
## How you use it
@@ -176,6 +178,16 @@ lives in its own repository and is passed to the binary with `-site` (ADR-0011),
is the engine's own job rather than the gate's. The gate skips `ideas/`, `reference/` and the uncommitted
`.scratch/`, so exploratory code parked there never has to compile.
**The handoff is the one state-describing file no gate can check, so its job is narrowed instead.**
`state.md`'s currency is compared against the last `.go` commit (ADR-0057), `surface.md` is generated and
diffed, the theme contract and this file are coupled to what they describe. `.scratch/continue.md` can have
none of that: it is gitignored, so there is no commit to compare it against. Two things stand in for the
gate it cannot have — it holds the plan and the carried findings but never what landed, and the read order
puts `git log` first with the handoff read against it (`docs/README.md`). The one check that *is* mechanical
now runs: a `.scratch/` path named in a doc must exist, guarded on the directory being present so a fresh
clone with no handoff still passes. A handoff that recorded what landed was believed for a whole session —
it said a doc trim awaited a yes while the commit being amended around it had already done the trim.
**The architecture gate.** `verify.sh` enforces the layering in `conventions.md` from `go list`
output: content imports no sibling, render imports neither web nor ext, web imports no ext, nothing
imports `cmd`. One convenient sibling import is what turns a layered engine into a ball of mud, and