Skip to content

[finding] dispatch-gates does not derive check:pm-expected-skips for a SKILL.md change, though that self-test pins a literal in SKILL.md — a SKILL.md PR passed 19 derived gates and went red on the 20th in CI #18673

Description

@os-justin

Filed by the domain:skills execution seat (session_01Gqi43smmqjJ5sUrhfoPeKu, seat post #7623) out of the #18454 round (PR #18666), first-hand. ⛔ Filed bare: finding only, domain:* / type / priority are triage's.

Dedupe words: check-expected-skips structural pin · enqueue bar names this file · dispatch-gates derivation SKILL.md · self-test reads SKILL.md · derived gate list missed.

The reading, on origin/main c049e7467

scripts/pm/check-expected-skips.mjs :1069 carries a structural self-test case: 「the SKILL.md enqueue bar names this file」 — readFileSync('.claude/skills/pm-dispatch/SKILL.md').includes('check-expected-skips.mjs'). CI runs it as pnpm check:pm-expected-skips (.github/workflows/lint.yml :1378, inside Lint & Repo Gates).

PR #18666 (#18454) re-keyed SKILL.md :628 and dropped the .mjs from the citation. The dev derived its gate list the prescribed way — node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack from the worktree, change set taken from the merge base — and got 19 families, ran all 19, all exit 0, reconciled with --ran (「0 NOT-MEASURED」). pnpm check:pm-expected-skips was not among them. CI then failed at step 53 of Lint & Repo Gates on exactly that case (job 105220877730 on 7e78dc6ad: 「✗ structural: the SKILL.md enqueue bar names this file (got false, want true)」, 1 of 99), and 126 later gates never ran.

⇒ A gate whose self-test READS a file is not derived for a change to that file. The derivation reasons from declared populations (dispatch-gates: markers, path hints); check-expected-skips.mjs carries no marker naming SKILL.md (seat's grep: 0 dispatch-gates: lines in the file), so its reading of SKILL.md is invisible to the derivation, and a SKILL.md PR is handed a clean 19/19 that CI contradicts.

Why it is worth a card and not a note

The seat's dispatch template tells every dev 「门禁清单取 dispatch-gates --commands 逐条跑 … --ran 对账」 and the dev did exactly that; the seat's own in-seat review ran the ratchet, the frame sync, the id-lint and the pair check on the head and also did not run this self-test. Two readers, one prescribed instrument, one gate outside it. This is the same shape as #8410 (closed: derivation for .changeset/ paths), one file further along: a structural pin that reads a governed file is a population claim on that file, and nothing declares it.

Shape (⛔ a proposal, not a prescription)

Either check-expected-skips.mjs declares the file it reads (a population / hint the derivation already understands — e.g. a dispatch-gates: marker naming .claude/skills/pm-dispatch/SKILL.md, if the marker grammar admits a non-gate read), or the derivation learns to surface every scripts/pm/*.mjs --self-test whose source names a path in the change set. The seat's dispatch template gains 「plus pnpm check:pm-expected-skips for any SKILL.md change」 only as a stopgap; the fix belongs in the derivation or the declaration.

⛔ Not measured

  • How many other scripts/** self-tests read a file under .claude/** or AGENTS.md by literal and carry no marker for it (a census would say whether this is one gate or a class).
  • Whether --ran could have caught it: it reconciles the DERIVED list, so a family outside the list is invisible to it by construction.

Refs: #18454 · PR #18666 (the red) · #8410 (the .changeset/ derivation gap, closed) · #18422 / PR #18660 (the population markers' wholeness, landing)

domain:skills execution seat · seat post #7623 · readings taken on origin/main c049e7467


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

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions