Skip to content

Commit eb40a72

Browse files
claude[bot]claude
andauthored
tooling(pm): pin the tenth DECLARED-NARROWER worklist row to its gate's declaration, and require a spelling on that verdict (#15314)
* tooling(pm): give the tenth DECLARED-NARROWER row a spelling, and make that verdict require one The declaration pin holds a DECLARED-NARROWER record SET-EQUAL to its gate's own declared hint array, read from the gate source. It reached nine of the ten such rows: `check-driver-conformance DRIVERS_DIR packages` carried no `spelling`, so there was no recorded set to compare and the pin skipped it by its own scoping rule -- while that gate does declare a hint at that root. The row named the subtree in prose, and nothing held the prose to the array. Both terms are re-measured together on one tree (commit 2200f8e, tree b8ebad2), against the gate's own walk driven under an fs recorder rather than reproduced by hand: 344 of 379 tracked files under the declared subtree are opened, five manifests are statted, and the declaration errs WIDE by the 30 it names and the gate never touches. The direction is recorded in the row. The floor that stops the class growing back: the requirement to carry a spelling now extends from SPELLABLE-UNDECLARED to DECLARED-NARROWER -- a verdict whose whole content is a claim about a declaration may not decline to record the set that claim is about. The self-test asserts it on the live map and on fixture records, so the rule is proved able to fail. The gate is not edited: it is correct, and the map recorded less than it judged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox * tooling(pm): name the offending row when the spelling requirement reds A bare every() verdict told the next author that some record is unspelled and not which one. The failure text now names the rows and states the remedy in the map's own terms: record the population and point the row at it, or the verdict is one of the two refusals. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1036776 commit eb40a72

1 file changed

Lines changed: 101 additions & 12 deletions

File tree

scripts/pm/bare-root-worklist.mjs

Lines changed: 101 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,18 @@ const POPULATION_CONSTANT = /^(?:[A-Z0-9_]*_ROOTS?|[A-Z0-9_]*_DIRS?|POPULATION|[
124124
* than the bare word. The row stays in the sweep because
125125
* the bare root is still not covered — which is correct,
126126
* not outstanding debt.
127-
* ⛔ A record carrying a `spelling` is pinned against the
128-
* DECLARATION as well as the tree: `--self-test` reads the
127+
* ⛔ Every record MUST carry a `spelling` naming a
128+
* `SPELLINGS` entry, for the reason this verdict is the
129+
* one where the requirement bites hardest: its whole
130+
* content is a claim about a DECLARATION, and a record
131+
* naming no set records nothing for the declaration pin
132+
* to compare — it sits outside that pin by construction,
133+
* not by oversight, keeping its verdict while the gate
134+
* moves under it. Measured, at the one row that did:
135+
* #15270. The requirement is held by `--self-test`, the
136+
* same way it is held for SPELLABLE-UNDECLARED below.
137+
* ⛔ That record is then pinned against the DECLARATION
138+
* as well as the tree: `--self-test` reads the
129139
* gate's own hint array out of its source and holds the
130140
* recorded spelling SET-EQUAL to it at this row's root,
131141
* with any deliberate omission NAMED in `omits` and
@@ -272,6 +282,21 @@ const POPULATION_CONSTANT = /^(?:[A-Z0-9_]*_ROOTS?|[A-Z0-9_]*_DIRS?|POPULATION|[
272282
* (see that verdict's definition above). ⛔ The gate itself is NOT edited from
273283
* here: it is correct, and the map is what went stale.
274284
*
285+
* ⭐ The TENTH DECLARED-NARROWER row was brought INSIDE that pin on 2026-09-04
286+
* (#15270), and it is a repair rather than a re-decision: the verdict is the one
287+
* it has carried since it was written and no authorisation sentence is claimed
288+
* for it. `check-driver-conformance DRIVERS_DIR packages` carried no `spelling`,
289+
* so the declaration pin skipped it by its own scoping rule — while its gate DID
290+
* declare a hint at that root, which the row named in PROSE and nothing held to
291+
* the array. Both terms are re-measured together on one tree in the row itself,
292+
* against the gate's own walk driven under an fs recorder rather than reproduced
293+
* by hand. What changes here is the FLOOR: the requirement to carry a spelling
294+
* now extends from SPELLABLE-UNDECLARED to DECLARED-NARROWER, so a record whose
295+
* whole content is a claim about a declaration may no longer decline to record
296+
* the set that claim is about, and the class cannot grow back one unspelled row
297+
* at a time. ⛔ The gate is not edited from here either: it is correct, and what
298+
* went stale is the MAP, which recorded less than it judged.
299+
*
275300
* ⚠️ One row of that seventeen was re-measured into a DIFFERENT population, not
276301
* merely fresher digits: #12392 (PR #12423, `69d0e18`) made
277302
* `check-skills-token-ratchet`'s walk RECURSIVE over whole skill directories, so
@@ -371,6 +396,17 @@ const SPELLINGS = new Map([
371396
claim: "every file inside a skill's references folder, at any depth",
372397
holds: (s) => s[0] === 'skills' && s.length >= 4 && s[2] === 'references',
373398
}],
399+
['driver package files', {
400+
// The WHOLE subtree, which is what the gate declares -- and the widest of
401+
// the entries here for that reason. Its row's `why` records the direction
402+
// that declaration errs in, measured against the gate's own walk: it names
403+
// 30 files the gate neither opens nor stats. Recording anything narrower
404+
// here would be a claim about a declaration nobody made, which the pin
405+
// below refuses in both directions.
406+
segments: ['packages', 'drivers', '**'],
407+
claim: 'every file at any depth under the drivers directory of the packages root',
408+
holds: (s) => s[0] === 'packages' && s[1] === 'drivers' && s.length >= 3,
409+
}],
374410
// ── Multi-hint entries (#14233) — a gate whose declared population is more
375411
// than one glob at the same root. `holds` accepts whatever any member hint
376412
// covers; see `hintsOf` and the pin loop below for how the union is asked.
@@ -446,8 +482,37 @@ const TRIAGE = new Map([
446482
// ── Taken: a strictly narrower subtree ────────────────────────────────────
447483
['scripts/check-driver-conformance.mjs DRIVERS_DIR packages', {
448484
verdict: 'DECLARED-NARROWER',
449-
why: 'the literal is a join() component; the real population is the driver subtree, declared '
450-
+ 'there at 259 of 291 files (89%) instead of 259 of 4903 (5.3%) at the bare root',
485+
spelling: 'driver package files',
486+
why: 'the literal is a join() component: the gate assembles its scan root from bare '
487+
+ 'single-segment words, so the extractor sees the top-level word and nothing else, and the '
488+
+ 'real population is the driver subtree, declared there beside the constant under the '
489+
+ 'ROOT_DIR_WATCH_HINTS idiom. RE-MEASURED 2026-09-04 (#15270) at commit 2200f8ec, tree '
490+
+ 'b8ebad25 — both terms together on one tree, never refreshed apart — and the previous '
491+
+ 'reading (259 of 291, against 4903 at the bare root) is superseded WHOLE, neither term '
492+
+ 'carried forward. The walk was driven under an fs recorder rather than reproduced by hand, '
493+
+ 'this gate exporting none of it: discovery takes the immediate children of the drivers '
494+
+ 'root that carry a manifest and the driver- prefix (five packages today), and every `.ts` '
495+
+ "file at any depth under each package's src directory is OPENED, node_modules and dist "
496+
+ 'skipped — 344 of the 379 tracked files under the declared subtree, 90.8%, against 5979 '
497+
+ 'tracked under the bare root, 5.8%. The five per-package manifests are STATTED rather than '
498+
+ 'opened, as the existence test that admits a package to the matrix, so 349 of 379 are '
499+
+ 'reached one way or the other. ⚠️ The DIRECTION the declaration errs is stated rather than '
500+
+ 'left to the ratio: it errs WIDE, naming 30 files the gate neither opens nor stats — 11 '
501+
+ 'markdown, 6 tsconfig JSON, 6 config `.ts` sitting beside the manifests rather than under '
502+
+ 'src, 5 LICENSE, one `.mjs` and one dotfile — and it is nevertheless the only spellable '
503+
+ 'claim, since collapseHint can express a SUBTREE and not "the src trees inside it". ⛔ The '
504+
+ 'record is what the gate SPELLS and is not narrowed to the walk: the pin holds it against '
505+
+ 'the DECLARATION, so a spelling narrower than the array would be a claim about a '
506+
+ 'declaration nobody made. Until 2026-09-04 this row named that subtree in PROSE only and '
507+
+ 'was the one DECLARED-NARROWER record with no spelling, so it sat outside the declaration '
508+
+ 'pin #15201 landed — the gate could widen or drop the hint with every pin in this file '
509+
+ 'green — which is why the spelling requirement now extends to this verdict. The other '
510+
+ 'root this gate reads, the case-set directory under the spec package (8 files), stays '
511+
+ 'deliberately undeclared on its own docblock reasoning: that is a population absent from '
512+
+ 'the array, not a declared hint the record passes over, so this row carries no `omits`. '
513+
+ '⛔ The gate is NOT edited from here. The row STAYS in the sweep because the bare root is '
514+
+ 'still not covered — no arbitrary file at the top of packages/ is reached — which is what '
515+
+ 'this verdict says and is correct, not outstanding debt',
451516
}],
452517
['scripts/check-logger-receiver-detach.mjs SCAN_ROOTS packages', {
453518
verdict: 'DECLARED-NARROWER',
@@ -1648,9 +1713,31 @@ function selfTest() {
16481713
// describing the tree. ⛔ The remedy is to re-measure the ROW, never to relax
16491714
// `holds` until it agrees again.
16501715
const spellingRows = [...TRIAGE.entries()].filter(([, v]) => v.spelling);
1651-
t('every SPELLABLE-UNDECLARED record names a spelling — the verdict is DEFINED only with one, '
1652-
+ 'and the ruling that created it rejects the whole option on an unpinned value',
1653-
[...TRIAGE.values()].every((v) => v.verdict !== 'SPELLABLE-UNDECLARED' || Boolean(v.spelling)));
1716+
// The two verdicts whose whole content is a claim only a spelling records, so
1717+
// a record without one records nothing for the pins to hold. SPELLABLE-
1718+
// UNDECLARED says a precise live spelling EXISTS, unpinnable while unspoken;
1719+
// DECLARED-NARROWER says the GATE DECLARES one, which the declaration pin
1720+
// below can compare only against a recorded set. #15270 measured what the
1721+
// second gap costs: the tenth DECLARED-NARROWER record named its subtree in
1722+
// PROSE only, so it sat outside that pin by construction while its gate did
1723+
// declare a hint at that very root — and nothing in this file reddened.
1724+
const SPELLING_REQUIRED = new Set(['SPELLABLE-UNDECLARED', 'DECLARED-NARROWER']);
1725+
const spellingHeld = (v) => !SPELLING_REQUIRED.has(v.verdict) || Boolean(v.spelling);
1726+
const unspelled = [...TRIAGE.entries()].filter(([, v]) => !spellingHeld(v)).map(([k]) => k);
1727+
t('every SPELLABLE-UNDECLARED and every DECLARED-NARROWER record names a spelling — both '
1728+
+ 'verdicts are DEFINED only with one, and the ruling that created the first rejects the '
1729+
+ `whole option on an unpinned value${unspelled.length
1730+
? ` — UNSPELLED: ${unspelled.join(' · ')}. Record the population as a SPELLINGS entry and `
1731+
+ 'point the row at it, re-measuring BOTH terms on one tree; a row that cannot be spelled '
1732+
+ 'is a row whose verdict is one of the two refusals.' : ''}`,
1733+
unspelled.length === 0);
1734+
t('…and that rule can FAIL, asked of FIXTURE records rather than of the map it judges: a '
1735+
+ 'record carrying either verdict and no spelling is REFUSED, while the two refusals — which '
1736+
+ 'have no spelling to record — are not',
1737+
!spellingHeld({ verdict: 'DECLARED-NARROWER' })
1738+
&& !spellingHeld({ verdict: 'SPELLABLE-UNDECLARED' })
1739+
&& spellingHeld({ verdict: 'REFUSE-WIDE' })
1740+
&& spellingHeld({ verdict: 'REFUSE-UNSPELLABLE' }));
16541741
t('every recorded spelling names a SPELLINGS entry',
16551742
spellingRows.every(([, v]) => SPELLINGS.has(v.spelling)));
16561743
t('the pins below judge something — at least one record carries a spelling',
@@ -1709,11 +1796,13 @@ function selfTest() {
17091796
// every run: an omission the gate stopped declaring
17101797
// reds exactly as loudly as one it started.
17111798
//
1712-
// ⛔ Only DECLARED-NARROWER rows carrying a `spelling` are asked, and that is
1713-
// a definition rather than an exemption: a SPELLABLE-UNDECLARED row IS the
1714-
// row whose gate declares nothing for that population, so the comparison
1715-
// there has its answer built into the verdict, and a row with no spelling
1716-
// records no set to compare. ⛔ When this reds the remedy is to re-measure
1799+
// ⛔ Only DECLARED-NARROWER rows are asked, and that is a definition rather
1800+
// than an exemption: a SPELLABLE-UNDECLARED row IS the row whose gate
1801+
// declares nothing for that population, so the comparison there has its
1802+
// answer built into the verdict. The `spelling` test in the loop is belt to
1803+
// the braces above, which now REFUSE such a record rather than let it pass
1804+
// over this pin unjudged (#15270) — reaching it would mean that rule had
1805+
// been removed. ⛔ When this reds the remedy is to re-measure
17171806
// the ROW -- never to extend `omits` until it agrees again, which is the same
17181807
// move as relaxing `holds`, refused above in as many words.
17191808
const declaredHintsAt = (file, root) => {

0 commit comments

Comments
 (0)