Repository navigation
feat(pm): epic seats open a mailbox and show on the fleet roster - #28751
Conversation
seatKey reads the epic lane `epic:#<parent>#K` (slug `epic-<parent>-K`; a `domain:epic-…` lane is refused so the slug stays one-to-one), so mailbox-open opens an epic seat's mailbox and a `To: epic:#N#K` doorbell reads. fleet-roster gives every open delegated `pm:epic` parent a row (one read per repo), seated by the login on its open mailbox, else seat 1 with status unknown; an epic mailbox is no longer flagged as on no seat row. project-forms 〈信箱 PR〉 says an epic seat opens one like any seat, paid by dropping the tool-owned branch spelling from the same line. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2g7RyXa8ErM6GAkHyc
|
domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc Contract reviewServed-tier: Inputs: card #28718 body and all four comments (triage 6560301001, state 6560747188, claim 6560767706, dev report 6561170948); PR #28751 body, file list (4 files, +109/−43) and ① Derived judgments
② Semver level
③ Boundary flagsDev deviations (report 6561170948), each answered:
Reviewer disclosure: this record is rendered by a contract-review subagent inside the ④ Design judgment
Findings — no must-fix:
Implemented-by: VERDICT: PASS |
…ted parents Contract-review should-fixes: the 〈信箱 PR〉 line brackets the seat number like the parent (`epic:#<n>#<k>`); an epic row's seats are matched by seatKey's slug `epic-<n>-<k>`, so a head-only epic mailbox seats its row as the mailbox column already reads it; and a registered `pm:epic` issue that an open mailbox names is a row before its first sub-issue (`isSeatedFreshEpic`), while `isEpicParent` stays equal to H45's two halves. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ihL2g7RyXa8ErM6GAkHyc
|
domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc Contract reviewServed-tier: This record supersedes 6561348241 (head ① Derived judgments
② Semver levelUnchanged from 6561348241: ③ Boundary flagsThe patch report carries no deviations and no Reviewer disclosure as before: rendered by a contract-review subagent inside the ④ Design judgment
Cited code, each prior should-fix against the new head:
Findings: none — no must-fix, no should-fix. Implemented-by: VERDICT: PASS |
|
domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc 维护者速读(席位终稿 · head
|
Requested by 田騏 · project thread
Fixes #28718
Clause-②: no
Metadata-protocol: none
维护者速读
epic:#父单号#K)现在能开信箱:mailbox-open.mjs认这种席位拼写;车队总表给每张已委托的pm:epic父单一行,信箱列显示它的信箱。scripts/pm/mailbox-open.mjs的SEAT_SHAPE/RESERVED_DOMAIN_LANE/ slug 一行;scripts/pm/fleet-roster.mjs的buildRowsepic 循环;project-forms.md〈信箱 PR〉首行。node scripts/pm/mailbox-open.mjs --repo objectstack-ai/objectstack --seat 'epic:#27293#1' --login sunhaolin --dry-run,应退出 0 并印出分支mailbox/sunhaolin/epic-27293-1。.claude/**属 Tier S,席位经契约复核记录落地。What changes
1.
mailbox-open.mjs— the seat grammar reads the epic lane.seatKeynow acceptsepic:#N#K(the seat-signature spelling the pm-dispatch references andcheck-half-states.mjs'sSIGNATURE_LANE_SOURCEalready use; measured live asepic:#27293#1,epic:#8345#1on the parent cards' signature lines).epic:#Nalone is seat 1, as for every lane. The epic kind is one new exported constant,SEAT_EPIC_KIND, and both the shape and the reserved set are built from it.epic:#27293#1); slug isepic-27293-1(the:#after the kind becomes one hyphen, then the seat's#), so the branch ismailbox/LOGIN/epic-27293-1— a legal ref segment.epic-;repo:slugs startrepo-, bare lanes aretriage-N/director-N. The only lane that could reachepic-N-Kis adomain:epic-Nlane, sodomain:epic-…joinsdomain:repo-…in the reserved set (nodomain:epic*label exists today).domain:epic/domain:epicsstill read.epic,epic:,epic:#,epic:12,epic#12,epic:#0,epic:#012,epic:#12#0,epic:#12#,epic:#12#1#2,epic:#abc,epic:#12-1,epic:skills#1.seatKey('epic:#12')as null now pins it asepic:#12#1/epic-12-1.record-recognisers.mjsis not edited: it readsTo:and every key's seat field throughseatKey, soTo: epic:#27293#1now reads (measured: aNotify: seat-online · epic:#27293#1 · …line reads withto: "epic:#27293#1";To: epic:27293is still refused). Its self-test passes unchanged.2.
fleet-roster.mjs— epic rows (the card's option (a)). One new read per repo,GET /repos/R/issues?state=open&labels=pm:epic, and a row per openpm:epicparent — sub-issues under it AND asession_…registration in its body, both halves of H45'sh45DelegationNodeSignals(held equal by the self-test; not imported, so the relay, which importsROSTER_MARKERfrom this file, never loads the patrol). Laneepic:#N, the seat link is the parent card.epic:#N#Kseat with an open mailbox (seat K, seated by the login on itsMailbox-of:line — a mailbox opens at seating and closes at hand-over); with none open, one row, seat 1, status unknown (? —), so an epic seat nobody can ring is visible as one.no seat post or epic parent carries this seat).Mailbox:line on the epic card body, needs the same epic-card read (or one read per epic mailbox) AND a new body protocol on epic cards; (a) needs only the read and reuses the delegation signal the epic lane already defines (「父单打pm:epic+ 正文写会话 ID」). Reading rows off the mailboxes alone (zero reads) was rejected: a mailbox of a closed epic would show as a live seat.3.
project-forms.md〈信箱 PR〉 — one line. The section's first line now says an epic seat (epic:#N#Kspelling in the rule) opens a mailbox like any seat. The file sits at its ratchet ceiling (54/54, headroom 0) and every line is near the 120-byte cap, so the clause is paid in place by deleting the branch spelling from the same line — a tooling detail whose one owner ismailbox-open.mjs's header. Line count unchanged, the line is 115 bytes.Session: https://claude.ai/code/session_017ihL2g7RyXa8ErM6GAkHyc
Tests
node scripts/pm/mailbox-open.mjs --self-test→✓ mailbox-open self-test: 81 cases in 10 batteries pass.(pins raised: arguments 13→14, seat 7→11, open plan 10→11, owner 7→8, finding 9→10, CLI 6→7).node scripts/pm/fleet-roster.mjs --self-test→✓ fleet-roster self-test: 88 cases in 8 batteries pass.(fixture battery 18→22, rendered body 9→10). The fixture gains two delegated parents (one with a mailbox, one without), apm:epicchild, an undelegated parent with sub-issues, an epic mailbox and a mailbox of a closed epic.record-recognisers.mjs --self-test(351 cases),check-owed-reviews.mjs --self-test(65),fleet-write/dispatch.mjs --self-test(265).node scripts/pm/fleet-roster.mjs --repos objectstack-ai/objectstack --json(no write): 30 rows, three epic rowsepic:#26676,epic:#27293,epic:#8345, each seat 1 status unknown (no epic mailbox is open yet).Acceptance notes
record-recognisers.mjs'sreadSeatdocblock still lists four lanes in prose; behaviour already followsseatKey. Left alone: outside this card's file surface.#8345's body says its epic seat is vacant in prose; the roster does not parse prose and shows it as unknown, the same as an epic with a live session but no mailbox. The mailbox is the seated signal.epic:#Nlane is not; a mailbox is matched to a parent by number across the repos read. No two live parents share a number today.Verification
Local gate union on head
27657d802c(dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, 38 derived families), each exit captured before any pipe;--ranreconciliation:✓ dispatch-gates --ran: 38 derived famil(ies) accounted for — 38 run, 0 NOT-MEASURED (a DERIVED zero — all 38 recorded an exit code and none of them is 3).Derived families and exits
All 38 exit 0. On the first pass, nine exited 3 (PREREQUISITE NOT MET: no
node_modules, and@objectstack/formula/@objectstack/lintunbuilt) andcheck-self-test-workflow-commands.mjsexited 1 onrelease-pending-publish.mjsfailing to import@changesets/cli— all environment, none measured anything. Afterpnpm install --frozen-lockfileandturbo run build --filter=@objectstack/formula --filter=@objectstack/lint(lock VERDICT command-exit 0) every one re-ran to exit 0.pnpm check:pm-dispatch-gates:✓ dispatch-gates self-test (fast tier): 1937 cases pass; 7 slow section(s) deferred.Among them, the four the order names:
pnpm check:pm-skill-ratchet0 (project-forms.md 54 lines, ceiling 54),pnpm check:pm-skill-id-lint0,pnpm check:skill-frame-sync0. Outside the derived set, also run:pnpm check:pm-governed-prose0, and both scripts'--self-test0.No changeset:
scripts/pm/**and.claude/**publish nothing (skip-changeset).🤖 Generated with Claude Code