Skip to content

The clause-② enqueue gate keys on PATHS, so a content-only clause-② card walks straight through it — a live instance exists on the day the gate landed (PR #9191) #9211

Description

@os-zhuang

Filed by the domain:metadata execution seat (#6367), PM session session_01NTKPDRoynY8i3HmdSFUxFj. ⚠️Filed by the seat the gate exists to catch — both of this seat's clause-② breaches today are the motivating incidents, so read the disposition suggestions with that interest in mind.

The gap

PR #9197 (merged 2026-08-17T01:37Z) landed the clause-② enqueue gate. Item 1:

contract surface (packages/spec/src/**, error-code ledger, *.zod.ts contract schemas) touched AND dispatch tier below the contract-review tier ⇒ enqueue forbidden.

The trigger is touched — a path predicate. But clause ② has two limbs, and #9197's own --tier output says so:

Clause ② is NOT reachable from paths: a card that changes contract accept/reject behaviour or widens the public surface is fable-mandatory too, judged from the card CONTENT.

⇒ A card that flips accept/reject without touching the contract surface satisfies clause ② and fails to satisfy the enqueue gate's trigger. It enqueues.

The live instance, found the same day

PR #9191 (card #9157) changes three GET routes from accepting a plural spelling (200 + empty body) to refusing it (400).

clause ② by contentyes — accept/reject behaviour, first limb
dispatch tieropus, below the contract-review tier
files touchedpackages/metadata-protocol/src/protocol.ts, one new test, one changeset
packages/spec/src/** / *.zod.ts / ledgernone
⇒ enqueue gate fires?NO

It is held only because the dispatching seat had already self-reported the breach and applied needs:contract-review by hand, on the broad reading. ⭐ A seat that had not self-reported would have hit no obstacle whatsoever — CI green, diff clean of the declared globs, gate silent.

The sibling PR #9173 (card #9111) does trip the gate, because it adds a ledger row. Same clause, same breach, same seat, same day — one caught by paths, one invisible to them.

Why the current wording does not close it

#9197 states the path line is "a FLOOR, never a clearance." That governs the tier hint. The enqueue gate is written as a conjunction whose first term is a path predicate, so on a content-only card the conjunction is simply false — there is no clearance being read, just a rule that does not reach.

⚠️ This is the same shape as the three list-derivation findings this shift (#9171, #9182, #9192): a path- or dependency-derived predicate consumed as if it covered the semantic question. The difference, and the reason this one is worse: those cost a missed gate run or a stale docs list. This one is the enforcement mechanism for a maintainer ruling, and its miss is silent by construction.

What a disposition has to decide

  1. Widen the trigger to the tier, not the path — if the card was judged clause ② (however that judgement is recorded), the gate fires regardless of paths. Needs a durable record of the judgement, which today exists only in the claim comment's Container & model line.
  2. Make the dispatching seat declare — every claim comment states clause-② yes/no explicitly; a yes binds the enqueue gate. Cheap, but it relies on the same judgement that failed twice today.
  3. Widen the globs — cannot work: a route's accept face lives in handler code, not in a declarable file set. This is offered only to be ruled out.
  4. Accept the gap and say so in SKILL.md — the gate catches the common landing zone, and content-only cards remain the seat's honesty. Honest, and it stops the gate being read as complete.

⛔ No recommendation. Options 1 and 2 both rest on a judgement this seat demonstrably got wrong twice in one shift; I am not the right party to argue which is sturdier.

Also, an operational defect I caused

The needs:contract-reviewlabel object did not exist (#9197 anticipated this: "the live label object is not yet created"). Applying it to a PR created it implicitly with GitHub's default ededed and an empty description, instead of d93f0b and the description at scripts/pm/ensure-pm-labels.sh:49.

⚠️ That script uses gh label create … || true, which fails silently on an already-existing label — so a later run will not repair it. A grey label in the strip where a red one was specified is exactly the kind of thing nobody notices; fixing it needs an explicit label edit, not a re-run.

Not claimed

Backlinks: PR #9197 / #9185 (the gate) · PR #9191 / #9157 (the live instance) · PR #9173 / #9111 (the sibling the gate does catch) · #9171 · #9182 · #9192 (same derived-predicate class).

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions