Skip to content

feat(pm): clause-2 enqueue gate and needs:contract-review re-review chain - #9197

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-9185-clause2-queue-gate
Aug 17, 2026
Merged

feat(pm): clause-2 enqueue gate and needs:contract-review re-review chain#9197
os-zhuang merged 1 commit into
mainfrom
claude/issue-9185-clause2-queue-gate

Conversation

@os-zhuang

@os-zhuangos-zhuang commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Fixes#9185

ADR-class (skills update — human merge only): this PR stays a draft awaiting the maintainer; never ready/enqueue/auto-merge.

What landed

.claude/skills/pm-dispatch/SKILL.md — rule package items 1–5, as two new bullets at the head of the 入队与落地 principle list plus a zero-line-cost pointer inside the 模型分档 clause-② sentence:

  1. Enqueue gate: before ready/enqueue, read the PR's actual diff; contract surface (packages/spec/src/**, error-code ledger, *.zod.ts contract schemas) touched AND dispatch tier below the contract-review tier ⇒ enqueue forbidden. Dispatching seat's duty ends at: one-line finding on the card, apply needs:contract-review, stop — no self-review clearance.
  2. Reviewer double condition: runs at the contract-review tier AND is not the card's dispatching seat.
  3. Review ownership: standing = triage seat (Routine model pinned by the maintainer in the Routines UI); new triage sub-round clears the label (reviews the contract-delta diff only, one-line conclusion on the card, label cleared before enqueue; hourly rounds batch naturally); transition period covered by the skills seat.
  4. Downgrade fuse: sub-round opens with a model self-check; not at the contract-review tier ⇒ whole sub-round skipped, labels left in place. Waiting outside the queue is the safe state; the quota exemption does not apply to the review.
  5. Single source for the tier: label needs:contract-review names what is reviewed (no model name anywhere in label or prose); the tier lives only in the CONTRACT_REVIEW_TIER constant.

scripts/pm/dispatch-gates.mjs — rule package item 6: CONTRACT_REVIEW_TIER = 'claude-fable-5' (single source), SUSPECT_TIER_GLOBS (packages/spec/src/**), and a --tier suspicion line on a hit — explicitly a hint, not a verdict. Self-test extended three ways (hit / no hit / wording), 219 → 234 cases; every pre-existing case still green.

Line budget (ratchet ceilings, 0 headroom before)

  • SKILL.md: 682 → 681 (ceiling 682). The +6 new lines are funded by 7 same-file merges of paragraph-trailing wrapped continuation lines into their predecessors — pure re-wrap, zero characters of prose added or removed, no semantics lost, no existing ⛔ line deleted. Ceiling untouched.
  • references/dispatch-runbook.md: left untouched (optional per the card). It sits at 223/223 with 0 headroom; a new section would cost 3–4 lines against a full ceiling, and the SKILL.md gate bullet already carries the complete operating sequence, so a runbook duplicate would add a sync burden for no reader.

Beyond the two named files (each necessary for the rule package, none a semantic change elsewhere)

  • scripts/pm/check-dispatch-gates.mjs: refreshed one header measurement note that this change made stale ("the spec filter path no longer matches at all" → it now matches via the declared suspect glob, pinned as deliberate in the tool's self-test). Comment-only.
  • scripts/pm/ensure-pm-labels.sh: seeded the needs:contract-review label (main repo only — the contract surface lives here). The SKILL.md state machine requires the label object to exist before a seat can apply it, and this script is the repo's one label-vocabulary mechanism. The live label object is not yet created; the first bash scripts/pm/ensure-pm-labels.sh run creates it.

Verification (all at final commit ad089549c)

  • pnpm check:pm-skill-ratchet — PASS (SKILL.md 681/682; all seven covered files under ceiling)
  • pnpm check:pm-skill-id-lint — PASS (9 files clean)
  • node scripts/pm/dispatch-gates.mjs --self-test — PASS, 234 cases (219 on base; +15: the three-way suspicion coverage, the liveness guards for the suspect table and constant, and the fixture-masking pin split into declared-glob vs fixture-only halves)
  • node scripts/pm/check-dispatch-gates.mjs — PASS
  • pnpm check:skill-frame-sync — PASS (4 copies isomorphic; the three-axis section was not touched)
  • pnpm check:doc-authoring — PASS (376 files clean)
  • pnpm --filter @objectstack/lint run check:doc-formula-expressions — PASS (after building the lint dependency closure)
  • node scripts/check-nul-bytes.mjs — PASS (6023 files, no raw control bytes)
  • bash -n scripts/pm/ensure-pm-labels.sh — PASS

Gate list re-derived from the actual changed paths (running node scripts/pm/dispatch-gates.mjs over the four changed paths): matched families are exactly the eight above (check:doc-authoring and check:doc-formula-expressions were the derivation's additions beyond the dispatch prompt's named list; both run green).

Tier derivation (quoted verbatim from node scripts/pm/dispatch-gates.mjs --tier over the four changed paths, at ad089549c)

Model tier — MANDATORY: claude-fable-5 (derived from the file surface, not recalled).
- .claude/skills/pm-dispatch/SKILL.md ⇢ '.claude/skills/pm-dispatch/**' — clause ① of the model-tiering ruling: a card editing the PM dispatch skill is fable-mandatory, references included — the skill is the lane's own operating protocol and a wrong edit propagates to every later dispatch
The only exit is the measured quota exemption (fable unavailable ⇒ opus, never lower), recorded with its reason in the claim comment's `Container & model` line.
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. This line is a FLOOR, never a clearance.

New suspicion output, demonstrated on the incident-shaped path (--tier packages/spec/src/api/error-code-ledger.zod.ts):

Model tier — no path-derived mandate: the surface hits none of the 1 declared glob(s), derived here, not recalled.
The tier stays the PM's per-card judgment call (floor sonnet · default opus · ceiling fable).
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. This line is a FLOOR, never a clearance.
Clause ② SUSPECT surface — a hint, not a verdict: judge the tier from the card CONTENT as best you can (a card changing contract accept/reject behaviour or widening the public surface is claude-fable-5); whichever tier is dispatched, the PR's actual diff passes the clause-② enqueue gate before the card may enqueue.
- packages/spec/src/api/error-code-ledger.zod.ts ⇢ 'packages/spec/src/**' — the contract surface (error-code ledger, *.zod.ts contract schemas) — the normal landing zone of a clause-② card

No conflict with the in-flight PR touching references/landing-operations.md and references/platform-readings.md — neither file is touched here.

This PR releases nothing (.claude/ + scripts/pm/ internal tooling only) — skip-changeset applies.


Generated by Claude Code

SKILL.md (queue-gate + review-chain rules 1-5, ceiling 682 held at 681 via
same-file rewrap funding), dispatch-gates.mjs (CONTRACT_REVIEW_TIER single
source, SUSPECT_TIER_GLOBS, --tier clause-2 suspicion hint + three-way
self-test), check-dispatch-gates.mjs (stale hint-measurement note refreshed),
ensure-pm-labels.sh (needs:contract-review label seed, main repo only).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017TNzEetykdh7ceZGwuAPLq
@github-actionsgithub-actionsBot added size/m documentation Improvements or additions to documentation labels Aug 17, 2026
@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 17, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 17, 2026 01:29
@os-zhuang
os-zhuang added this pull request to the merge queueAug 17, 2026
Merged via the queue into main with commit 08760a3Aug 17, 2026
26 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-9185-clause2-queue-gate branch August 17, 2026 01:37
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

技能卡:条款②入队闸门——契约面 diff 复核与 needs:contract-review 复审链

2 participants

@os-zhuang@claude