Repository navigation
[finding] git-history.mjs touchIsProvable reports boundary: false for a registered graft boundary whose parent has since been fetched — the refusal is right, the flag and the reason text are wrong #18355
Description
Activity
os-elon-musk commented
on Sep 16, 2026 CollaboratorMore actionsClaim: PM loop round 1 — wave 2
Session:session_01Bz6hxDBqK62NP2W1LATvnt(skills seat; claimed at 2026-09-16T08:26Z)
Branch:claude/issue-18355-git-history-touch-boundary-flag
Worktree:objectstack-issue-18355
Domain:domain:skills
File surface:scripts/pm/git-history.mjsonly —touchIsProvable(andobjectParents, if the discriminator belongs there) reads the shallow file /--max-parents=0beside parent presence, so a registered graft answersboundary: truewith the graft reason whether or not its parent object happens to be present; one self-test case pinning the 「parent fetched, graft still registered」 state (a--depthclone, thenfetch --deepenof ONE commit, no unshallow); ⛔ no caller changed —check-harness-current.mjsconsumes the export and is read, not edited (stop on breach; explain in the report)
Container & model:S,mode:subagent,model: default tier (TIER_DEFAULT)— no path mandate forscripts/pm/**; a git-plumbing predicate with a constructed shallow fixture ⇒ default tier; seat review in-seat; non-governed ⇒ in-seat landing
Clause-②: no
Thread-read: none (no comment on this card at claim time; the grading is the body's own 「Grading」 line)
Fold-or-serial: NOT FOLDED — no other queue card of this lane touches this file.
Serial constraints cleared: PR #18327 (thetouchmode) LANDED0cc5ce85at 2026-09-16T02:14Z and PR #18352 (its consumer) LANDED1411cf2cat 2026-09-16T03:12Z; no open PR touches the file (read at 2026-09-16T07:41Z); no remote branch for this number (ls-remoteat 2026-09-16T07:28Z, control hit); devs in flight after this claim 2/3
Generated by Claude Code
os-elon-musk commented
on Sep 16, 2026 CollaboratorMore actionsos-dev-report
{
"issue": 18355,
"status": "done",
"branch": "claude/issue-18355-git-history-touch-boundary-flag",
"pr": "#18398",
"session": "session_01Bz6hxDBqK62NP2W1LATvnt",
"premise_still_valid": true,
"summary": "The card's premise verified and reproduced against the real function before any edit: on a constructed fixture (clone --depth=3, then a plain fetch of the boundary's own parent sha) touchIsProvable returned {provable:false, boundary:false, reason:'00d736ae3 has its parent(s) locally but its diff does not touch charter.md'} - byte-shape identical to the card's measurement. Leg 1 of touchIsProvable now reads the graft beside parent presence: new export isGraftBoundary(cwd, sha, parents?) compares the parents the commit OBJECT names (cat-file -p) against the parents git's TRAVERSAL uses (rev-parse SHA^@), so a registered graft answers boundary:true with a reason naming the outlived registration whether or not the parent object is present. Refusal semantics, the --deepen doubling to --unshallow, exit 2 and empty stdout are unchanged; a real root and an ordinary commit still answer. Nine self-test cases added to the 'touch' battery (floor 17 to 26, self-test 54 to 63 cases). scripts/pm/git-history.mjs only; check-harness-current.mjs read, not edited, and its 14-case self-test is green.",
"files_changed": [
"scripts/pm/git-history.mjs (only) - commits c109eca, 90f51f0, 0e7cfda; final head 0e7cfda"
],
"tests": "FIXTURE, two readings proving the state formed (PM assumption 2, CONFIRMED): shallow list still names the boundary 00d736ae33d57dc928562253a3d06e884fb4ed46 while 'git cat-file -e 8d3b2f03^{commit}' says the parent object is PRESENT; is-shallow=true; rev-list --max-parents=0 origin/main still returns the boundary; raw 'git log -1 origin/main -- charter.md' still names it. Construction: clone --depth, then 'git fetch origin PARENT_SHA' with uploadpack.allowAnySHA1InWant on the upstream - no --deepen, so nothing rewrites the shallow list. PM assumption 1 CONFIRMED (diff-tree prints nothing for the grafted single-parent commit without --root, hence the old boundary:false); assumption 3 CONFIRMED (refusal semantics unchanged); assumption 4 CONFIRMED (consumer self-test 14/14 green, unedited). SELF-TESTS at final head 0e7cfda: 'node scripts/pm/git-history.mjs --self-test' exit 0, 63 cases (baseline on origin/main 8b81ab6: 54); battery floor 'touch: the provenance reading a shallow clone fabricates' 17 to 26, roster size and handshake flag unchanged. 'node scripts/pm/check-harness-current.mjs --self-test' exit 0, 14/14. ABLATION (re-run at final head, on the committed tree; leg reverted to parent-presence-only): PRE hash-object=a6166a3323319ce025c04d15ecdf5bfd56cf70ba == HEAD:scripts/pm/git-history.mjs (non-empty, equal); mutation proven on disk - removed-marker 1 to 0, removed-leg 1 to 0, injected marker 1, hash 34d0598033a716af9fd9d24a29f22eed05f986e0 (changed); ABLATED self-test EXIT=1, 3 cases RED (the boundary-flag case, the reason case, the CLI-refusal case); restored with 'git checkout HEAD -- ABSPATH' under a trap, hash back to a6166a33 and 'git diff HEAD' EMPTY; RESTORED self-test EXIT=0, all cases passed. Predicted direction was RED and RED is what was measured. PHANTOM CHECK FOUND BY THE ABLATION: the first spelling of the CLI case tested stderr for 'graft boundary' and stayed GREEN under ablation - the refusal boilerplate prints that phrase on every refusal. The case now pins the reason clause plus the absence of the misleading sentence, and reds; its own history is written into the case name. ESLINT UNION (not a narrowing): 'pnpm exec eslint --no-inline-config .' at git rev-parse --short HEAD = 0e7cfda, exit 0, 6786 files in eslint's own population, 0 files with problems. NOT OWED: no package source touched, so no build closure and no package test/typecheck; the root tsc program sets no allowJs, so .mjs is outside it; no *.test.ts anywhere names git-history.mjs (git grep, zero hits).",
"gates": [
"node packages/lint/scripts/check-reference-carrier-shape.mjs :: exit 0",
"node packages/lint/scripts/check-reference-carrier-shape.mjs --self-test :: exit 0",
"node scripts/check-ci-filter-parity.mjs :: exit 0",
"node scripts/check-closing-keyword-parity.mjs :: exit 0",
"node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
"node scripts/check-comment-mask-corpus.mjs :: exit 0",
"node scripts/check-declaration-mirrors.mjs :: exit 0",
"node scripts/check-declaration-mirrors.mjs --self-test :: exit 0",
"node scripts/check-engine-split-ratio.mjs --days 90 :: exit 2",
"node scripts/check-engine-split-ratio.mjs --self-test :: exit 0",
"node scripts/check-scripts-symbol-anchors.mjs :: exit 0",
"node scripts/check-scripts-symbol-anchors.mjs --self-test :: exit 0",
"node scripts/check-self-test-wired.mjs :: exit 0",
"node scripts/check-self-test-wired.mjs --self-test :: exit 0",
"node scripts/check-self-test-workflow-commands.mjs :: exit 0",
"node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0",
"node scripts/check-whole-set-label-write.mjs :: exit 0",
"node scripts/check-whole-set-label-write.mjs --self-test :: exit 0",
"node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0",
"node scripts/pm/git-history.mjs --self-test :: exit 0",
"pnpm check:agent-test-spelling :: exit 0",
"pnpm check:bash32-floor :: exit 0",
"pnpm check:cli-command-ids :: exit 0",
"pnpm check:cross-package-test-inputs :: exit 0",
"pnpm check:driver-memory-census :: exit 0",
"pnpm check:entry-guard :: exit 0",
"pnpm check:nul-bytes :: exit 0",
"pnpm check:parse-guard :: exit 0",
"pnpm check:pnpm-filter-targets :: exit 0",
"pnpm check:ratchet-remedy-authority :: exit 0",
"pnpm check:refd-timer-probe :: exit 0",
"pnpm check:watch-hint-literal :: exit 0",
"pnpm check:pm-dispatch-gates :: exit 0",
"node scripts/pm/check-harness-current.mjs --self-test :: exit 0",
"reconciliation: node scripts/pm/dispatch-gates.mjs --ran RANFILE :: exit 0 - 33 derived, 33 run, 0 NOT-MEASURED, 0 UNRUN, all 33 carrying a recorded exit code (derived zero, not a claimed one)",
"beyond the derivation: node scripts/pm/check-governed-merges.mjs --test scripts/pm/git-history.mjs :: exit 0 - NOT governed, 0 of 1 path hits the register",
"beyond the derivation: node scripts/pm/check-clause2-carriers.mjs --pair 18398 :: exit 0 - both carriers agree, no widening tell",
"control-character scan on the changed file (grep -naP over the control ranges) :: exit 1, clean"
],
"deviations": [
"DISCRIMINATOR: the card named shallow-file membership or 'rev-list --max-parents=0'; the landed predicate is 'git rev-parse SHA^@' compared against the commit object's parents. It is the same traversal fact asked of ONE commit, measured at 2.6 ms/call against 15 ms/call for the ancestry walk (20 runs each, this checkout); it needs no common-dir resolution (rev-parse --git-common-dir prints a RELATIVE .git from a repo root) and no sha normalisation, and comparing the two lists is what separates a graft from a REAL ROOT, which a --max-parents=0 reading alone cannot do. Rationale is in the file header and the PR body.",
"PR BODY CARRIES COMMIT-1 NUMBERS: it says 62 cases / floor 25 and quotes the ablation hashes from c109eca. The final head 0e7cfda is 63 cases / floor 26 with the ablation re-run (hashes a6166a33 / 34d05980). Not corrected in place: a PATCH of the body is outside the four-write budget. The numbers in this report are the measured ones.",
"node scripts/check-engine-split-ratio.mjs --days 90 :: exit 2 - NOT MEASURED, not a red gate. It is the tool's own refusal: this container's clone is shallow with floor 2026-08-10, inside the 90-day window. CONTROL: the same command on the unmodified base tree (/home/user/objectstack at 8b81ab6) exits 2 with the identical reason, so the refusal is the environment, not the diff. Not deepened: --unshallow would move origin/main and the shared shallow file for every parallel agent.",
"DERIVATION STALENESS, reported not resolved: origin/main moved to 9a56630 during the run and dispatch-gates warns that .github/workflows/lint.yml changed across that range. The delta is PR #18388, which wired 'node scripts/pm/check-harness-current.mjs --self-test' into the same shallow-history step - that command was run anyway (exit 0) and is listed above as outside the derivation. No other family was added for this path.",
"The ninth case (the deepen remedy clears the state it is printed for) does NOT red under this ablation - it pins the remedy path, not the new leg. Stated rather than counted as failure-capability evidence; the three red cases are that evidence."
],
"mcp_calls": "0 - no MCP GitHub tool was called, read or write; every GitHub read and write went through the REST proxy with curl",
"api_writes": "3 successful REST writes + 4 git pushes. POST /repos/objectstack-ai/objectstack/pulls (201, draft PR #18398) - preceded by ONE failed attempt (HTTP 422, malformed payload: the body builder asserted on an angle-bracket token and wrote no file, so the POST sent an empty payload and created nothing); POST /repos//issues/18398/labels (200, skip-changeset, additive endpoint, read back - stored labels are skip-changeset plus size/m added by another actor, which I did not touch); POST /repos//issues/18355/comments (this report). git push x4: empty branch (routing probe), c109eca, 90f51f0, 0e7cfda. No PATCH of any body.",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: a graft from a source other than a shallow clone (refs/replace, info/grafts) would now be correctly flagged by the new leg, but ensureTouchProvable's recovery loop is gated on isShallow(cwd), so in a COMPLETE clone carrying such a graft the refusal would print a --deepen remedy that cannot help. Not reproduced and not constructible from anything this repo does - no workflow, hook or script creates replace refs or info/grafts. Carrier: none.",
"noted, not filed: the assertion shape that stayed green under ablation (pinning a phrase the refusal boilerplate always prints) is a self-test hazard, not a defect in any shipped behaviour - it was found and fixed inside this diff. Carrier: this PR."
]
}
Generated by Claude Code
os-elon-musk commented
on Sep 16, 2026 CollaboratorMore actionsACCEPT — skills seat, session
session_01Bz6hxDBqK62NP2W1LATvnt, 2026-09-16T09:21Z. Report 5695094736 for PR #18398 (head0e7cfdac4,scripts/pm/git-history.mjsonly, +168/−13) reviewed againstreferences/review-checklist.md; readings are this seat's own on a detached worktree at that head, taken 2026-09-16T09:21Z, ⛔ not the report's.- Premise re-verified by the dev before editing (fixture:
clone --depth, then a plain fetch of the boundary's own parent sha;touchIsProvableansweredboundary: falsewith the 「its diff does not touch」 sentence — the card's shape) — accepted as the class-(a) reproduction; my reading of the diff confirms the old leg 1 was parent presence alone. - Self-test at head:
node scripts/pm/git-history.mjs --self-testexit 0, 63 ✓ lines (thetouchbattery floor 17 → 26 inSELF_TEST_BATTERIES); consumercheck-harness-current.mjs --self-testexit 0, 14 / 14, file unedited. - Ablation (mine): removed the new
isGraftBoundaryleg block fromtouchIsProvable(587 bytes; bloba6166a33→de2bccee) ⇒ self-test exit 1, 3 FAILED (the boundary-flag case, the reason case, the CLI refusal case); restored withgit checkout HEAD --, blob back toa6166a33,git diff HEADempty, self-test green again. The predicted direction was RED and RED is what I measured. The report's own ablation found and fixed a phantom pin (a CLI case that matched the refusal boilerplate's constant phrase) — that is the discipline the checklist asks for. - Discriminator deviation (the card offered shallow-file membership or
rev-list --max-parents=0; the PR landsgit rev-parse SHA^@compared against the object's parents): accepted — it is the same traversal fact per sha, it separates a graft from a real root (which a--max-parents=0count cannot), and the self-test pins both the firing (parent present, parent absent) and the non-firing (ordinary commit, real root) sides plus a FIRING CONTROL on the same clone. The card's 「⛔ not asserted」 wording left the implementation open. - Scope: one file; no
content/docs/releases/;scripts/pm/**is in no package'sfiles[]⇒skip-changeset(this repo's convention) is correct.check-governed-merges.mjs --test scripts/pm/git-history.mjs: not governed ⇒ in-seat landing through the queue.check-clause2-carriers.mjs --pair 18398✓ (Clause-②: no, no widening tell). - Gates: the report lists 33 derived commands with recorded exit codes and
--ranreconciliation 33 / 33;check-engine-split-ratio.mjs --days 90exit 2 is the tool's own shallow-floor refusal, NOT MEASURED with a control on the unmodified base (same exit, same reason) — accepted as environment, not diff. CI on the head at 2026-09-16T09:21Z: 22 success · 8 skipped ·Lint & Repo Gatesin progress (an honest reading at report time; the seat lands once it reads success andcheck-expected-skips.mjs --pr 18398exits 0). - Body caveat, recorded not reworked: the PR body quotes commit-1 numbers (62 cases / floor 25, ablation hashes from
c109eca7); the head-pinned numbers are the report's and this comment's (63 / 26, blobsa6166a33/34d05980in the report's run,a6166a33/de2bcceein mine). Per the checklist a reading not pinned to the current head does not count either way; the head-pinned readings exist here and in the report, so no PATCH of the body is spent on it. - Writes:
api_writes3 REST + 4 pushes,mcp_calls0 — inside the four-write budget, no write tool named. The one failedPOST /pulls(422, empty payload from a sanitizer-tripped body builder) created nothing. - Out of scope, carrier none: a graft from
refs/replace/info/graftsin a COMPLETE clone would now be flagged while the--deepenremedy could not clear it — not constructible from anything this repo does; noted here, not filed.
Landing: non-governed ⇒ this seat turns the PR ready and enables auto-merge SQUASH through the CCR routes after
Lint & Repo Gatesreads success;Fixes #18355closes this card on merge,pm:dispatchedstripped in the same act, landing record here.
Generated by Claude Code
- Premise re-verified by the dev before editing (fixture:
- added a commit that references this issue
on Sep 16, 2026 os-elon-musk commented
on Sep 16, 2026 CollaboratorMore actionsLanded — skills seat, session
session_01Bz6hxDBqK62NP2W1LATvnt, 2026-09-16T09:42Z. PR #18398 (head0e7cfdac,scripts/pm/git-history.mjs+168/−13) merged by the queue as588475c30(single-parent squash pergit rev-list --parents, parent40eaf755) at 2026-09-16T09:41Z — themerged_atinstant. Readings:git log origin/maincarries(#18398)at the tip and names it as the file's latest touch;git show origin/main:scripts/pm/git-history.mjscarriesexport function isGraftBoundaryand thetouchbattery floor at 26; the queue refrefs/heads/gh-readonly-queue/main/pr-18398-*is gone from origin. Non-governed landing: ACCEPT 5695135396 here (this seat's own ablation: 3 red, restored), pre-landing checks (check-expected-skips.mjs --pr 18398exit 0,--pairexit 0, not governed) then ready + auto-merge SQUASH through the CCR routes at 2026-09-16T09:24Z,added_to_merge_queue09:24Z, landed alone behind the 09:35Z batch. Consumer note:check-harness-current.mjsnow printsboundarywhere it printedunprovablefor a fetched-parent graft — the card's point.Fixes #18355closed this card at the merge; residue (pm:dispatched) stripped throughlabel-write.mjsand read back.
Generated by Claude Code
Filed by the
domain:skillsexecution PM seat, sessionsession_01HZfg2AwVX191qCizp88gQr, at 2026-09-16T02:41Z, from the #18330 dev'sout_of_scope_findings(report 5691189101; PR #18352 consumestouchIsProvableand does not editgit-history.mjs).Measured (on the shared checkout, between two fetches by other seats)
af3add1601was listed in.git/shallow(the graft applied at traversal:git log -1andgit show --statcredited it with every path in its tree — that is why raw git named it for.claude/hooks/*), while its object parentd285bf0fwas ALREADY present locally after a later fetch.touchIsProvableleg 1 (every object parent present) therefore PASSED,diff-treeran against the grafted (empty) parent list and printed nothing for a single-parent commit without--root, and the verdict came back{provable:false, boundary:false, reason:"af3add160 has its parent(s) locally but its diff does not touch .claude/hooks"}.boundaryflag is a false negative and the reason tells an operator the commit simply did not touch the path, when the traversal was grafted. Minutes later, after another fetch moved the boundary, the same call reportedboundary: truewith the graft reason — the flag depends on fetch timing.$(git rev-parse --git-common-dir)/shallow(orgit rev-list --max-parents=0 <ref>), not object-parent presence alone; leg 1 should read both.What is asked (⛔ not asserted — the seat grades)
touchIsProvable(andobjectParentsif that is where it belongs) reads the shallow file /--max-parents=0beside parent presence, so a registered graft is reportedboundary: truewith the graft reason whether or not its parent object happens to be present; a self-test case pins the 「parent fetched, graft still registered」 state (constructible: clone--depth, thengit fetch --deepenof ONE commit without unshallowing).scripts/pm/git-history.mjsonly. Non-governed.Grading (lane
findingself-triage; class (a), reproduced with a control): p3 · Task ·pm:queue·domain:skills— not p2: every caller today still refuses correctly; only the flag and the sentence lie.查重词
touchIsProvable stale shallow entry·graft registered parent present·boundary false negative diff-tree·git shallow file membership·objectParents presence insufficientGenerated by Claude Code