fix(pm): bare-root-worklist sweeps the bare ROOTS / DIRS spellings, and names what it now sees but has not judged (#15468) - #15767
Conversation
POPULATION_CONSTANT required a literal underscore in every alternative but POPULATION, so `SCAN_ROOTS` matched and the plainest spelling of the shape this sweep exists to find -- `const ROOTS = [...]` -- did not. The instrument that reports on invisibility was itself blind to it, and no reader of its output could infer the omission from the output. Admitted as two EXACT alternatives, never as `_?` on the two that were there: that looser edit also admits ROOT, DIR and SCANROOTS, and the bare singular ROOT is this tree's commonest name for a repo root -- one path fragment, the thing the regex exists to exclude. Pinned in --self-test in both directions, with SCAN_ROOTS / SCAN_DIRS / POPULATION as the control that the widening added alternatives rather than replacing them. Measured on 66e68ad before the regex moved: the two names add 23 rows across 11 gate source files, and the profile is the OPPOSITE of --wide -- 21 of 23 are real populations (recursive readdirSync walk, or git ls-files over the root), 2 are a label/name field beside a separator-carrying path that was always visible, and NONE is a join() path component in a gate that never reads the root. 12 land REACHABLE against declarations their gates already carry; 11 land open with no verdict. No verdict rows are written -- the map is shrink-only and maintainer-ruled. The 11 go into a new UNJUDGED bucket: seen, measured, judged by nobody, and printed under the worklist so the debt list stops reading as complete. The exclusion buys no silence, because --self-test holds the bucket SET-EQUAL to the open rows carrying no verdict in both directions -- a row can only leave the FRESH case by being NAMED, and anything unlisted still prints as UNTRIAGED and still reds. The two battery floors this touches are re-baselined to their measured run counts (17 and 19 static cases, no loops or conditionals in either region), the convention the roster's other entries follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
|
ACCEPT — PR #15767 (head Exactly the ruling: Measured by this seat (branch blob at Closing keyword changed by the PM: Ruling on Q6 (battery floors re-baselined to measured run counts 17 / 19): A, as landed — the roster convention is measured counts and both regions are loop-free. Process note recorded, not penalised: the first commit skipped Flip + arm when both required jobs report success on Generated by Claude Code |
|
Flipped ready + auto-merge enabled (07:15Z, Generated by Claude Code |
Part of #15468 (the widening and the UNJUDGED bucket; the 11 verdict rows are the maintainer's and keep the card open)
POPULATION_CONSTANTis the one judgement callbare-root-worklist.mjsmakes: whichconstant NAMES say "this is my population". Every alternative but
POPULATIONrequired aliteral underscore — the leading character class may be empty only if an underscore
follows it — so
SCAN_ROOTSmatched and the plainest spelling of the very shape thissweep exists to find did not. A gate whose author wrote a bare
ROOTSarray was invisibleto the instrument that reports on invisibility, and nothing in its output said so.
Measured FIRST, on the branch base
66e68adc6The card asked for the measurement before the regex moved, and it is the half a regex edit
cannot assert. Taken with an untracked copy of the map carrying only the widened
recogniser, run against the same tree:
Classified per row, at file and line, against each gate's own source:
readdirSyncwalk, orgit ls-filesover the root.
label:/name:field sitting beside a separator-carryingpath that the derivation always saw. Both spell the word
docs.--widefinds: ajoin()path component in a gate that neverreads the root.
That profile is the whole argument that this is not the wide sweep in miniature.
--widefinds roughly twice the rows and is overwhelmingly the component shape; it remains
runnable, untriaged, and unchanged by this PR.
Of the 23, 12 land REACHABLE against declarations their gates already carry, and
11 land open with no verdict.
What changed
Two EXACT alternatives were added, never
_?on the two that were there. That looser editreads as the same repair and is not — it also admits
ROOT,DIRandSCANROOTS, and thebare singular
ROOTis this tree's commonest name for a repo root, one path fragment andthe exact thing the regex exists to exclude. Pinned in
--self-test, both directions:ROOTSDIRSROOTDIRROOTS_XSCANROOTSSCAN_ROOTSSCAN_DIRSPOPULATIONNo verdict rows are written
The map is shrink-only and maintainer-ruled, so the pass that made these rows visible may
not judge them. The thing it must not do instead is go quiet — an unlisted row is exactly
what the
--self-testFRESH clause would have been silenced into. The 11 go into a newUNJUDGEDbucket: seen, measured, judged by nobody, printed under the worklist so the debtlist stops reading as complete, each carrying a measurement of how the literal is used in
its gate (never a judgement of it) plus the base it was measured on.
The exclusion buys no silence.
--self-testholds the bucket SET-EQUAL to the open rowscarrying no verdict, in both directions:
and still prints as
UNTRIAGEDrather than asUNJUDGED;Plus: disjoint from
TRIAGEandCENSUS_REFUSE_WIDE, well-formed entries, one shared base,non-empty, and no key entering this file's own hint set.
The 11 UNJUDGED rows, for the maintainer (three are one gate's walked triple):
check-doc-security-posture.mjs ROOTS docs— NOT a population (alabelfield)check-doc-security-posture.mjs ROOTS skills— walked,.mdunder the rootcheck-doc-frontmatter.mjs ROOTS docs— NOT a population (anamefield)check-live-db-isolation.mjs ROOTS×apps/examples/packages— walkedcheck-vendor-version-stamps.mjs ROOTS×apps/examples/packages/scripts— walkedcheck-whole-set-label-write.mjs ROOTS scripts— walked, and the gate already declaresa strictly NARROWER extension filter at that root
The two gates the card named, measured under the widened sweep
check-live-db-isolation.mjs(ROOTS) reads UNJUDGED, not declared. It does carrythe [finding] 16 gates CI runs declare no path at all and walk a subtree, so dispatch-gates scores them undetermined for every card — the sibling half of #15082, measured #15341
wide-populationmarker and this file does read it — but that marker excuses arow that is COVERED and carries a recorded verdict, and these three rows are neither. Its
packagesrow is judged inCENSUS_REFUSE_WIDE; that table is a different key space thissweep cannot produce and is deliberately not coupled to it ([finding] 14 root-wide gate families measure into bare-root-worklist's REFUSE-WIDE class (32–52 % of
packages/) but carry no ledger row — so the class reads as undecided debt when it has been ruled #14695), and it says nothingabout
appsorexamples. The marker count in the verdict line moves 9 to 12 accordingly,with none of them covered.
check-org-identifier.mjs(ROOTS) reads REACHABLE — the declaration it gained infix(scripts): the subtree-walking gates declare their watch hints, so dispatch-gates names them (#15341) #15466 covers all three of its roots, so it owes no row and is not in the bucket.
Verification
Exit codes captured before any pipe; verdict lines quoted as the gates print them.
node scripts/pm/bare-root-worklist.mjs --self-test— BEFORE, on66e68adc6:AFTER, on
25036cc5e:The sweep's own output moves
54 ... 34 gate source file(s) ... 8 now reachable; 46 still unreachableto77 ... 43 gate source file(s) ... 20 now reachable; 57 still unreachable,with the 11-row UNJUDGED section printed after the worklist.
Ablation, trap-guarded, blob-hash restore
Direction predicted before running: the recogniser pin fails, and BOTH bucket-coupling
cases fail (11 entries against 0 live rows), while the negative-control case still passes
because the refused spellings stay refused.
4ea5bb6evs HEAD4f2db5a8;node --checkclean, so the run is an ablation and not a syntax error--self-testexit 1, 3 failing cases: the recogniser pin,no UNJUDGED entry outlives the row it names(STALE, all 11 named), andthe UNJUDGED bucket names EXACTLY the open rows carrying no verdict — 11 entr(ies), 0 such row(s)— as predictedgit checkout HEAD -- ...with an absolute path;git diff HEADempty (0 bytes),git hash-object== HEAD blob4f2db5a8,git statusclean,--self-testexit 0garbage, produced a syntax error, and exited 1 with zero cases printed. Read from the exit
code alone that is indistinguishable from a successful ablation. It was caught by the
injected-text count reading 0, which is why that check exists, and the
node --checklegabove was added from it.
The derived gate family — all 28 measured, all green
node scripts/pm/dispatch-gates.mjs --changed --commands --repo objectstack-ai/objectstack(exit 0) derived 28 commands at
25036cc5e. Every one of them was run and every one exits0. Notable verdict lines:
NOT MEASURED: none. Seven of the 28 first exited 3 / 1 on a missing dependency
(
typescript,yaml,@typescript-eslint/parser). Rather than report them by name asunmeasured,
pnpm install --offlinesucceeded from the lockfile and all seven were re-rungreen —
check-comment-mask-corpusin particular genuinely bears on this diff, since itdiffs comment ranges byte-for-byte over every JS file and this PR adds a great deal of
comment prose.
node scripts/pm/check-governed-merges.mjs --test scripts/pm/bare-root-worklist.mjs:Changeset
None, and
skip-changesetapplies: AGENTS.md scopes that label to "a diff that publishesnothing from any released package", and this diff is one repo-internal PM tool under
scripts/pm/.Two things worth a reviewer's eye
their measured run counts — 17 and 19. The triage battery's floor was 6 while it ran 13,
so raising it to 19 floors seven pre-existing cases that were not floored before. Both
regions were checked for loops and conditionals (there are none, so the counts are
static), and the roster's other entries are run counts too. Say the word and it goes back
to 12, which floors only what this PR adds.
this file enters its OWN hint set and names the tool for every card under that root. The
first draft of the bucket tripped exactly that pin, which is now recorded in the
bucket's docblock.
🤖 Generated with Claude Code
https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Generated by Claude Code
Generated by Claude Code