Measured while fixing #12289. ⛔ Not fixed there — that card's declared surface is scripts/pm/bare-root-worklist.mjs, and this lives in scripts/pm/dispatch-gates.mjs. Filed unassigned, not graded.
Measured on a6b6e54a26, driving the real hintCovers.
The shape
#12300 routed a glob in a non-final segment through triggerCovers instead of the collapse. In that matcher, ** matches one or more path segments, never zero:
hintCovers('scripts/**/*.d.mts', 'scripts/pm/x.d.mts') -> true (one segment)
hintCovers('scripts/**/*.d.mts', 'scripts/invoked-as.d.mts') -> false (zero segments)
hintCovers('packages/**/*.ts', 'packages/x.ts') -> false (zero segments)
Conventional glob semantics — and the reading a hint author will assume — is that a/**/b matches a/b. The three tracked files scripts/**/*.d.mts is the natural spelling for sit at the top level of the root:
scripts/check-regen-pending.d.mts
scripts/invoked-as.d.mts
scripts/js-comment-mask.d.mts
So the hint names three files and reaches none of them. That is the same failure mode #12246 was filed for — a hint that matches nothing BY CONSTRUCTION while looking like an ordinary literal — arriving through the branch that fixed it, for a different reason.
The other spelling is dead too, by the older route: scripts/*.d.mts is a final-segment glob, so it still goes through collapseHint, which yields scripts/.d.mts and matches 0.
Why it is worth a row
The hintCovers docblock prices a fabricated lead above a missing one, and a dead hint is worse than both: unreachableClass classifies a dead hint whose deepest differs from its collapsed form as "THE LAYOUT MOVED … a real miss, worth triaging" — the wrong-classification-plus-wrong-evidence row #12300's commit body calls "the worst row this output can print". A zero-segment ** reproduces the conditions for it.
⭐ It also silently props up a recorded verdict. scripts/pm/bare-root-worklist.mjs's scripts/check-declaration-mirrors.mjs SCRIPTS_DIR scripts row refuses on the grounds that "what cannot be spelled here is the EXTENSION filter" — and today that is true only because of this gap. Both spellings of its population are dead: one on the zero-segment rule, one on the collapse. Fix this and that row's reason becomes stale in the same way #12328 describes for four of its siblings. Worth handling together, or at least knowing about.
Not asserted
Whether **should match zero segments is a real decision, not an obvious bug fix — #12300's self-test deliberately pins a large set of "what this must NOT disturb" cases, including the ROOT_DIR_WATCH_HINTS idiom it measured at −7404 pairs on three gates if widened wrongly. Any change here needs the same measurement. The alternative remedy is to leave the matcher alone and treat scripts/**/*.d.mts as a spelling authors must not use, which argues for a check that refuses a hint reaching zero tracked files at its declaration site.
Repro
node -e "import('./scripts/pm/dispatch-gates.mjs').then(({hintCovers, trackedFiles}) => { const real = trackedFiles().filter(f => f.startsWith('scripts/') && f.endsWith('.d.mts')); console.log('tracked:', real); console.log('reached by scripts/**/*.d.mts:', real.filter(f => hintCovers('scripts/**/*.d.mts', f)).length); console.log('reached by scripts/*.d.mts: ', real.filter(f => hintCovers('scripts/*.d.mts', f)).length);});"Refs: #12300 (added the branch) · #12246 (the dead-hint species) · #12328 (the sibling rows this one is deliberately NOT among) · #12289
Generated by Claude Code
Measured while fixing #12289. ⛔ Not fixed there — that card's declared surface is
scripts/pm/bare-root-worklist.mjs, and this lives inscripts/pm/dispatch-gates.mjs. Filed unassigned, not graded.Measured on
a6b6e54a26, driving the realhintCovers.The shape
#12300 routed a glob in a non-final segment through
triggerCoversinstead of the collapse. In that matcher,**matches one or more path segments, never zero:Conventional glob semantics — and the reading a hint author will assume — is that
a/**/bmatchesa/b. The three tracked filesscripts/**/*.d.mtsis the natural spelling for sit at the top level of the root:So the hint names three files and reaches none of them. That is the same failure mode #12246 was filed for — a hint that matches nothing BY CONSTRUCTION while looking like an ordinary literal — arriving through the branch that fixed it, for a different reason.
The other spelling is dead too, by the older route:
scripts/*.d.mtsis a final-segment glob, so it still goes throughcollapseHint, which yieldsscripts/.d.mtsand matches 0.Why it is worth a row
The
hintCoversdocblock prices a fabricated lead above a missing one, and a dead hint is worse than both:unreachableClassclassifies a dead hint whosedeepestdiffers from its collapsed form as "THE LAYOUT MOVED … a real miss, worth triaging" — the wrong-classification-plus-wrong-evidence row #12300's commit body calls "the worst row this output can print". A zero-segment**reproduces the conditions for it.⭐ It also silently props up a recorded verdict.
scripts/pm/bare-root-worklist.mjs'sscripts/check-declaration-mirrors.mjs SCRIPTS_DIR scriptsrow refuses on the grounds that "what cannot be spelled here is the EXTENSION filter" — and today that is true only because of this gap. Both spellings of its population are dead: one on the zero-segment rule, one on the collapse. Fix this and that row's reason becomes stale in the same way #12328 describes for four of its siblings. Worth handling together, or at least knowing about.Not asserted
Whether
**should match zero segments is a real decision, not an obvious bug fix — #12300's self-test deliberately pins a large set of "what this must NOT disturb" cases, including theROOT_DIR_WATCH_HINTSidiom it measured at −7404 pairs on three gates if widened wrongly. Any change here needs the same measurement. The alternative remedy is to leave the matcher alone and treatscripts/**/*.d.mtsas a spelling authors must not use, which argues for a check that refuses a hint reaching zero tracked files at its declaration site.Repro
Refs: #12300 (added the branch) · #12246 (the dead-hint species) · #12328 (the sibling rows this one is deliberately NOT among) · #12289
Generated by Claude Code