Observed 2026-08-27 while implementing #12514 (PR #12794), on origin/main @ ead731756 plus that PR's change. Filed unassigned, recording only. ⛔ Not fixed in #12794 — out of that card's scope, which is the matcher.
What changed under this branch
unreachableReason checks target FIRST, and it is the strongest sentence the residue can print:
if (target) {
return `'${hint}' — the tree HAS ${target}; the literal is that file's
extensionless module spelling, which no whole-segment comparison reaches`;
}
That was true when it was written: hintCovers could not reach a dropped extension, so "no whole-segment comparison reaches" was a statement about the rule. #12514 taught hintCovers to follow a dropped extension, so a hint that carries a path separator and names a real file is now MATCHED and never enters dead at all.
The residue path that survives, and prints the wrong cause
One population still reaches the target branch: a hint the matcher refuses for a different reason — the bare-single-segment rule (if (!hint.includes('/') && !plain.startsWith('.')) return false). For a hint spelled conversions with a tracked root file conversions.ts:
extensionlessModuleTarget('conversions', files, prefixes) returns conversions.ts (conversions is not a tracked prefix, so its up-front guard does not fire);hintCovers refuses it for being a bare word, not for the extension;- the reader is told the whole-segment comparison cannot reach it, which is now false — a separator is what it lacks, and the "too generic" branch below is the sentence that names the real escape (declare the subtree spelling).
Same species as #12299 and #12568: a residue row whose classification and whose evidence are both wrong, about a file that is sitting right there. Those two were the reason the branch exists; this is the branch drifting back into the same failure through a different door.
Reachability today: LATENT, measured not assumed
Zero on this tree. It needs a bare separator-less hint whose plain + ext is a tracked repo-root file. Measured over the live fleet at ead731756: no dead bare hint (conversions, migrations, and the rest) has a root-level module sibling. So this is a latent wrong sentence, not a live one — which is exactly the state the two closed cards above were in before a layout change made them live.
Why the #12794 pin does not cover it
That PR adds a coherence case asserting no hint that carries a separator is both dead to the matcher and extensionless-resolvable. The filter is deliberate and stated: for a separator-carrying hint the disjointness is structural, and for a bare one it is not. So the class is named there and left open here rather than pinned green by a case that quietly excludes it.
⛔ Not proposing a shape
Whether the right repair is to order the bare-word branch ahead of target, to teach the target sentence which refusal actually fired, or to decide the branch is now residue that should be retired, is triage — and it sits on scripts/pm/dispatch-gates.mjs, which has a serial queue on it (#12470, #12411, #12410, #12500, #12749). Whoever holds that file next is the cheapest place for it.
Dedup: one targeted search of the board for dispatch-gates residue/reason cards found #12299 and #12568 (both closed, both the other direction) and no open card naming this branch.
Generated by Claude Code
Observed 2026-08-27 while implementing #12514 (PR #12794), on
origin/main@ead731756plus that PR's change. Filed unassigned, recording only. ⛔ Not fixed in #12794 — out of that card's scope, which is the matcher.What changed under this branch
unreachableReasoncheckstargetFIRST, and it is the strongest sentence the residue can print:That was true when it was written:
hintCoverscould not reach a dropped extension, so "no whole-segment comparison reaches" was a statement about the rule. #12514 taughthintCoversto follow a dropped extension, so a hint that carries a path separator and names a real file is now MATCHED and never entersdeadat all.The residue path that survives, and prints the wrong cause
One population still reaches the
targetbranch: a hint the matcher refuses for a different reason — the bare-single-segment rule (if (!hint.includes('/') && !plain.startsWith('.')) return false). For a hint spelledconversionswith a tracked root fileconversions.ts:extensionlessModuleTarget('conversions', files, prefixes)returnsconversions.ts(conversionsis not a tracked prefix, so its up-front guard does not fire);hintCoversrefuses it for being a bare word, not for the extension;Same species as #12299 and #12568: a residue row whose classification and whose evidence are both wrong, about a file that is sitting right there. Those two were the reason the branch exists; this is the branch drifting back into the same failure through a different door.
Reachability today: LATENT, measured not assumed
Zero on this tree. It needs a bare separator-less hint whose
plain + extis a tracked repo-root file. Measured over the live fleet atead731756: no dead bare hint (conversions,migrations, and the rest) has a root-level module sibling. So this is a latent wrong sentence, not a live one — which is exactly the state the two closed cards above were in before a layout change made them live.Why the #12794 pin does not cover it
That PR adds a coherence case asserting no hint that carries a separator is both dead to the matcher and extensionless-resolvable. The filter is deliberate and stated: for a separator-carrying hint the disjointness is structural, and for a bare one it is not. So the class is named there and left open here rather than pinned green by a case that quietly excludes it.
⛔ Not proposing a shape
Whether the right repair is to order the bare-word branch ahead of
target, to teach thetargetsentence which refusal actually fired, or to decide the branch is now residue that should be retired, is triage — and it sits onscripts/pm/dispatch-gates.mjs, which has a serial queue on it (#12470, #12411, #12410, #12500, #12749). Whoever holds that file next is the cheapest place for it.Dedup: one targeted search of the board for dispatch-gates residue/reason cards found #12299 and #12568 (both closed, both the other direction) and no open card naming this branch.
Generated by Claude Code