Found while measuring the scripts/ bare-root species for #11155. Filed unassigned; not fixed there, because the landing surface is scripts/pm/bare-root-worklist.mjs and #11155's file surface is the gate it judges.
The shape
scripts/pm/bare-root-worklist.mjs records a triage verdict per (family, constant, word) triple. Two rows share the scripts root, and the second one's stated reason is copied from the first:
['check:ratchet-remedy-authority SCRIPTS_DIR scripts', {
verdict: 'REFUSE-UNSPELLABLE',
why: 'reads the TOP LEVEL of the root only, and only two extensions -- 115 of 226 (51%). The '
+ 'idiom has no non-recursive spelling: a subtree hint claims every nested directory too',
}],
['scripts/check-declaration-mirrors.mjs SCRIPTS_DIR scripts', {
verdict: 'REFUSE-UNSPELLABLE',
why: 'same top-level-only shape, 115 of 226 (51%)',
}],
The second row's why is wrong on both of its terms. Measured on a2ec3770:
- The walk is recursive, not top-level-only.
mirrorFiles() in scripts/check-declaration-mirrors.mjs descends (if (e.isDirectory()) walk(p)), and its own docblock says so: "Every scripts/**/*.d.mts, repo-relative, sorted." - The population is 2 files, not 115. The filter is the
.d.mts extension, not "two extensions":
node -e "import('./scripts/check-declaration-mirrors.mjs').then(m=>console.log(m.mirrorFiles()))"
-> scripts/check-regen-pending.d.mts
scripts/js-comment-mask.d.mts
git ls-files scripts | wc -l -> 236
So the honest ratio is 2 of 236 (0.85%), not 115 of 226 (51%).
Why it matters even though the verdict is right
REFUSE-UNSPELLABLE is the correct verdict here — more strongly correct at 0.85% than at 51%. Nothing is mis-triaged. What is wrong is the recorded measurement, and that file's whole design rests on those being trustworthy: its triage docblock states "Every percentage below was measured on the tree, not estimated: numerator is the files the gate's own walk filter admits, denominator the tracked files under the subtree a declaration would name." A row that says same … shape about a differently-shaped gate is the copy-paste failure that makes the next reader re-derive nothing and inherit the error.
It also mis-files the row under the wrong refusal class. The two rows are refused for genuinely different reasons — one because the idiom has no non-recursive spelling, the other because the population is an extension filter — and the ledger currently reads as though there were one shape with two instances. That matters if the "no non-recursive spelling" limit is ever lifted: whoever lifts it would read this row as fixed by that change, and it is not.
Not caught by the self-test, by construction
--self-test audits the triage keys against the live sweep in both directions (STALE / FRESH) and asserts every verdict is one of the three defined and carries a why longer than 20 characters. Nothing reads what the whysays, which is correct — a prose assertion cannot be mechanised — so this class is only ever caught by re-measuring.
Suggested remedy (not applied here)
Rewrite that one why to its measured terms: a recursive walk under scripts/ filtered to .d.mts, 2 of 236 (0.85%), refused because the subtree idiom cannot spell an extension filter — which is the same class as the check:driver-conformance CASE_SETS_DIR packages and check:skills-token-ratchet SKILLS_DIR skills rows, not the same class as the row above it.
Worth re-deriving the other percentages in the same pass: this one was found by measuring a single row, not by a sweep, so the extent is unmeasured.
Refs
#11155 (where it surfaced) · scripts/pm/bare-root-worklist.mjsTRIAGE · scripts/check-declaration-mirrors.mjsmirrorFiles
Found while measuring the
scripts/bare-root species for #11155. Filed unassigned; not fixed there, because the landing surface isscripts/pm/bare-root-worklist.mjsand #11155's file surface is the gate it judges.The shape
scripts/pm/bare-root-worklist.mjsrecords a triage verdict per(family, constant, word)triple. Two rows share thescriptsroot, and the second one's stated reason is copied from the first:The second row's
whyis wrong on both of its terms. Measured ona2ec3770:mirrorFiles()inscripts/check-declaration-mirrors.mjsdescends (if (e.isDirectory()) walk(p)), and its own docblock says so: "Everyscripts/**/*.d.mts, repo-relative, sorted.".d.mtsextension, not "two extensions":So the honest ratio is 2 of 236 (0.85%), not 115 of 226 (51%).
Why it matters even though the verdict is right
REFUSE-UNSPELLABLEis the correct verdict here — more strongly correct at 0.85% than at 51%. Nothing is mis-triaged. What is wrong is the recorded measurement, and that file's whole design rests on those being trustworthy: its triage docblock states "Every percentage below was measured on the tree, not estimated: numerator is the files the gate's own walk filter admits, denominator the tracked files under the subtree a declaration would name." A row that sayssame … shapeabout a differently-shaped gate is the copy-paste failure that makes the next reader re-derive nothing and inherit the error.It also mis-files the row under the wrong refusal class. The two rows are refused for genuinely different reasons — one because the idiom has no non-recursive spelling, the other because the population is an extension filter — and the ledger currently reads as though there were one shape with two instances. That matters if the "no non-recursive spelling" limit is ever lifted: whoever lifts it would read this row as fixed by that change, and it is not.
Not caught by the self-test, by construction
--self-testaudits the triage keys against the live sweep in both directions (STALE / FRESH) and asserts every verdict is one of the three defined and carries awhylonger than 20 characters. Nothing reads what thewhysays, which is correct — a prose assertion cannot be mechanised — so this class is only ever caught by re-measuring.Suggested remedy (not applied here)
Rewrite that one
whyto its measured terms: a recursive walk underscripts/filtered to.d.mts, 2 of 236 (0.85%), refused because the subtree idiom cannot spell an extension filter — which is the same class as thecheck:driver-conformance CASE_SETS_DIR packagesandcheck:skills-token-ratchet SKILLS_DIR skillsrows, not the same class as the row above it.Worth re-deriving the other percentages in the same pass: this one was found by measuring a single row, not by a sweep, so the extent is unmeasured.
Refs
#11155 (where it surfaced) ·
scripts/pm/bare-root-worklist.mjsTRIAGE·scripts/check-declaration-mirrors.mjsmirrorFiles