Skip to content

finding: an AGENTS.md-only card derives ZERO gates — check:pm-skill-ratchet is locally undiscoverable for the file carrying its largest ceiling #9964

Description

@os-warren

Filed unassigned while implementing #9923 (ratchet header boundary honesty). Out of that card's scope: that card's file surface is exactly scripts/pm/check-skill-line-ratchet.mjs, and this is a property of scripts/pm/dispatch-gates.mjs derivation.

Measured

On origin/main at merge base 5989b0de9:

node scripts/pm/dispatch-gates.mjs AGENTS.md
-> "No check family names the given paths in its own source, and no workflow's
path filter schedules one for them."
-> 0 matched · 35 undetermined · 79 silent
-> grep -c pm-skill-ratchet == 0

Zero gates derived for a card whose surface is AGENTS.md.

Mechanism

extractWatchHints requires a hint to look pathy: it must contain a slash, or start with a known dotted dir. AGENTS.md is a top-level file with neither, so the ratchet's own CEILINGS key for it is dropped at extraction. Measured hint set for check-skill-line-ratchet.mjs: 17 hints for 18 ceiling entries — every .claude/ key survives, AGENTS.md is the one that does not.

This is the documented top-level-FILE class that dispatch-gates' own residue text already describes ("a literal with no path separator is refused as too generic, so the gate reads your file while naming nothing that can match it"). What seems worth a card is the specific consequence rather than the class: AGENTS.md carries the largest ceiling in the ratchet (958 lines, headroom 0), and it is precisely the file whose growth the ratchet was extended to stop. A dev dispatched on an AGENTS.md compression card gets a derived gate list of nothing at all.

Severity is bounded — this is discoverability, not enforcement

check:pm-skill-ratchet sits in lint.yml, which declares no pull_request path filter, so CI runs it on every PR regardless. Nothing can land over the ceiling. What is lost is the local brief: the dev is not told to run it, and at headroom 0 an AGENTS.md edit that adds a single line goes red in CI having derived no local signal.

Options, not a recommendation

  1. Leave it — CI covers enforcement, and widening the extractor to accept bare top-level literals was already measured and REFUSED (it takes watch-hint pairs from 19,024 to 158,108).
  2. A narrow allowance for a top-level literal that ends in a known instruction-file extension and names a real tracked file, which is a much smaller opening than the refused general case.
  3. Nothing in the extractor; instead have the ratchet declare its population with a glob the extractor already accepts as written.

Option 2 or 3 would need measuring against the same corpus the refusal used before anyone acts on it.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions