Skip to content

[finding] scripts/pm/git-history.mjs's --self-test runs nowhere in CI — the sixth instance of a class fixed five times one at a time #10196

Description

@os-zhuang

Found while wiring scripts/pm/ci-failure.mjs's --self-test into Lint & Repo Gates for #9898 (PR #10195). Not fixed there — that card's declared file surface is .github/workflows/lint.yml and this is a different tool. Filed unassigned.

The observation

scripts/pm/git-history.mjs ships a --self-test (dispatch at :306, reporter at :503, documented in its own usage block at :13) and nothing runs it: no workflow names it, and root package.json carries no alias for it.

Derived at origin/main by resolving pnpm check:* aliases rather than grepping workflows for filenames — the naive filename scan is wrong here, because most PM tools reach CI through an alias and their filename never appears in any workflow:

toolself-test in CI
check-governed-merges.mjsyes (pnpm check:pm-governed-merges)
check-governed-prose.mjsyes (pnpm check:pm-governed-prose)
check-half-states.mjsyes (pnpm check:pm-half-states)
check-label-desc-cap.mjsyes (pnpm check:pm-label-desc-cap)
check-skill-id-lint.mjsyes (pnpm check:pm-skill-id-lint)
check-skill-line-ratchet.mjsyes (pnpm check:pm-skill-ratchet)
os-verify-lock.shyes (direct)
release-rehearsal-clone.mjsyes (direct)
ci-failure.mjsno → PR #10195
git-history.mjsno ← this card

(dispatch-gates.mjs is covered indirectly: pnpm check:pm-dispatch-gates runs the dedicated check-dispatch-gates.mjs gate, whose header argues why it is a separate file.)

Why this is worth a card rather than a shrug

This exact class has now been closed five separate times, one instance at a time: #8110, #8170, #8162, #8528, #9348 — and #9898 is the sixth. Every one was found by a human or an agent noticing, never by a gate. The rot is quiet by construction: a self-test nobody runs stays green in the only sense that matters (nobody looks), and the tool it guards is typically reached for mid-round, under time pressure, by someone who needs it to work right then.

git-history.mjs also sits in the blast radius of #9902 (seat tools asking windowed history questions with no shallow guard), which makes an unrun self-test on it worth more than average.

Suggested shape — close the class, not the instance

Rather than a seventh manual wiring, a gate that asserts every scripts/pm/** tool shipping a --self-test is reachable from some workflow (directly or through a package.json alias), with an explicit, reasoned opt-out list for anything deliberately excluded. The alias-resolution above is the whole detector; it is ~20 lines and it already exists in prose in several step comments in lint.yml.

That converts "somebody notices the seventh instance" into "the seventh instance cannot merge unwired", which is the same trade every step in the Lint & Repo Gates self-test family already accepts.

⚠️ Worth measuring before building: whether the runtime of git-history.mjs --self-test is CI-affordable, and whether it needs network. Neither was measured here — only its wiring was.

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions