Repository navigation
Description
Filed unassigned and ungraded, observation-class, severity not judged. Found while working #12529 (an unrelated comment repair in packages/cli), so it is filed on its own card rather than folded into that PR.
Measured
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, run on 52a982388, prints an Unreachable section headed:
9 where THE LAYOUT MOVED under a gate that still spells the old path — a real miss, worth triaging
with entries such as:
- pnpm --filter @objectstack/spec run check:spec-changes [lint.yml]
dead: 'packages/spec/src/kernel/protocol-version' — the tree stops at
packages/spec/src/kernel; the layout moved under it · …
The layout did not move. Those literals are extensionless module specifiers, and the files are tracked — checked with git ls-files "$p" "$p.ts" "$p.mts" "$p.mjs" "$p.js" "$p.tsx" for each:
| literal reported dead | actually tracked as |
|---|---|
packages/spec/scripts/lib/dist-freshness |
…/dist-freshness.ts |
packages/spec/scripts/lib/sharded-artifacts |
…/sharded-artifacts.ts |
packages/spec/scripts/lib/export-origins-layout |
…/export-origins-layout.ts |
packages/spec/scripts/lib/strictness-ledger |
…/strictness-ledger.ts |
packages/spec/scripts/lib/strictness-ledger-doc |
…/strictness-ledger-doc.ts |
packages/spec/src/kernel/metadata-plugin.zod |
…/metadata-plugin.zod.ts |
packages/spec/src/kernel/protocol-version |
…/protocol-version.ts |
packages/spec/src/migrations/registry |
…/registry.ts |
packages/spec/src/migrations/spec-changes |
…/spec-changes.ts |
packages/spec/src/conversions/registry |
…/registry.ts |
packages/spec/src/meta-spelling/manifest-collection-spelling |
…/manifest-collection-spelling.ts |
packages/spec/src/meta-spelling/metadata-url-spelling |
…/metadata-url-spelling.ts |
12 of the 14 literals in that section resolve to a tracked .ts file. The two that genuinely do not resolve are not "moved layout" either: packages/spec/scripts/dist/other.d.ts is build output and packages/node_modules/typescript/bin/tsc is an installed binary.
Demonstrated in one run
Passing one of those very files to the script makes both halves visible at once:
$ node scripts/pm/dispatch-gates.mjs --residue packages/spec/src/migrations/registry.ts
- …check:spec-changes [lint.yml] names: packages/spec/src/kernel/protocol-version,
packages/spec/src/migrations/registry, packages/spec/src/migrations/spec-changes, …
- …check:spec-changes [lint.yml] dead: 'packages/spec/src/migrations/registry'
— the tree stops at packages/spec/src/migrations; the layout moved under it · …
The family names the path, the path exists, and the same run still classifies it dead.
Two consequences, and the second is the expensive one
-
It manufactures triage work. The heading calls it "a real miss, worth triaging", so a reader is sent after nine defects that do not exist.
-
⭐ In the opposite direction, and worse: because the literals are classified unreachable, the nine families declaring them can never be matched to a change set. A dev editing
packages/spec/src/migrations/registry.tsdoes not getcheck:spec-changesin their derived local gate list — it lands in the unreachable bucket instead of the matched one. By the script's own words an unreachable family "score[s] the same quiet green for every card in the tree", which is precisely the outcome a local-gate derivation exists to prevent. The under-derivation is silent and the script exits 0.
Families affected
All packages/spec, all in lint.yml except the last, which is in spec-liveness-check.yml: check:api-surface, check:dual-source-exports, check:entry-nameability, check:export-origins, check:exported-any, check:meta-url-spelling, check:spec-changes, check:upgrade-guide, check:strictness-ledger.
Direction, not a decision
The path matcher probably needs to try the module-resolution extensions when a literal carries none, before concluding a prefix is dead. ⛔ Unverified — the matcher itself was not read, only its output.
Dedup
Semantic issue search for this returned zero. That zero was reverse-checked with a query in the same instrument that does return results (#12529 and #11958), so it is a real zero rather than a broken search.
Generated by Claude Code
Activity
hintCoversreads an extensionless module specifier as a filesystem path, so 9packages/specgate families can never be MATCHED to a change set — silent under-derivation on every dispatch #12514