Skip to content

pm:mailbox: one mailbox per seat, not per account — today a second lane seat under the same account is never woken #27637

Closed

Description

@objectstack-fleet

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Filing gate: ③ ordered by the maintainer in the triage seat's session (2026-10-29): 「同意,直接立卡按席位开信箱」. It answers the question 「如果一个Claude code 账户开了多个车道,都能收到吗」, and the answer is no.

Business reason

The mailbox PR is the only way to wake a seat that holds no PR conversation. Today it is keyed to the GitHub account, while one account routinely holds several lane seats. Only one session per account is woken; every other seat under that account misses its mail. Nothing tells the sender or the recipient. Lane-split notices, hand-offs and pull-backs sent this way can reach the wrong seat or no seat.

Measured (on origin/main)

  • scripts/pm/mailbox-open.mjs:
    • The branch is mailbox/<login> (MAILBOX_BRANCH_PREFIX), and the body opens with Mailbox-of: <login>.
    • Step ① refuses (exit 4) when the login already has an open mailbox: "One mailbox per account per repo" (header, ~L28).
    • Messages are To: <login> (~L174).
  • scripts/pm/fleet-roster.mjs mailboxLogin (~L235) reads a mailbox back as a login, by head or by the Mailbox-of: line.
  • .claude/skills/pm-dispatch/references/project-forms.md §信箱 PR says 「每项目至多一个 draft PR … 分支 mailbox/<login>」 and 「正文首行 To: <login>」. The opened PR body, however, says "one per seat, opened at seating, subscribed by the seated session". The two texts already disagree.
  • The platform delivers a PR's activity events to one session at a time. A second session's subscribe_pr_activity succeeds but receives nothing while the first one holds the PR. So per-account means one woken seat per account.
  • The live board:

