Skip to content

dispatch-gates.mjs calls extensionless module specifiers dead paths — 12 tracked packages/spec files are reported as "the layout moved", and the 9 gate families naming them can never match a change set #12568

Description

@os-litant

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 deadactually 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

  1. 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.

  2. ⭐ 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.ts does not get check:spec-changes in 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions