fix(pm): check-harness-current prints boundary, not a fabricated sha, when a harness path's latest touch is not provable on the shallow checkout - #18352
Conversation
… when a harness path's latest touch is not provable `git log -1 <ref> -- <path>` on the shared SHALLOW checkout names the clone's graft boundary whenever no commit above the shallow floor touched the path: the boundary's object names a parent the clone lacks, git applies the graft at traversal, diffs the commit against the EMPTY tree, and every path in its tree reads as touched there -- at exit 0, with no warning. The harness-currency verdict survives that (it is a placement question about a COMMIT, and the boundary is an ancestor-side stand-in for a true touch that sits at or below the floor), but the sha printed beside it was offered as the path's provenance and is not a reading of the path. Take the reading through `touchIsProvable` and print `boundary` / `unprovable` with the reason in place of a sha that cannot be proven, and the sha WITH its proof (parents present, diff-tree touches the path) when it can. No fetching: the shared checkout is not this tool's to deepen. The verdict computation, the exit codes and the CURRENT / STALE / UNDECIDED summary line are untouched -- other seats read those. Adds a 14-case `--self-test` over real shallow and complete fixture clones: the boundary reading, the provable reading on the same clone, the byte-identical summary in both, the STALE and UNDECIDED branches, and the no-fetch invariant. Claude-Session: https://claude.ai/code/session_01HZfg2AwVX191qCizp88gQr Co-authored-by: Claude <noreply@anthropic.com>
Contract reviewServed-tier: Reviewing seat: ① Derived judgments
② Semver levelNot applicable — nothing published moves; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
Landing provenance — skills seat, session Generated by Claude Code |
Fixes #18330
The defect
scripts/pm/check-harness-current.mjstook each harness path's latest touch from rawgit log -1 REF -- PATHon the shared SHALLOW checkout and printed the resulting sha as that path's provenance. On a shallow clone that sha is routinely the clone's own graft boundary: the boundary's commit object names a parent the clone does not have, git applies the graft at traversal, diffs the commit against the EMPTY tree, and every path in its tree reads as touched there — at exit 0, with no warning.The same mechanism was observed three times on the shared checkout within one shift, at three different fetch states, naming three different shas for
.claude/hooks/*:9b00f9f9cf(the card's reading),af3add1601, anda0dd872c1b(the reading quoted below). None of them changed a hook.What changed
The provenance clause — and only that clause — now goes through
touchIsProvablefromscripts/pm/git-history.mjs(the proven leg that landed with PR #18327, itself the second half of the finding filed from #18180):[proven: N parent(s) present locally, diff-tree touches PATH].boundaryis printed in place of the sha, followed by the tool's own reason.unprovable, followed by the reason.It never fetches. The shared checkout is not this tool's to deepen (deepening is an operator action per
scripts/pm/git-history.mjs's header), and a seat-side reading must not mutate the tree every other seat is reading. A self-test case pins that the clone is still shallow and its boundary unmoved after a run.What deliberately did NOT change
The verdict computation (the
merge-base --is-ancestortest and the committer-time / shallow fallback), the three exit codes, and the CURRENT / STALE / UNDECIDED summary line are byte-identical — the seating protocol and the triage seat's stand-down logic read those.The header now records WHY the verdict survives a boundary reading: the verdict is a placement question about a COMMIT, not about the path, and a boundary is only ever named when no commit above the shallow floor touched the path — so the true touch sits at or below the floor, hence is an ancestor of the named boundary, and a commit whose descendant is already under HEAD is under HEAD too. The negative direction was already conservative: a negative ancestry test on a shallow clone reports UNDECIDED rather than STALE.
Reverse verification (both versions run back to back on the shared checkout, same tree, same moment)
BEFORE (
origin/mainversion):AFTER (this branch):
diffof the two summary lines is empty; both runs exit 0; the shared checkout is still shallow and.git/shallowis unchanged (md566039b7f8cfd0bcc7ea50d01daf5865d). The provable path (.claude/agents/*.md) keeps the same sha it printed before, now with its proof.Firing control — a deepened clone must print the TRUE sha for the same path, or
boundarywould be a constant rather than a reading. That control runs inside the self-test rather than by hand: the fixture's hook file is touched only at c1, below every shallow floor the test cuts, so the depth-5 clone printsboundaryand the complete clone of the same upstream prints c1's real sha.Self-test — 14 cases, floor pinned at 14
node scripts/pm/check-harness-current.mjs --self-testbuilds a 40-commit fixture upstream carrying the three real harness paths, then clones it shallow (depth 5), complete, and behind:git log -1names the graft boundary for a hook the boundary never changedboundary, with the graft mechanism named-- STALEline-terminalPlus a case floor, because
failures === 0alone cannot tell "every case held" from "the cases never ran".Gates
node scripts/pm/dispatch-gates.mjs --commands scripts/pm/check-harness-current.mjsderived 29 commands; all 29 ran and all exit 0, reconciled with--ran(29 derived, 29 run, 0 NOT-MEASURED, 0 UNRUN). Plusnpx eslint scripts/pm/check-harness-current.mjs(exit 0) and the new--self-test(14/14).pnpm check:pm-dispatch-gatesis not derived for this path and was not run.Acceptance notes (noted, not filed)
--self-testruns in no CI job.check-self-test-wiredcounts 228 scripts underscripts/carrying a--self-testand 212 that CI runs; this script is named by no workflow and no rootpackage.jsonalias, so it is outside that gate's population and joins a pre-existing set of ~15. Wiring it would mean a fourthrun_self_testline in lint.yml'sShallow-history guard self-testscollector (plus that step's closing prose, whichcheck-step-collectors.mjs --self-testextracts and drives) — both outside this card's file surface. Left for the seat.touchIsProvablereportsboundary: falsefor a registered graft whose parent has since been fetched. Measured on the shared checkout earlier in the same shift:af3add1601was listed in.git/shallow, sogit logandgit show --statapplied the graft and credited it with every path in its tree, while its object's parentd285bf0fwas present locally — so leg 1 (object parents present) passed and the verdict came backprovable: false, boundary: falsewith the reason "has its parent(s) locally but its diff does not touch PATH". The refusal is correct and this script printsunprovablerather than a fabricated sha either way, but theboundaryflag is a false negative, and the discriminator that would not miss it is membership in.git/shallowrather than object-parent presence.scripts/pm/git-history.mjsis consumed, not edited, on this card; carded in the report for the seat to file. Dedupe words:touchIsProvable stale shallow entry·graft registered parent present·boundary false negative diff-tree·git shallow file membership·objectParents presence insufficient.Generated by Claude Code