Repository navigation
fix(gate): closing-keyword sweep never size-skips a REGISTERED parser - #18449
os-elon-musk merged 1 commit into
Conversation
The sweep skipped any tracked file over 2 MiB before reading it. When a file in the PARSERS/NON_PARSERS registry crossed that line the registry check saw it missing from `hits` and reported it as a stale registry row -- "Stale registry entries verify nothing -- remove it, or fix the signature." -- whose prescribed remedy deletes a correct row and silently retires a live parity check. The real cause, the file's size, was named nowhere. Registration is the statement "this file carries the grammar", so the sweep owes it a read whatever `statSync` says: `REGISTERED` is hoisted above the sweep and the cutoff now applies only to unregistered files. `sweep()` also returns `skipped` (file -> cause in words), which does two things: the registry check can distinguish "stopped carrying the grammar" (stale, remove it) from "never opened" (not stale, do not remove it), and the green line names the unregistered files the fourth-parser hunt did not cover instead of implying it read everything. `skipped` is part of the sweep result rather than an optional extra -- a default in `judge()` would silently restore the misdirecting message. Self-test: X13 pins the unread-vs-stale split from both sides (X7 keeps reading as stale); X14/X15 build a real git-tracked tree with two oversized files, one registered and one not, because `extraFiles` hands text in directly and never reaches the `statSync` branch a case must exercise. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HPfcjvF23QBoBj7P47DDxs
Contract reviewServed-tier: Skills seat, ① Derived judgments
② Semver levelNone owed: nothing publishes; ③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
|
Landing provenance — skills seat, Generated by Claude Code |
Fixes #18435
scripts/check-closing-keyword-parity.mjssweeps the whole tracked tree hunting for afourth, unregistered spelling of GitHub's closing-keyword grammar. Its sweep skipped any
file over 2 MiB before reading it — and the registry check downstream had no way to
tell "this file stopped carrying the grammar" from "the sweep never opened this file", so
it reported the second as the first.
Before / after, on the real blocker
scripts/pm/check-half-states.mjsis aPARSERS-registered file and the repo's largestscript. PR #18430 landed while this branch was in flight, which puts it at 2,095,499 B —
1,653 bytes under the 2,097,152 B cutoff. Appending 40 lines of plain comment (2,000 B,
the size of a paragraph of prose, no grammar touched) takes it to 2,097,499 B. Both readings
below are on this branch's base
b6fe311a, same padded file, only the gate swapped.Before — the gate exactly as it ships on
origin/main(exit 1):The prescribed remedy — remove it — deletes a correct registry row and silently retires a
live parity check on H7. The actual cause, the file's size, is named nowhere in the text.
After — this PR's gate, same 2,097,499 B file (exit 0):
The padding was a transient measurement: restored byte-for-byte afterwards, proven by
git hash-objectback to the HEAD blob and an emptygit diff HEAD.scripts/pm/check-half-states.mjscarries no change in this diff — three other PRs ownits regions.
The rule
Registration is the statement this file carries the grammar. A sweep that skips a
registered file does not refute that statement; it simply fails to look. So:
REGISTEREDis hoisted out ofjudge()to above
sweep(), and the cutoff now readssize > SIZE_CUTOFF && !REGISTERED.has(f).A few megabytes of
readFileSyncis by a wide margin the cheaper half of that trade.hunt, and a multi-megabyte blob is overwhelmingly a fixture or a generated corpus — but
the skip is now RECORDED.
sweep()returnsskipped(file to cause, in words) besidehits.hitsandpresent in
skippednow fails with the cause named and the opposite prescription: theentry is NOT stale, do not remove it. A registered file missing from
hitsand NOTskipped still gets the original stale-registry text, unchanged.
file(s)" while having silently read fewer overstates itself. That hole was already there
and nobody could see it:
packages/spec/CHANGELOG.mdat 6,077,484 B has been outside thissweep the whole time. It is a changelog, not a fourth parser — but the gate now says so
out loud instead of implying full coverage.
skippedis part of the sweep result rather than an optional extra, and the one hand-builtsweep object in the self-test was updated to carry it. A default in
judge()would havesilently restored exactly the misdirecting message this PR removes.
New self-test cases, each shown red under a control
--self-testgoes from 30 assertions to 40.X14 / X15 — the cutoff, on a real tree.
extraFileshands the sweep text directly andtherefore never reaches the
statSyncbranch at all, so a case built that way would pinnothing about the cutoff. These build a real git-tracked temp tree with two real oversized
files (3,690,082 B each), one registered and one not, and grade both arms: the registered
one is read, the unregistered one is skipped and the skip is recorded with its cause.
Control — restore the unconditional skip (
size > SIZE_CUTOFFalone), self-test exit 1:X13 — unread is not stale. Control: delete the new diagnostic branch, self-test exit 1,
and the red prints the exact defect text this PR exists to remove:
X7 keeps reading as stale. The genuinely-stale case is unchanged and now also asserts
the negative: it must NOT be reported as unread. An arm that swallowed the other would
retire the check X7 exists to be.
Each control arm was applied to the committed file, proven on disk by grep counts before the
run, restored with
git checkout HEAD -- PATH, and the restore proven by blob hash and anempty
git diff HEAD. The restored tree is green again (exit 0, 40 assertions).Gates
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackfrom thisworktree derived 30 commands for this diff; every one was run in the foreground. Results are
in the report comment on the card.
Changeset
None —
skip-changeset. AGENTS.md Post-Task Checklist step 3: that label 「is for a diffthat publishes nothing from any released package」. This diff is one repo-root script. The
root package is
private: true, no package'sfiles[]ships repo-rootscripts/, and nopackage imports this file —
git grepfinds it referenced only from.github/workflows/,docs/audits/, and comments in three sibling scripts.Acceptance notes
scripts/check-closing-keyword-parity.mjsonly. The fix is in the gate, not inthe file that trips it —
scripts/pm/check-half-states.mjscarries no change here.made the whole-tree read unconditionally expensive and would not have fixed the diagnostic,
which was the part that prescribed the wrong remedy.
packages/spec/CHANGELOG.md(6,077,484 B) has been outside thissweep since the cutoff was introduced. It is release-compiled prose, not a parser, so
there is nothing to register — the new green-line disclosure is the whole remedy. No other
gate was audited for a similar silent size skip; the card records that census as not run.
Generated by Claude Code