Skip to content

[finding] dispatch-gates never routes a .d.mts change set to check:declaration-mirrors — its corpus is discovered by extension, no path literal, so a drifted mirror only reds in CI #15553

Description

@claude

Filed by the PM seat domain:devx @ objectstack (#6023), session session_012zGPuVVX3deAx9LdjK8jCk, from a measured CI red on PR #15532 (#15487). Filed finding, domain:devx; priority stated with its reason (one rework cycle already paid) so triage can overrule.

What happened

PR #15532 edited scripts/js-comment-mask.d.mts (a hand-written declaration mirror) and ran the derived family for its change set — 32 commands, all green. CI then went red on check:declaration-mirrors (scripts/check-declaration-mirrors.mjs, lint.yml step "Hand-written declaration mirrors", run 33914061581):

FAIL: a hand-written declaration disagrees with the module it mirrors.
  - scripts/js-comment-mask.d.mts:106 declares `makeRegexRecogniser` with 1 required parameter(s), but scripts/js-comment-mask.mjs implements 0.

The gate is right (Function.length vs a required declared parameter). The derivation could not have named it.

The gap, measured

check-declaration-mirrors.mjs declares its population as DISCOVERED: "every scripts/**/*.d.mts is checked … Discovered, never listed" (:47, :136), walking by extension with no path literal. dispatch-gates.mjs derives families from declared path literals, so a change set consisting of a .d.mts (or the .mjs it mirrors) never routes to this gate. Measured on main 85a245988+:

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack -- scripts/js-comment-mask.d.mts scripts/js-comment-mask.mjs
→ 0 lines mentioning declaration-mirrors   (20 other commands derived)

So the exact class of change this gate exists for — a .d.mts moving out of step with its module — is the class the derivation never sends to it; the red arrives in CI, a cycle late, on every card that touches a mirror. #15532 is the specimen; #15534 / #15398 (both queued, both edit this same .d.mts) would pay it next.

What a fix owes (direction, not prescription)

Declare the gate's population so a .d.mts (and its sibling .mjs) change set derives it — a ROOT_DIR_WATCH_HINTS-shaped declaration naming scripts/** restricted by extension if the hint vocabulary can spell an extension (check hintCovers and check:watch-hint-literal's roster; if the vocabulary is directory-only, the scripts/** hint routes every scripts/ card to a ~1 s gate, which is the false-positive cost to measure and state). ⛔ Not a hand list of mirrors (the corpus is discovered on purpose); ⛔ no self-test edited to pass.

Related: #15501 (the same shape on check:merge-driver, PR #15538 — the fix pattern), #15414 / #15509 (same shape on the self-test gates), #14918.


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