Skip to content

[finding] #12300 retired the double-slash refusal — 4 bare-root-worklist TRIAGE rows still refuse on a mechanism the tree no longer has, and their VERDICTS (not just their prose) are now unsupported #12328

Description

@yinlianghui

Blocked-by: #12369

⚠️ STATUS (PM seat #6023, 2026-08-25). Blocked on #12369. The dispatch of this card returned premise_still_valid: false without editing anything: the class is not 4 rows, it is 17 of the 39 recorded verdicts. #12300's retirement is general, not confined to the rows whose prose cites the collapse — only 5 cite it, but the REFUSE-UNSPELLABLE definition at :109-111 moved under 17, each with a measured 100%-precise live spelling. Re-deciding a third of the map is a materially different job from the 4 scoped here, and the vocabulary question this card's "Not asserted" section hands to the maintainer is now #12369, with the full table and 四维分析. This card stays open so its four rows are not hidden behind a closed card.

Measured while fixing #12289 (PR against scripts/pm/bare-root-worklist.mjs). ⛔ Not fixed there — that card is scoped to the reason text of two rows and rules verdict changes explicitly out of scope ("Re-deciding a TRIAGE verdict is a separate judgment call and is deliberately not proposed here"). Filed unassigned, not graded.

Measured on a6b6e54a26 (merge base) / 4d44af2580 (the #12289 branch head), driving the real hintCovers and collapseHint imported from scripts/pm/dispatch-gates.mjs — not a re-implementation.

What changed under these rows

#12300 (783111d252, "match a hint whose glob sits in a non-final segment") did two things. The one its commit body leads with is small: it deleted a dead second trailing strip from collapseHint. The one that matters here is the other:

export function hintCovers(hint, inputPath) {
  if (globInNonFinalSegment(hint)) return triggerCovers(hint, inputPath);   // ← added by #12300
  const plain = collapseHint(hint);
  

collapseHint itself is unchanged — it still returns packages//src for packages/**/src/**. What changed is that a glob in a non-final segment no longer goes through it. That distinction is the trap: probing collapseHint alone still reproduces every double slash these rows cite, and still reads as confirmation, while the reachability claim built on it has been false since #12300 landed.

The four rows

Each refuses on some form of "the narrow spelling collapses to a malformed double separator, so it would be a live hint covering nothing". Measured today:

row its narrow spelling covers the row's own population precision
check:skill-refs SKILLS_DIR skills skills/*/references/** 12 12 of 50 100%
check:objectql-double-limit SCAN_ROOT packages packages/**/*.test.ts 2733 every *.test.ts under the root (2733 tracked) 100%
check:i18n PACKAGES_DIR packages packages/**/i18n-extract.config.ts 9 the 9 extract configs 100%
check:i18n-stale-fill PACKAGES_DIR packages packages/**/i18n-extract.config.ts 9 the same 9 100%

All four now have an exactly precise spelling available. The 12 that skills/*/references/** reaches are the row's own 12, nine _index.md plus data-hooks.md, plugin-hooks.md, react-blocks.md. The 9 are the nine scripts/i18n-extract.config.ts files by name.

So the prose is not the only casualty. REFUSE-UNSPELLABLE is defined in that file as "the population is a file-KIND or FILENAME filter inside the root. The subtree idiom can only say 'all of it', at the precision quoted" — and for these four the idiom can now say exactly it. The verdict no longer describes the tree, which is why this is filed rather than repaired under #12289: rewriting the why would either misstate the measurement or leave a rationale arguing against its own verdict.

⭐ Note the fifth row, check:runner-env-posture SCANNED_ROOTS packages (the substantive half of #12289): its verdict does survive, and it is the useful contrast. Its narrow spelling packages/**/src/** is live too and reaches all 1812 population files — but it covers 4291 to do it, 2466 of them the test files the gate skips. 42% where the bare root is 35%. There the unspellable thing is a file-KIND filter that no glob expresses; for the four above, the filter is a filename or a directory the glob names directly. That row is repaired in the #12289 PR; these four are not.

Why the verdicts are a real question, not bookkeeping

REFUSE-UNSPELLABLE and "a precise declaration exists" carry opposite prescriptions, which is the same objection #12289 raises about its own row 1. Two open findings are currently blocked on exactly the remedy this unblocks:

Both were filed before #12300 landed, or without driving the post-#12300 hintCovers.

Not asserted

No replacement verdict is proposed. The vocabulary has three values (DECLARED-NARROWER, REFUSE-WIDE, REFUSE-UNSPELLABLE) and DECLARED-NARROWER reads as "already declared elsewhere", which none of these four are — so this may need a fourth value, or a declaration at each gate, or a judgement that a live-but-unnamed spelling is still not worth declaring. That choice is the maintainer's. ⇒ now #12369.

Note also that declaring the spelling does not on its own clear the row from the sweep: covered() probes hintCovers(h, '/probe.file'), which is false for all four spellings. What the declaration buys is the gate being named for a card that touches the real files, which is what #12310 and #12322 are about.

Repro

node -e "
import('./scripts/pm/dispatch-gates.mjs').then(({hintCovers, collapseHint, trackedFiles}) => {
  const f = trackedFiles();
  for (const h of ['skills/*/references/**','packages/**/*.test.ts','packages/**/i18n-extract.config.ts']) {
    console.log(h, '-> collapse', collapseHint(h), '| covers', f.filter(x => hintCovers(h, x)).length);
  }
});
"

Refs: #12369 (the vocabulary decision this is blocked on) · #12289 (the card that found the first two rows; its row 1 is repaired, its row 2 is one of the four above) · #12300 (the change that retired the mechanism) · #12246 (the defect #12300 closed) · #12310 · #12322

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions