Skip to content

finding: dispatch-gates.mjs never names check:cross-package-test-inputs for an edited test file — it shipped a real red invisible to local derivation #11199

Description

@os-elon

Observed live on PR #11191 (packages/create-objectstack/src/starter-comments-self-contained.test.ts, three prose comments naming another gate in backticks). node scripts/pm/dispatch-gates.mjs (no paths — merge-base derived) reported a full gate union, all green, and none of it was check:cross-package-test-inputs. CI's Lint & Repo Gates job then failed on exactly that gate:

scripts/check-published-readme-links.mjs (named in packages/create-objectstack/src/starter-comments-self-contained.test.ts)
Widen the package's globs to cover them.

grep -i cross-package-test-inputs over a fresh dispatch-gates.mjs run (no args) for that diff produces zero lines — the gate is absent from the matched list, the convention-triggered list, and the unreachable-by-construction list. It only surfaces under --residue, in the silent/undetermined bucket, which the tool's own text says is "not known irrelevant" but reads, in practice, as safe to skip.

Root cause

check-cross-package-test-inputs.mjs's population is not a path set. Two independent things make a test file matter to it:

  1. a real escaping read/import (an actual cross-package dependency), or
  2. a prose mention — its flat literal collector (repoRelativeLiterals) matches ANY backtick/quote-wrapped (packages|apps|examples|content|scripts|skills)/... string anywhere in the file's text, comments included, with no parsing.

Both are properties of a test file's content, not of which package owns it — the same shape #9955 documented for check:test-source-alias ("the trigger is a NEW cross-package import inside a test, which no path literal describes"). #9955 was fixed by PR #10540 declaring workspace-parent globs, but that fix was for a gate whose declared population is expressible as parent globs once every workspace member is listed. check-cross-package-test-inputs has no such fix available: a package with zero prior entries in its per-package ledger (like create-objectstack before this PR) contributes nothing for the tool to widen — there is no existing glob to have named it, because the trigger is "any test file's content changed," full stop.

dispatch-gates.mjs already has exactly this shape of trigger modeled — the 'adds or edits a test file' convention-trigger kind (CHANGE_KIND_GATES[0], scripts/pm/dispatch-gates.mjs:2157) — and it already carries five gates for the same reason (check:query-options-erasure, check:type-check-coverage, check:type-check-debt, check:engine-double-contract, check:where-matcher), each because it "walks every *.test.* file" or "*.test.ts file" for something a path literal cannot describe. check-cross-package-test-inputs is the same kind of whole-corpus, content-driven scan, runs in the same CI job (lint.yml's lint job, "Lint & Repo Gates"), and is conspicuously absent from that list with no rationale in the source excluding it — it appears to simply have been missed when the convention-trigger list was built.

Why this matters

This is not a false-positive-tolerance question — the gate itself was correct (my test file's comments genuinely did read as an undeclared escape to its literal collector). The gap is that a dev following the standard dispatch-gates.mjs + reported-green workflow has no local signal at all that this gate exists to fail, for any PR that merely edits or adds a test file anywhere in the repo — which is a very large fraction of PRs. The existing five-gate convention list exists precisely to cover this class of blind spot for its siblings; this gate rides the identical trigger and sits just outside it.

Suggested fix, not asserted as the only one

Add check:cross-package-test-inputs as a sixth entry under CHANGE_KIND_GATES[0] ('adds or edits a test file'), alongside its five current siblings — cheap (one more entry, no new derivation machinery) and consistent with how the other whole-corpus test-content scanners in the same CI job are already handled. Not measured here: whether any other currently-unlisted gate in lint.yml shares this same "scans every test file's content" shape and is missing from the same list for the same reason — worth a companion sweep if this fix lands.

Filed while working #10990/#11022 (PR #11191); not fixed there because widening dispatch-gates.mjs is unrelated to that PR's own scope.

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