Repository navigation
pm-dispatch: pm:epic marks every card an epic reserves — never with pm:queue - #15696
Conversation
…`pm:queue` SKILL.md 「Epic 子树车道」 gains the five reservation rules (children carry `pm:epic`, claim protocol as written, one-write hand-over, the half-state, single- vs multi-lane repos), paid inside the section by merging adjacent single-rule lines; the `pm:epic` label-table row and the label description in `scripts/pm/ensure-pm-labels.sh` carry the same meaning. Ceiling untouched (811/811, table pin 342). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
…ic-reservation-label-on-children
|
ACCEPT — governed in-seat review of PR #15696, head Implemented-by: Verified in a detached compare worktree at the PR head against merge-base Landing regime: governed ( Generated by Claude Code |
Fixes #15666
Governed surface (
.claude/**) — draft PR, human merge. No seat flips it ready, enqueues it, arms auto-merge, or approves it.skip-changeset: the diff publishes nothing from any released package (.claude/**+scripts/pm/**).What changes, and why only this
The maintainer's rulings stay verbatim on the card (no dates, quotations or card numbers enter the file): the reservation an epic holds must be visible on every reserved card in the list page, and reusing
pm:epicon the sub-issues instead of a new label was accepted. This PR writes that meaning into exactly the three surfaces the card names:.claude/skills/pm-dispatch/SKILL.md— section「Epic 子树车道」: the five rules, one line each, paid inside the section (811 of 811 lines; ceiling untouched; every line ≤120 bytes)..claude/skills/pm-dispatch/SKILL.md— thepm:epicrow of the label table.scripts/pm/ensure-pm-labels.sh— thepm:epicdescription only (98 characters against the 100 cap). Repo list untouched — the loop already seeds all five repos includingcloud; no credentials logic.Deliberately untouched, per the rulings:
references/core-rules.md(the digest carries no epic line today),references/state-machine.md,scripts/pm/check-half-states.mjs(the two patrol rows are the sibling card #15667, filed in the same act), every other SKILL.md section, every ratchet row and pin.Before → after
Section「Epic 子树车道」(SKILL.md lines 298–311; the angle-bracket placeholder in the
epic:argument is spelledNhere and is unchanged in the file)Before — 14 rule lines:
After — 14 rule lines:
Label-table row (SKILL.md line 118)
| `pm:epic`(父单) | 子树已委托 epic PM;其它 PM 不把其 sub-issue 当候选 |— 87 bytes| `pm:epic`(父单或 sub-issue) | 已由 epic PM 保留;其它 PM 永不取;⛔ 永不与 `pm:queue` 同挂 |— 110 bytes (the file's widest row stays thedomain:enginerow at 342, pin unchanged)Label description (
scripts/pm/ensure-pm-labels.sh, thepm:epicline)Parent delegated to a dedicated epic PM — other PMs never dispatch into its subtree— 83 charactersReserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue— 98 characters (cap 100, measured in code points as the gate does)Rule inventory — one row per surviving line (E1–E14 = the 14 pre-existing rules in file order; N1–N5 = the card's five)
pm:epic, ⛔ neverpm:queue;label:pm:epicis the whole reserved set, parents and children; domain seats never take onelabel:pm:epicindex + epic PM holds nodomain:*seat; 选择时→选择, 不同时持有→不兼任Claim:, full-thread re-read;pm:epicstays after the claimpm:epicand addspm:queuein one label writepm:epic+pm:queueon one card is a half-state (reserved and handed over at once);pm:queuemeans handed over; taking back = full claim protocol incl. the re-readdomain:*) may open-and-claim in one act; multi-lane repos keep the domain-label prerequisite, the subtree marker is the reservationpackages/spec/public contract go to the spec seat queue, epic side writesBlocked-by:; now one ⇒ branch of the trichotomyreferences/seat-post-protocol.md)All 14 pre-existing rules survive; the section's one pre-existing ⛔ (E12) survives; two ⛔ are added (line 3, the table row). Five lines paid by six joins (E6 is split across lines 5 and 6), net 0 lines in the file.
Gates — all run on the merged head
edc6d1226after the final commit; exit codes captured before any pipe; each gate's own verdict line quotedpnpm check:pm-skill-ratchet— exit 0 —✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md is 811 lines (ceiling 811; headroom 0).and✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/SKILL.md: widest table row is 342 bytes (pin 342; headroom 0).pnpm check:skill-frame-sync— exit 0 —✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 files(none of the frame's fingerprint phrases appear in the new lines)pnpm check:pm-governed-prose— exit 0 —✓ check-governed-prose: 2 instruction surface(s) name all 5 registered governed surfaces (docs/adr/** · .claude/** · skills/** · AGENTS.md · CLAUDE.md) and claim no others.pnpm check:pm-skill-id-lint— exit 0 —✓ check-skill-id-lint: 24 file(s) clean (pattern /#[0-9]{3,}/g).pnpm check:pm-label-desc-cap— exit 0 —✓ check:pm-label-desc-cap: 23 label descriptions in scripts/pm/ensure-pm-labels.sh, all ≤100 characters (longest: 100, repo:objectui).pnpm check:nul-bytes— exit 0 —check-nul-bytes: OK (scanned 7583 text file(s) -- 7583 tracked, 0 untracked-not-ignored; skipped 7 binary; no raw ASCII control bytes).node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/SKILL.md scripts/pm/ensure-pm-labels.sh— exit 3 (expected) —⛔ GOVERNED — a human merge is the review record for this PR,.claude/** ×1;paths not on the register: scripts/pm/ensure-pm-labels.shnode scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack⇒ 32 commands; every one executed and recorded byte-for-byte;node scripts/pm/dispatch-gates.mjs --ran— exit 0 —✓ dispatch-gates --ran: 32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED.31 of the 32 exit 0 (each gate's own verdict line is in the run log); the one non-zero is below.pnpm lint(eslint . --no-inline-config, whole tree — no narrowing to declare) throughscripts/pm/os-verify-lock.sh—VERDICT command-exit 0 · held the lock 110sonedc6d1226(and command-exit 0, held 120s, on the pre-merge commit718c718a5); shared-box seconds, not idle-box figures.dispatch-gates.mjs --tier: MANDATORY (clause ①, the PM skill main file).Not measured locally (honest gaps, CI owns them)
pnpm --filter @objectstack/lint run check:doc-formula-expressions— exit 3,PREREQUISITE NOT MET — the workspace package `@objectstack/formula` is not built; after building@objectstack/formulathrough the lock (VERDICT command-exit 0, held 236s) the next prerequisite is@objectstack/lint's own dist. A whole-tree family overcontent/docsformula expressions, which this diff does not touch.check-cross-package-test-inputs --union-into,check-shard-attestation,check-test-completeness) and 1 CI-measured-only family, as it prints them.Serial notes
origin/main5eb24f867;origin/mainmerged in ata55efc6c1(the derivation flagged two gate scripts as moved, so the union was re-run on the merged head).origin/mainhas since moved again (95d5cbb31); the delta of this branch against it is exactly the two files above.pm:retriageis the only channel a seat has for asking triage a NON-grading question, so those cards are skipped by every dispatcher and actionable by no sweep — one ruled p1 sat 2d5h #15404 (two SKILL.md lines onpm:retriage) waits behind this PR on the same file. The ratchet map is not touched here.🤖 Generated with Claude Code
https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
Generated by Claude Code
Generated by Claude Code