Repository navigation
pm-dispatch: pm:epic marks every card an epic reserves, not only the parent — a reserved card never carries pm:queue, and pm:queue means handed over (maintainer 2026-09-05) #15666
Description
Activity
- addeddocumentationImprovements or additions to documentationImprovements or additions to documentationpriority:p2Medium: important, M3Medium: important, M3
on Sep 5, 2026 Claim: PM loop round 5 — unblocked the minute PR #15460 landed (02:16Z); the maintainer's live ruling of 2026-09-05, executed on the rewritten SKILL.md
Session:session_019RfFHiRCSs3JXLK4cwcfox
Branch:claude/issue-15666-epic-reservation-label-on-children
Worktree:objectstack-issue-15666
Domain:domain:skills
File surface:.claude/skills/pm-dispatch/SKILL.md— the「Epic 子树车道」section (lines 296–307 onmainfa125f3bf) and thepm:epicrow of the label table (line 118): the five rule lines on the card, paid inside the section (811 of 811, headroom 0; ⛔ no ceiling raise, ⛔ no other section) +scripts/pm/ensure-pm-labels.sh: thepm:epicdescription (the script already seeds all five repos includingcloud, so no repo-list change). ⛔ No edit tocore-rules.md(the digest carries no epic line today),state-machine.md, orcheck-half-states.mjs(that is #15667) (stop on breach; explain in the report)
Container & model: S,mode:subagent,model: fable(dispatch-gates.mjs --tier .claude/skills/pm-dispatch/SKILL.md scripts/pm/ensure-pm-labels.shatfa125f3bf, 02:3xZ: MANDATORY — SKILL.md is clause-① mandatory)
Clause-②: no (PM protocol text; no published contract)
Serial constraints cleared: PR #15460 (member 1b) MERGED 02:16Z — the section is edited on its rewritten form; no open PR touches SKILL.md or the label script (scan 02:28Z); #15404 (two SKILL.md lines onpm:retriagesemantics) is the same file's next card, a different defect ⇒ hard-serial behind this flight (pm:blocked,Blocked-by: #15666); the ratchet map is shared with PR #15641 (dirty, being re-merged by its dev) on disjoint rows and this flight does not touch the map. GOVERNED ⇒ draft PR, in-seat review,os-zhuang+hotlong, human merge,skip-changeset. The PR carriesFixes #15666.Decision re-read (02:3xZ): the four maintainer messages quoted on the card are the whole mandate; the「ok」accepted the seat's proposal as written; nothing further owed.
Generated by Claude Code
os-dev-report
{ "issue": 15666, "status": "done", "branch": "claude/issue-15666-epic-reservation-label-on-children", "pr": "https://github.com/objectstack-ai/objectstack/pull/15696", "premise_still_valid": true, "summary": "Wrote the four rulings into exactly the three surfaces the card names, on the rewritten SKILL.md (base 5eb24f867, origin/main merged in at a55efc6c1): (1) SKILL.md section Epic 子树车道 now carries the five reservation rules, one line each (children hang under the parent and carry pm:epic, never pm:queue, label:pm:epic is the whole reserved set and domain seats never take one; claim atomic pair as written with pm:epic staying after the claim; leaving the subtree swaps pm:epic for pm:queue in one label write; pm:epic + pm:queue is a half-state and pm:queue means handed over, take-back is the full claim protocol incl. re-read; single-lane repos may open-and-claim, multi-lane keep the domain-label prerequisite) — paid inside the section by six joins of adjacent lines (E2+E4, E5+E6a, E6b folded into the rule-2 line, E8+E9, E7+E10, E11+E12), all 14 pre-existing rules and the one pre-existing ⛔ survive, every line ≤120 bytes, file stays 811/811 with the table pin at 342; (2) the pm:epic label-table row now reads reserved by an epic PM, parent or sub-issue, other PMs never take it, ⛔ never with pm:queue (110 bytes); (3) scripts/pm/ensure-pm-labels.sh pm:epic description is now 'Reserved by a dedicated epic PM, parent or sub-issue; other PMs never take it; never with pm:queue' (98 chars, cap 100) — repo list and credentials untouched. Nothing else edited: core-rules.md (no epic digest line exists today), state-machine.md, check-half-states.mjs (sibling card #15667), other sections, ratchet rows. Governed surface ⇒ opened PR #15696 as a DRAFT to main, first line Fixes #15666, skip-changeset added via the REST additive endpoint and read back (delayed re-read at 03:35Z still carries it, plus the labeler's documentation + size/s); reviewers os-zhuang + hotlong requested at 03:17Z. State I did not set, recorded and not reverted (timeline actors read via REST): os-zhuang APPROVED at 03:23:52Z, flipped ready_for_review at 03:23:57Z, enabled auto-merge at 03:24:00Z and added_to_merge_queue at 03:33:28Z; the Governed Surface Queue Guard check reported success on both its runs. I never readied, enqueued, armed or approved anything; whether that approval is an authorized landing of a governed diff (GOVERNED_APPROVERS in scripts/pm/check-governed-queue-guard.mjs) is the PM's/maintainer's read, flagged here rather than acted on. Observations, no action: SKILL.md line 425 (已排队父单… pm:epic 父单的子树除外, outside the section) and check-half-states.mjs comments still describe pm:epic as a parent marker — consistent with the new rule (children carry it too) and the latter file belongs to #15667. The PR body was PATCHed once to repair backslash-escaped backticks inside inline code spans; the platform's footer downgrade on edit was observed as measured (session-form block kept from creation, bare block appended), not re-pasted. The assignee field was empty at pickup (PM-side half state as the prompt anticipates); a REST repo-scoped read probe answered 200 so all GitHub reads and writes went through REST — zero MCP GitHub calls.", "tests": "Local, on the merged head edc6d1226 after the final commit (exit codes captured before any pipe; each gate's own verdict line quoted): pnpm 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'; 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'; 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).' (the pm:epic description is 98 code points); 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 as expected — '⛔ GOVERNED — a human merge is the review record for this PR', .claude/** ×1, 'paths not on the register: scripts/pm/ensure-pm-labels.sh'; node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack ⇒ 32 commands (derived from the change set git computed: the two files, committed), every one executed and its printed command recorded byte-for-byte, then --ran exit 0 — '✓ dispatch-gates --ran: 32 derived famil(ies) accounted for — 32 run, 0 NOT-MEASURED.'; 31 of 32 exit 0 (verdict lines in the run logs), the one non-zero is 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/formula through the lock (VERDICT command-exit 0, held 236s) the next prerequisite is @objectstack/lint's own dist ⇒ NOT MEASURED locally, a whole-tree family over content/docs formula expressions this diff does not touch. The same 32-command union had already run green (same one exit-3) on the pre-merge commit 718c718a5; it was re-run because the first --ran flagged two gate scripts (check-governed-merges.mjs, check-governed-queue-guard.mjs) as moved on origin/main, so origin/main a55efc6c1 was merged in and everything re-measured on edc6d1226. pnpm lint (eslint . --no-inline-config, the whole tree — no narrowing to declare) through scripts/pm/os-verify-lock.sh: 'VERDICT command-exit 0 · held the lock 110s (1m50s) · waited 195s' on edc6d1226 and 'VERDICT command-exit 0 · held the lock 120s' on 718c718a5 — shared-box seconds, not idle-box figures. Byte measurements on HEAD: the 14 section lines are 97/95/117/108/113/111/92/119/110/119/115/117/106/91 bytes (none over 120), row 118 is 110 bytes, the file is 811 lines, widest table row 342. No test suite is touched (rules-only prose and one shell string literal), so no vitest run applies. CI on PR #15696 (head edc6d1226): all 38 check runs completed by 03:33Z, none non-green — Lint & Repo Gates success; Type Check · workspace / source gates / consumer gates / debt ledger success; Test Core success (6 of 6 shards); Dogfood Regression Gate success; Governed Surface Queue Guard success (both runs); No other open PR may claim the same issue / single-writer path success; Check Changeset skipped (skip-changeset present); Build Core, Temporal Conformance and Console Pin Gate skipped by path filter.", "mcp_calls": "0 — every GitHub read (issue page payload channel, check runs) and write (draft PR, label, reviewers, body PATCH, report comment) went through the REST channel after a repo-scoped read probe returned 200; MCP GitHub tool schemas were loaded but never invoked", "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
Filed by the
domain:skillsseat (sessionsession_019RfFHiRCSs3JXLK4cwcfox, os-steve) on maintainer rulings given in the live PM chat, 2026-09-05 02:0xZ–02:2xZ. Self-triaged into the lane:priority:p2, governed surface,pm:blockedbehind PR #15460 (the rules-only rewrite of the same file, in the merge queue).Blocked-by: #15412
The incident (cloud repo, reported by the maintainer)
An epic (专题) session opened a card with
pm:queue, then implemented it itself; a patrol lane had lawfully claimed the same card 29 minutes earlier. One card, two implementations. The epic's own post-mortem: it skipped the claim protocol's full-thread re-read, and it had put the card into the public queue while assuming nobody would take it.The rulings (verbatim, untranslated)
⇒ Ruled: the reservation must be visible on every reserved card in the list page. The seat's recommendation — reuse
pm:epicon the sub-issues rather than add a new label — was accepted with the「ok」.What changes (rules only, house style)
.claude/skills/pm-dispatch/SKILL.md, section「Epic 子树车道」and thepm:epicrow of the label table:pm:epicon each of them; ⛔ neverpm:queue. A card carryingpm:epicis not a candidate for any domain seat;label:pm:epicis the whole reserved set, parents and children.Claim:comment, then the full-thread re-read;pm:epicstays on the card after the claim.pm:epicand addspm:queuein the same label write.pm:epicandpm:queueon one card is a half-state — reserved and handed over at once.pm:queuemeans handed over: taking such a card back means the full claim protocol, re-read included.domain:*): open-and-claim in one act is lawful there; in multi-lane repos the domain-label prerequisite stands and the subtree marker is the reservation.references/core-rules.md: one digest line only if the digest carries the epic rule today (check; ⛔ no new section).scripts/pm/ensure-pm-labels.sh: thepm:epicdescription becomes "Reserved by a dedicated epic PM — parent or sub-issue; other PMs never take it; never together with pm:queue" (wording free, meaning fixed). Seeding thecloudrepo is done by whoever runs the script with access there — note it in the script's repo-list comment; ⛔ no credentials logic.Why not a new label (recorded so it is not re-derived)
pm:epicis already in the patrol's visibility set (PM_STATE_LABELSinscripts/pm/check-half-states.mjs) and not in the six-state exclusive set, so a child carryingpm:epic+pm:dispatchedis legal and trips neither H25 nor H29; triage does not grade a card that has a named reader. A new label would have to be learned by the triage disjunction, the patrol and the unlock scan; per-epicepic:#nlabels would sprawl.Serial and gates
Same file as PR #15460 (member 1b of #15379), in the merge queue: this card dispatches after it lands and edits the rewritten file — one rule per line, ≤120 bytes, no dates or quotations in the file (the quotations above stay on this card). The rewritten
SKILL.mdis re-pinned at its landed count with headroom 0, so the added lines are paid for inside the epic section (⛔ no ceiling raise). Gates:check:pm-skill-ratchet,check:skill-frame-sync,check:pm-governed-prose,check:pm-skill-id-lint, and whateverdispatch-gates --commandsderives. Governed ⇒ draft PR, in-seat review,os-zhuang+hotlong, human merge.The two patrol rows that make these states visible are the sibling card, filed in the same act.