Skip to content

dispatch-gates and check-self-test-wired both anchor gate invocations on scripts/, so lint.yml's package-local check-reference-carrier-shape gate is invisible to one and mis-keyed by the other #15342

Description

@claude

Filed unassigned by the #15312 dev seat (session session_012zGPuVVX3deAx9LdjK8jCk), surfaced by that card's residue measurement.

The specimen

lint.yml runs one gate that does not live under the repo-root scripts/ directory:

node packages/lint/scripts/check-reference-carrier-shape.mjs --self-test
node packages/lint/scripts/check-reference-carrier-shape.mjs

It is the only such invocation in the whole workflow corpus today (grep -oE "node packages/[A-Za-z0-9_./-]+\.mjs" .github/workflows/*.yml returns exactly these). Two independent tools mis-handle it, both for the same reason, and neither says anything about it.

Tool 1 — scripts/pm/dispatch-gates.mjs never discovers it

const DIRECT_CHECK_INVOCATION =
  /node[ \t]+(scripts\/[\w./-]*check-[\w.-]+\.mjs)([^\n;|&<>()]*)/g;

Anchored on scripts/, so the invocation matches nothing. The family is not undetermined, not silent, not in the artifact-roster block and not in the residue listing — it is absent from the derivation entirely, so --residue cannot report it either. Confirmed live: discoverFamilies() yields no key containing reference-carrier.

This is a strictly worse shape than #15312's, which the tool at least listed as undetermined where a seat reading --residue could see it. Here there is nothing to read and decline.

Tool 2 — scripts/check-self-test-wired.mjs keys it to a path that does not exist

const INVOCATION_RE =
  /(scripts\/[A-Za-z0-9_.\-/]+\.(?:mjs|mts|js|sh))(\s+--self-test(?[\w-]))?/g;

The same anchor, matching as a SUBSTRING, so collectInvocations records the gate under scripts/check-reference-carrier-shape.mjs — a path with no file behind it. That key then flows into auditPopulation and auditLedger, whose whole job is deciding whether a script CI runs has its self-test run. A gate keyed to a nonexistent path is audited as a different script than the one CI executes, and the failure is silent in both directions: the real file is never audited, and the phantom key can never be reconciled against a carrier.

Why it matters beyond one gate

The repo has a documented package-local gate lane (packages/lint/scripts/), so this is not a one-off typo — it is a shape both derivations refuse to see. Today it costs one gate. The cost is a gate CI runs that no seat can be told about, which is precisely the defect #15312 was filed on, arriving through a different door.

Remedy sketch (not a decision — the shape is a judgement for the owning lane)

Widen both anchors from scripts/ to any tracked path ending in a gate-shaped .mjs, or introduce an explicit second root for the package-local lane. Both tools already resolve check:* npm scripts to files, so the widening has to keep the direct-invocation and script-resolution answers from disagreeing. Whichever shape is chosen, it wants a self-test case pinning packages/lint/scripts/check-reference-carrier-shape.mjs by name, since it is the tree's only live specimen and a widening measured on zero specimens is not measured.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions