fix(hygiene): bind each banner figure to the surface its own checks read - #1348
Merged
Conversation
The gate opened every run with one sentence whose leading figure was `codeFiles.length` -- every file type the walk returns -- while the clause that figure sat in named the marker and copyright-header checks, which read `allTs`: `.ts` only. Measured on main, that printed 340 beside two checks reading 329, so a reader taking the sentence at face value got 343. The gap widens on its own: every non-`.ts` file added under the scanned trees moves `codeFiles.length` and leaves `allTs` alone. So the remedy is a binding, not a corrected number, and the figure is not deletable either -- `codeFiles.length` is exactly what the size cap and its advisory measure. The banner is now one line per surface, each count printed beside the checks that consume it, every figure interpolated from the same array those checks are handed below. No threshold, constant, check or scanned file set moved. `test/source-hygiene-scan-surface.test.ts` asserts the binding on a sandbox built so the `.ts` count and the walk count disagree, so printing the walk figure in the marker clause turns it red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016ED4cusQ7pxZ7d7TCLKrZb
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1339
Description
The source-hygiene gate opened every run with one sentence:
That leading
340iscodeFiles.length— every file type the walk returns —while the marker and copyright-header checks named in the same clause read
allTs, which is.tsonly. Re-measured onorigin/main@41232dcbeforetouching anything:
A reader taking the sentence at face value got 343 where the truth is
329, and the 14 files in the gap are exactly the set the gate's own
"Why
.tsonly" paragraph explains is excluded (the foursrc/docs/*.mdpages,seven
scripts/*.mjs,scripts/lib/main-module.d.mts,scripts/lib/source-hygiene-surface.mjs,scripts/wow1-live-schema.sh).The gap is not a stale constant that could be corrected once. It widens on its
own: every non-
.tsfile added anywhere under the scanned trees movescodeFiles.lengthand leavesallTsalone. #1343 added one and took the gapfrom 13 to 14 without going near this line. So the remedy has to be a binding,
not a fresh number.
Type of Change
Related Issues
Fixes #1339. Context, none of it touched here: #1343 (landed the shared surface
module), #1236 (put the root
.tsfiles on the two.tschecks), #1338 and#1346 (the no-producer members of the class, whose ruling is the opposite of
this one's).
Changes Made
Route 2 of the card — one banner line per surface — and why, decided on the
real code. Route 1 (print
allTsin that clause) cannot be done withouteither dropping
codeFiles.length, which the ruling forbids because it is alive reading, or re-running the two figures together in one sentence, which is
route 2 with worse formatting.
codeFiles.lengthis exactly what the size capand its advisory measure, so it keeps its own line, beside the checks where it
is true:
scripts/check-source-hygiene.mjs— the banner statement only, plus thecomment above it recording why the figure is bound rather than corrected and
why it is not deletable. Every figure is interpolated from the same array its
checks are handed a few lines below; the marker/header line prints its own
total and the two parts (
allTs.length - rootTs.lengthandrootTs.length) so the arithmetic is visible and cannot be mis-added the waythe old sentence was.
test/source-hygiene-scan-surface.test.ts— one new case that asserts thebinding. Outside the card's stated file surface, and deliberately: the
acceptance criterion is "demonstrated by asserting the printed figure against
allTsin the gate's own suite", which cannot be met inside the gate alone.test/source-hygiene-header-position.test.ts(source-hygiene-header-position.test.tsprose says "3 of 5.mjsunderscripts/" — it is 2 of 7, both integers were already wrong, and PR #1343 nudges it to 2 of 8 #1346, in flight) and.github/workflows/code-quality.ymlwere left alone..changeset/hygiene-banner-binds-what-the-checks-read.md— emptyfrontmatter; tooling and tests only, nothing ships to users.
Readers checked before choosing route 2, since it reshapes a line other
things read:
test/source-hygiene-scan-surface.test.tsis the only place that asserts onbanner text. All three of its existing assertions still hold unchanged
against the new banner:
TEXT_SCANNED.join(', '), the literal16 root file(s), and the literalplus 3 root .ts file(s)from The three root.tsfiles are outside the TODO/FIXME and copyright-header checks, andplaywright.config.tshas no header #1236 areeach still present, so nothing that The three root
.tsfiles are outside the TODO/FIXME and copyright-header checks, andplaywright.config.tshas no header #1236 or 控制字节扫描仍看不到 docs/、.github/、.claude/ 与根目录的一等文件(含三个根 .ts 配置) #838 pinned was given up..github/workflows/code-quality.ymlpoints at this banner in prose — "Itprints the surface it actually reads on every run — read that banner" — and
names no number and no shape, so it stays true and was not edited.
grepovertest/,docs/,content/,.github/, root*.md).Nothing else moved: no threshold, no constant, no check, and not one file in
any check's input set.
pnpm hygienereads exactly what it read before; onlywhat it prints changed.
Testing
pnpm verifygreen at6fc5222, the branch head this PR is opened on. Thewhole chain ran serialised through the shared verify lock:
Reverse-verified, because a green run proves nothing here — the gate was green
before this PR too. The new case is built on a sandbox where the two figures
disagree: three
.tsfiles under the code trees plus the three root.ts(marker/header surface = 6) against nine files in the walk (size surface = 9),
six of the nine carrying a marker that the marker check never sees. The fixture
asserts
walkSurface > markerHeaderSurfacefirst, so it cannot pass on amis-bound banner by the two happening to be equal.
Then the mis-binding was put back on disk and the suite re-run. Mutation proven
before any verdict was read —
git hash-objectmoved from6f90a9e2f890a7010bb2c2b3d587e71a544d968b, injected text 1 hit, removed text 0hits — and the run went red, on that case alone:
That is the exact defect this PR closes, reproduced and caught: the walk figure
printed in the clause that names the marker and header checks. Restored with
git checkout HEAD -- PATHand proven back at HEAD — blob hash identical,git diff HEADempty — beforepnpm verifywas run.pnpm test)pnpm lint,pnpm lint:i18n-gate)pnpm build)Additional Notes
The control-byte figure was left computed and was not pinned anywhere. This
PR is its own evidence for why: it reads 350 on
mainand 351 on thisbranch, moved by one by the changeset this PR is required to add.
The banner grew from one line to five. That is the point of route 2 — the
workflow comment sends readers here to learn what the gate reads, and the old
single sentence could not answer that question for four different surfaces
without binding a figure to the wrong one.
Generated by Claude Code