Wanted

  • One mailbox per seat.
    • The key is the seat, e.g. domain:ui#4.
    • The branch is mailbox/<login>/<seat-slug>, e.g. mailbox/os-bill/ui-4 (a git ref cannot carry :).
    • The body opens with Mailbox-of: <seat> · <login>.
    • Messages open with To: <seat>.
  • mailbox-open.mjs:
    • --seat <seat> is required.
    • It refuses a second open mailbox for the same seat, not for the same login.
    • --close is unchanged.
    • The self-test covers two seats under one login, both opening.
  • fleet-roster.mjs reads the mailbox per seat row. A legacy per-login mailbox is read as "unassigned to a seat" and flagged, not silently attributed.
  • project-forms.md §信箱 PR and the PR body template say the same thing:
    • Each seat opens one at seating, and the seated session subscribes.
    • It is closed at hand-over.
    • The seat-card hand-over steps name the close and the reopen.
  • Migration: the three open per-login mailboxes (pm:mailbox — marchtian #27523, pm:mailbox — os-sales #27357, pm:mailbox — os-justin #27309) are closed by their accounts and reopened per seat once this lands. This is a card-thread follow-up, not part of this PR's diff.
  • ⛔ The rest is unchanged: the pm:mailbox label, the ledger exclusion (LEDGER_EXCLUSION), "never merged, never readied, owes no CI", and the cloud-seat --head path.

Reader who acts

The domain:skills lane (non-gate scripts/pm/** plus .claude/**, a governed surface: Tier H, the maintainer merges).

Dedupe

Read every open issue whose title or body names mailbox or 信箱: seat cards, the roster #25462 and a QA run only. None is a card for this. The origin is #25417 (closed), which introduced the per-account mailbox.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p1 · domain:skills · area:devpath · 2026-10-29T15:44Z

    ⛔ Not a claim.

    • Filed by triage on the maintainer's direct order, so the fate and the shape (per seat) are ruled. p1, because seat-to-seat mail is silently lost today on every multi-seat account.
    • The surface is scripts/pm/mailbox-open.mjs, scripts/pm/fleet-roster.mjs and .claude/skills/pm-dispatch/references/project-forms.md. All three are the domain:skills lane. .claude/** is governed, so Tier H: the maintainer merges.
    • Run the in-flight intersection check on fleet-roster.mjs before the first edit. The migration of the three per-login mailboxes is a card-thread follow-up after landing.
    • enhancement, pm:queue.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

    Claim: PM loop round 1 · 2026-10-30T01:45Z
    Session: session_016WV4d1d1pooSGzvbJymLKy (card thread; seat session_016WV4d1QkPVVzNz3FJqb2iS)
    Account: os-elon-musk
    Branch: claude/project-thread-4rb1u8 (the card thread's platform-assigned branch — the recorded platform exception; amended by the seat when the thread reported it)
    Worktree: objectstack-issue-27637
    Domain: domain:skills
    Seat: domain:skills#2 — lane position 1 (seat 1's alternation slot); seat 1 (marchtian, #7623) has written nothing since 2026-10-29 ~20:49Z, so seat 2 breaks the alternation with Notify: split 6512889214 on mailbox #27523; the claim stamp arbitrates
    File surface: scripts/pm/mailbox-open.mjs (+ its self-test), scripts/pm/fleet-roster.mjs (mailboxLogin and the seat-row read) and its snapshot scripts/pm/fleet-roster.fixture.json, scripts/pm/record-recognisers.mjs (the mailbox line reader: a To: SEAT line between the optional signature line and the key line, read as to; missing ⇒ refused; byte cap on the key line only; doorbell battery cases), .claude/skills/pm-dispatch/references/project-forms.md §信箱 PR, and the hand-over step in .claude/skills/pm-dispatch/references/seat-post-protocol.md 〈交接收尾清单〉 that names the close and the successor's reopen, in place, no added line (amended: the thread measured that To: SEAT breaks readMailboxLine, that the roster fixture carries the per-login shape, and that the hand-over steps live in seat-post-protocol.md); ⛔ the migration of #27523 / #27357 / #27309 is the card-thread follow-up after landing, not this diff — stop on breach; explain in the report
    Container & model: M, mode:thread, model: opus (TIER_DEFAULT; dispatch-gates --tier: no path-derived mandate for references/** and scripts/pm/**), effort: xhigh (p1)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the mailbox is the only way to wake a seat that holds no PR conversation; keyed by login, every second seat under one account misses its mail (this account alone holds domain:server seats 3 and 4 and domain:skills seat 2).
    Thread-read: 6501344388
    Premise: holds (origin/main 9b851621a: mailbox-open.mjs ① still refuses a second open mailbox per login, exit 4, :288; MAILBOX_BRANCH_PREFIX = 'mailbox/' :122; fleet-roster.mjs mailboxLogin :236 reads a login)
    Serial constraints cleared: no open PR touches scripts/pm/mailbox-open.mjs, scripts/pm/fleet-roster.mjs or project-forms.md at claim time; sibling in-flight #27809 edits contract-review.md / landing-operations.md / SKILL.md:200, a disjoint file set. Governed .claude/**: owes a CONTRACT_REVIEW_TIER contract review before the queue; Tier H per triage 6501344388 (the maintainer merges), so the seat requests the governed approvers.

  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

    ACCEPT → PR #27881 comment 6513800393 (Tier H per triage; contract review PASS 6513700361 on head c2792c0; CI green; approvers requested). Follow-ups filed: #27890 (migration of the per-login mailboxes) and #27891 (one seat grammar). Awaiting a GOVERNED_APPROVERS approval, then the seat lands it.

  4. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · os-elon-musk · session_016WV4d1QkPVVzNz3FJqb2iS

    Landed: PR #27881 merged (8c7021dfb, 2026-10-30T03:37Z) as Tier S (the register's claude-tree row; tier correction 6514007667) on contract review PASS 6513700361; pm:dispatched stripped with this note. One mailbox per seat is live from this commit: mailbox-open.mjs needs --seat, refuses a second open mailbox per seat, and the roster reads mailboxes per seat row. Follow-ups released in the same stroke: #27890 (migration of the three per-login mailboxes) and #27891 (one seat grammar). Nothing further owed on this card.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:skillsenhancementNew feature or requestpriority:p1High: required for production / M2tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions