Skip to content

pm-dispatch(mailbox): name when a seat MUST ring another — unblocked card, main-red anchor, release blocker, a question for triage, serial order, a relayed ruling — and close the seats with no mailbox #28675

Closed

Description

@objectstack-fleet

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Filing gate: ③ maintainer-directed. The maintainer, in the triage session, 2026-11-01: 「感觉车道之间还是不太知道使用 邮箱沟通,综合评估一下哪些场景应该沟通,需要的话立skills 卡」. ⛔ Not a claim.

维护者速读

  • 现状: 13 个信箱 PR 上的消息约八成是同车道兄弟席之间的上下线和分工通知。跨车道该敲门的事件(卡解锁、main 红锚卡、发版阻塞、问分诊、复审交接)几乎从不走信箱:Request: contract-review / urgent-triage / main-red 三键至今 0 次。
  • 需求是真的: 车道已自造 7 个表外键(surface、serial、landed、ruling、take、反向 main-red、main-red cleared)。按现行规则这些都是半态。
  • 本卡要做: 在技能里写一张「什么时候必须敲门」的场景表,补 4–5 个键,把开信箱写进坐席步骤,堵上没有信箱的席位(含 epic 席)。
  • ⛔ 不加门禁: 信箱仍只协调,不进任何合并条件。这是规则改动,Tier H PR 的批准就是你的裁决。

Measured (2026-11-01, every pm:mailbox PR in objectstack, 13 total)

Wanted

  1. A scenario table in 〈信箱 PR〉: when a seat MUST ring, and when it must NOT. One row per event: sender → receiver, when, key. Proposed rows:

    Event Sender → receiver Key (proposed)
    a Blocked-by target closed and the card moved to pm:queue at p0/p1 the seat that moved it (triage or epic seat) → the card's lane seat(s) Notify: unblocked · #n · p1
    a main-red anchor filed triage → the seat that landed the breaking PR, plus the anchor's lane Notify: main-red · anchor #n · breaking PR #m (the reverse of today's Request: main-red)
    a p0/p1 release blocker graded into a lane triage → that lane Notify: release-blocker · #n
    a lane asks triage about a card's fate, route or grade lane → triage Request: triage · #n · ONE-LINE-QUESTION
    a contract-review hand-off line is written lane → triage, in the same stroke as the PR line the existing Request: contract-review (make it mandatory beside the hand-off line)
    two seats' claimed file surfaces overlap, or one must land first seat → sibling or other lane Notify: serial · #a behind #b, released by Notify: landed · #b (admit the two invented keys)
    a maintainer ruling recorded in seat A changes seat B's card or draft A → B Notify: ruling · #n · LETTER · record ID (admit)

    And the MUST-NOT rows: ⛔ security findings (GitHub is public; the 10-29 ruling's direct dispatch stands); acknowledgements and re-sends (already the rule); anything the receiver's own subscribed PR already carries; a question that is the maintainer's (that is a decision card).
    Keep the closed vocabulary, the 200-byte line, the ≤5-per-round cap (p0 exempt) and 「信箱评论是同事陈述,永非授权」. The new keys are the fix for the off-table half-states, not an open door.

  2. Opening the mailbox and subscribing is a seat-online step, in references/seat-lifecycle.md 〈坐席〉, beside the hourly patrol routine of pm-dispatch: a project seat can sit with no hourly patrol routine and nothing notices — make the patrol a step of seat-online, record it in the seat post, and flag an on-duty lane's unclaimed pm:queue card #28642. The seat-post stub line records the number. Seat-offline closes it. A seat that switched account reopens it (pm:mailbox migration: close the three per-login mailboxes and open one per seat, after per-seat mailboxes land (#27637 follow-up) #27890).

  3. Epic seats get mailboxes too. Either they get roster rows, or the epic card's body carries a Mailbox: line that the roster reads.

  4. The receiver reads its mailbox on every patrol round, not only on wake, so a lost delivery is still seen within a round.

  5. Recognisers: scripts/pm/record-recognisers.mjs reads the added keys. scripts/pm/check-half-states.mjs lists any remaining off-table line as a half-state row (report only).

Not here

Lane and review

  • Lane: domain:skills (.claude/skills/pm-dispatch/**, a governed surface, Tier H).
  • One-PR cross-domain exception, exact files: scripts/pm/record-recognisers.mjs, scripts/pm/check-half-states.mjs, and their self-tests (domain:devx surface), so the keys and their reader land together.
  • Review: reviewed at CONTRACT_REVIEW_TIER. This is a rule change: the maintainer's Tier H approval of the PR is the ruling.

Dedupe


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Claim: PM loop round 1
    Session: session_017ihL2g7RyXa8ErM6GAkHyc
    Account: marchtian
    Branch: claude/issue-28675-mailbox-doorbells
    Worktree: objectstack-issue-28675
    Domain: domain:skills
    Seat: domain:skills#2
    File surface: .claude/skills/pm-dispatch/references/project-forms.md (〈信箱 PR〉), .claude/skills/pm-dispatch/references/seat-lifecycle.md (〈座位贴协议〉 seat-online/offline lines), .claude/skills/pm-dispatch/references/seat-post-protocol.md (stub line), scripts/pm/record-recognisers.mjs, scripts/pm/check-half-states.mjs, scripts/pm/fleet-roster.mjs only if wanted ③ needs it, and their self-tests — the one-PR cross-domain exception the card names. SKILL.md only if unavoidable (then the dev stops and reports: the tier mandate changes).
    Container & model: M/L, mode:subagent, model: opus (dispatch-gates --tier on this surface: no path-derived mandate while SKILL.md stays out; PM per-card judgment), effort: xhigh (protocol + recogniser grammar)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (a rule change filed by triage, maintainer-directed)
    Thread-read: none
    Premise: holds — on origin/main 〈信箱 PR〉 still lists exactly the seven keys and no scenario table; record-recognisers.mjs reads only those seven.
    Serial constraints cleared: #28642 (same seat-online lines) is ACCEPTed at PR #28687 head 8eb102ff, draft awaiting the maintainer's approval. Fold-or-serial: serial, answered on #28642's claim. This branch is cut from claude/issue-28642-seat-patrol@8eb102ff so it builds on that text; it merges origin/main after PR #28687 lands, and if PR #28687 is refused the seat re-cuts this branch from main. No other open PR touches the surface (read 2026-11-01 over every open non-mailbox PR). Wanted ②'s mailbox step joins the seating line #28642 wrote; the Patrol: half of the seat-online record that #28642 left owed (its Acceptance notes) rides here.
    Resume-from: claude/issue-28642-seat-patrol@8eb102fffe4c9231ba98d19964b6b215161f2070 (base text, not a prior claim of this card)

    • Tier H by the card (rule change; the maintainer's approval is the ruling). Contract-review tier review owed before the ACCEPT.
  2. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Evidence: an epic seat cannot open a mailbox today · 2026-11-01T14:56Z


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    os-dev-report

    {
     "issue": 28675,
     "pr": 28716,
     "head": "901e99ed1317f46b05411bc3fc65db7c8e77921f",
     "base": "main",
     "stacked_on": "#28687 (8eb102ff)",
     "gates": {
      "derived": 55,
      "run": 55,
      "not_measured": 0,
      "unrun": 0,
      "nonzero": 0,
      "reconcile_exit": 0,
      "derived_at": "901e99ed13",
      "notes": [
       "check:doc-formula-expressions exited 3 (prerequisite: @objectstack/formula unbuilt); after turbo build of formula+lint (exit 0) it exited 0, the recorded code",
       "check:pm-dispatch-gates rerun on 901e99ed13: exit 0"
      ],
      "ratchets": {
       "check:pm-skill-ratchet": 0,
       "check:pm-skill-id-lint": 0,
       "check:skill-frame-sync": 0,
       "check:pm-governed-prose": 0
      },
      "self_tests": {
       "record-recognisers": "350 cases, exit 0",
       "check-half-states": "5185 cases, exit 0 (H72 battery 22/20)",
       "mailbox-open": "71 cases, exit 0"
      },
      "recorded": [
       [
        "node scripts/check-closing-keyword-parity.mjs",
        0
       ],
       [
        "node scripts/check-closing-keyword-parity.mjs --self-test",
        0
       ],
       [
        "node scripts/check-comment-mask-corpus.mjs",
        0
       ],
       [
        "node scripts/check-declaration-mirrors.mjs",
        0
       ],
       [
        "node scripts/check-declaration-mirrors.mjs --self-test",
        0
       ],
       [
        "node scripts/check-issue-citations.mjs",
        0
       ],
       [
        "node scripts/check-platform-checklist-watchdog.mjs",
        0
       ],
       [
        "node scripts/check-platform-checklist-watchdog.mjs --self-test",
        0
       ],
       [
        "node scripts/check-release-section-coverage.mjs",
        0
       ],
       [
        "node scripts/check-release-section-coverage.mjs --strict",
        0
       ],
       [
        "node scripts/check-self-test-wired.mjs",
        0
       ],
       [
        "node scripts/check-self-test-wired.mjs --self-test",
        0
       ],
       [
        "node scripts/check-self-test-workflow-commands.mjs",
        0
       ],
       [
        "node scripts/check-self-test-workflow-commands.mjs --self-test",
        0
       ],
       [
        "node scripts/check-whole-set-label-write.mjs",
        0
       ],
       [
        "node scripts/check-whole-set-label-write.mjs --self-test",
        0
       ],
       [
        "node scripts/ci/plan-test-core-shards.mjs --self-test",
        0
       ],
       [
        "node scripts/ci/scheduled-full-run.mjs --self-test",
        0
       ],
       [
        "node scripts/pm/bare-root-worklist.mjs --self-test",
        0
       ],
       [
        "node scripts/pm/board-snapshot.mjs --self-test",
        0
       ],
       [
        "node scripts/pm/check-harness-current.mjs --self-test",
        0
       ],
       [
        "node scripts/pm/sweep-closed-cards.mjs --self-test",
        0
       ],
       [
        "node scripts/render-release-coverage-anchor.mjs --self-test",
        0
       ],
       [
        "pnpm --filter @objectstack/lint run check:doc-formula-expressions",
        0
       ],
       [
        "pnpm check:agent-test-spelling",
        0
       ],
       [
        "pnpm check:bash32-floor",
        0
       ],
       [
        "pnpm check:ci-filter-parity",
        0
       ],
       [
        "pnpm check:cli-command-ids",
        0
       ],
       [
        "pnpm check:closing-target-claim",
        0
       ],
       [
        "pnpm check:commit-card-trailers",
        0
       ],
       [
        "pnpm check:cross-package-test-inputs",
        0
       ],
       [
        "pnpm check:doc-authoring",
        0
       ],
       [
        "pnpm check:driver-memory-census",
        0
       ],
       [
        "pnpm check:entry-guard",
        0
       ],
       [
        "pnpm check:gitlink-declared",
        0
       ],
       [
        "pnpm check:issue-citations",
        0
       ],
       [
        "pnpm check:nul-bytes",
        0
       ],
       [
        "pnpm check:parse-guard",
        0
       ],
       [
        "pnpm check:partof-closing-keyword",
        0
       ],
       [
        "pnpm check:platform-checklist",
        0
       ],
       [
        "pnpm check:pm-governed-merges",
        0
       ],
       [
        "pnpm check:pm-half-states",
        0
       ],
       [
        "pnpm check:pm-post-stamped",
        0
       ],
       [
        "pnpm check:pm-record-recognisers",
        0
       ],
       [
        "pnpm check:pm-skill-id-lint",
        0
       ],
       [
        "pnpm check:pm-skill-ratchet",
        0
       ],
       [
        "pnpm check:pnpm-filter-targets",
        0
       ],
       [
        "pnpm check:pnpm-flag-spellings",
        0
       ],
       [
        "pnpm check:ratchet-remedy-authority",
        0
       ],
       [
        "pnpm check:refd-timer-probe",
        0
       ],
       [
        "pnpm check:scripts-symbol-anchors",
        0
       ],
       [
        "pnpm check:single-claim-paths",
        0
       ],
       [
        "pnpm check:skill-frame-sync",
        0
       ],
       [
        "pnpm check:watch-hint-literal",
        0
       ],
       [
        "pnpm check:pm-dispatch-gates",
        0
       ]
      ]
     },
     "line_budget": {
      "references/project-forms.md": {
       "before": 54,
       "after": 54,
       "net": 0
      },
      "references/seat-lifecycle.md": {
       "before": 96,
       "after": 96,
       "net": 0
      },
      "references/seat-post-protocol.md": {
       "before": 88,
       "after": 88,
       "net": 0
      },
      "references/landing-operations.md": {
       "before": 101,
       "after": 101,
       "net": 0
      },
      "max_line_bytes": 120
     },
     "deviations": [
      "landing-operations.md L80 Request: main-red -> Notify: main-red (outside the claim surface; the old spelling became off-table)",
      "scripts/pm/mailbox-open.mjs header and mailbox body text 'seven doorbell keys' -> 'doorbell keys' + names --mailbox-keys (outside the claim surface; text became false)",
      "full key templates moved from rules text to MAILBOX_KEYS in record-recognisers.mjs, printed by new --mailbox-keys",
      "wanted 3 (epic seat mailboxes) not built: seatKey refuses epic: spellings and fleet-roster has no epic rows; filed as out_of_scope_findings[0]"
     ],
     "files_changed": [
      ".claude/skills/pm-dispatch/references/project-forms.md",
      ".claude/skills/pm-dispatch/references/seat-lifecycle.md",
      ".claude/skills/pm-dispatch/references/seat-post-protocol.md",
      ".claude/skills/pm-dispatch/references/landing-operations.md",
      "scripts/pm/record-recognisers.mjs",
      "scripts/pm/check-half-states.mjs",
      "scripts/pm/mailbox-open.mjs"
     ],
     "commits": [
      "310f697986",
      "bb642cc228",
      "d1975d8a81",
      "901e99ed13"
     ],
     "mcp_calls": 0,
     "api_writes": {
      "relay_dispatches": 1,
      "platform_writes": [
       "POST pulls (#28716, draft)",
       "POST issues/28716/labels skip-changeset"
      ],
      "comments": 1,
      "git_pushes": "branch pushes only"
     },
     "out_of_scope_findings": [
      "epic seats cannot be rung: mailbox-open.mjs seatKey refuses epic:#N#K spellings and fleet-roster.mjs has no epic rows; needs seatKey + roster + one rules line (card wanted 3)",
      "frozen dispatch-gates.data.mjs (~L505) and dispatch-gates.self-test.mjs (~L7573) comments still say 'seven' doorbell keys/templates; comment-only, left for the freeze",
      "live off-table mailbox lines today on #28284 #28379 #28481 #28646 #28672 (old 5-field seat-online, prose after a key, free-form triage question, a ruling line over 200 bytes); H72 lists them about a day after landing"
     ],
     "seat_decides": [
      "Fixes #28675 vs Part of #28675 given wanted 3 is a finding",
      "file the epic-mailbox finding"
     ]
    }
  4. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Item ③ (epic seats get mailboxes) is carried by #28718, filed from the dev report 6559765410 (open_questions 1): it needs mailbox-open.mjs seatKey and fleet-roster.mjs epic rows, outside this claim. PR #28716 keeps Fixes #28675 for items ①②④⑤. The H72 transition noise (open_questions 2: pre-landing 5-field seat-online lines read off-table for about a day) is accepted as a report-only reading.

  5. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    ACCEPT → PR #28716 comment 6560134588 (head 37661b885bac64fd4d09ed0c922d7504fc0d1577; contract review PASS 6560123525). Waiting on an authorised approver and on PR #28687 (stacked base); the PR stays draft with needs-user-decision until then.

  6. objectstack-fleet commented on Nov 1, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · marchtian · session_017ihL2g7RyXa8ErM6GAkHyc

    Landed 2026-11-01T16:31Z: PR #28716 merged as db357f6da9 (merge queue, enqueued by os-zhuang). Contract review PASS 6560123525 (+ Regen-provenance 6560344780 for the base sync), seat ACCEPT 6560134588. Item ③ (epic seats get mailboxes) is carried by #28718, now unblocked.

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:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions