Skip to content

pm-dispatch(mailbox): a stale-work knock — triage sweeps claimed cards and open PRs idle 3 h, knocks Request: progress to the owning seat's mailbox, and the seat answers Notify: progress to triage's #29754

Closed

Description

@objectstack-fleet

triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

Filing gate ③: a task the maintainer directed. In the triage session, 2026-11-03, the maintainer said, verbatim:

  • 「排查一下 3小时没有更新的pr,敲门督促车道」
  • 「排查一下已认领, 3小时没有更新的issue,敲门督促车道」
  • 「你催完之后,你能有要求,对方会回复吗?对方知道回复到哪里嘛?」

⛔ Not a claim. Reader who acts: domain:skills.

What happened (measured, 2026-11-03T03:05–03:20Z)

Wanted (one PR)

  1. Two mailbox keys (MAILBOX_KEYS in scripts/pm/record-recognisers.mjs, plus project-forms.md), each with a self-test row:
    • Request: progress · #n · idle since TIME: triage → the claiming seat, one per stale item. "Item" means a claimed card, or an open PR whose head and comments are older than 3 h.
    • Notify: progress · #n · record ID: the seat → triage. Its record is a comment on #n giving the next act and an ETA, or the §C park with Blocked-by: / Resume-from:, or a release.
  2. project-forms.md L47. 「⛔ 不敲:催」 keeps meaning "never a second nag on the same item". The first Request: progress for an item is the knock. Escalation stays as it is: no answer within one triage round ⇒ the item goes on triage's round record as unanswered, and the seat is treated as possibly down.
  3. lanes/triage.md, a round step. Every round, sweep pm:dispatched cards and open non-mailbox PRs idle for 3 h or more, and skip those parked with a Blocked-by: line or waiting on a decision. Knock each unanswered owner once, read the answers next round, and list unanswered items.
    • A seat that answers nothing for two rounds: its claims fall under the existing "接手无主阻塞项" (orphan takeover) path for a sibling seat. ⛔ Triage does not release them itself.
  4. The per-seat cap (≤5 per round) applies. Several stale items for one seat go in one knock line per item, up to the cap.

⛔ No new gate and no new label.


Generated by Claude Code

Activity

  1. added
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Nov 3, 2026
  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Amendment 1 · repeat interval: one hour, not never · 2026-11-03T04:11Z

    ⛔ Not a claim. The maintainer's words, verbatim (the triage session, 2026-11-03):

    • 「技能规定不能用信箱催, 这个合理吗?信箱的价值是什么」
    • 「同一项一小时内不准敲第二次是否更合理」

    This replaces Wanted item 2. project-forms.md L47's 「⛔ 不敲:催」 becomes a rate rule, not a ban.

    • One knock per item per hour. At most one Request: progress for the same item within 60 min of the last. That matches the hourly seat patrol and the hourly triage round.
    • An answer resets the clock.
      • An item whose seat answered with an ETA is not knocked again until that ETA passes.
      • An item parked with Blocked-by: / Resume-from: (§C), or waiting on a decision card, is not knocked at all.
    • Escalation. After two unanswered knocks (about 2 h), the item goes on triage's round record as unanswered. Its seat is treated as possibly down, and the claims fall under the existing "接手无主阻塞项" path for a sibling seat. ⛔ Triage does not release them itself.
    • The per-seat cap stays at ≤5 per round, and knocks count toward the write pace.
    • Why not "never twice": one missed knock (a seat between patrols, or a busy session) would leave the item stuck until the maintainer notices. On 2026-11-03 that is what the card-comment nudges did.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: pm:queue → pm:blocked · 2026-11-03T04:12Z

    ⛔ Not a claim.

    Blocked-by: #29775


    Generated by Claude Code

  4. added
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: unblocked · p2 kept · pm:blocked → pm:queue · 2026-11-03T04:32Z

    ⛔ Not a claim. #29775 is ruled A (「同意29775 A」): build this card as amended by amendment 1, with one knock per item per hour.


    Generated by Claude Code

  6. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 3, 2026
  7. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Amendment 2 · how "idle" is read, and an off-shift seat's items go to a sibling · 2026-11-03T04:58Z

    ⛔ Not a claim. The maintainer's words, verbatim (the triage session, 2026-11-03):

    • 「同意:下班席位的卡交给兄弟席」
    • 「以上是否需要修改分诊技能」

    Ruling A on #29775 stands. This adds two things to the same PR (lanes/triage.md, project-forms.md, seat-lifecycle.md).

    1. Idle is read from progress, not from updated_at. An item's last progress is the latest of:
      • its head commit, for a PR;
      • any comment not posted by triage;
      • a label change by its seat.
        Triage's own nudge comment bumps updated_at and hides the item from a naive "not updated in 3 h" filter. Measured 2026-11-03: four PRs read "updated" only because of triage's nudges.
    2. An off-shift seat's items go to a sibling seat in the same lane.
      • When this applies: a seat signs off (Notify: seat-offline), or two progress knocks go unanswered.
      • What happens: its claimed cards and open PRs go to an online sibling in the same lane. The sibling claims them with a Resume-from: line, citing the off-shift seat's brief.
      • Triage's part: in its next round, triage knocks the sibling once with Request: progress · #n · idle since TIME, for each such item still unclaimed. ⛔ Triage never claims, and never releases a claim itself.
      • Exceptions:
        • Items waiting on a decision card wait for the letter first, then go to the sibling.
        • Items with no online sibling in the lane are listed on the round record under "awaiting a seat".
        • Security items stay with security#1's seat post.

    Generated by Claude Code

  8. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH

    Claim: PM loop round 4 · 2026-11-03T09:11Z
    Session: session_01WGufzf7EDaUFBmJTyLuKbj (os-dev card thread "Add mailbox progress knock keys"; dispatched by session_01WGufzhd2Ad9ANGTyAMW7pH)
    Account: os-support-ai
    Branch: claude/project-thread-6q7l00
    Worktree: objectstack-issue-29754
    Domain: domain:skills
    Seat: domain:skills#3
    File surface: scripts/pm/record-recognisers.mjs (MAILBOX_KEYS + self-test rows), .claude/skills/pm-dispatch/references/project-forms.md 〈信箱 PR〉, references/lanes/triage.md, references/seat-lifecycle.md; ceiling raises only as ruling 6595514258 orders, by measured delta; no changeset (skip-changeset)
    Container & model: M, mode:thread, model: CONTRACT_REVIEW_TIER — reason: governed pm rules text plus the mailbox recogniser (per-card call; --tier: no path mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6595840476
    Premise: holds — #29775 ruled A (6595514258), amendments 1 (6595244387) and 2 (6595840476) in force; unblocked by triage 6595519090
    Serial constraints cleared: no open PR or in-flight claim touches the four files (measured on origin/main eb833b5)

  9. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 3, 2026
  10. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzf7EDaUFBmJTyLuKbj
    os-dev-report

    Stamp: 2026-11-03T09:40Z

    {
      "issue": 29754,
      "status": "done",
      "branch": "claude/project-thread-6q7l00",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29887",
      "head": "32a1b5f570639071b83bd313ae88ac04e8163c3a",
      "session": "session_01WGufzf7EDaUFBmJTyLuKbj",
      "premise_still_valid": true,
      "summary": "Two mailbox keys (request:progress `Request: progress · #n · idle since TIME`, notify:progress `Notify: progress · #n · record ID`) added to MAILBOX_KEYS with field readers and a self-test row each (roster pin 15 to 17). project-forms.md 〈信箱 PR〉 names the pair and turns 不敲:催 into the 60-min rate with the ETA hold and the parked/decision-card exclusions; lanes/triage.md carries the round step (sweep, idle read off progress never updated_at, knock, next-round read, two silent rounds = seat down, items to an online sibling, triage knocks it once and never releases); seat-lifecycle.md sends an off-shift seat's in-flight to the online sibling claimed with Resume-from citing the brief, with the decision-card / no-sibling (待席) / security#1 exceptions. Ceilings raised by the measured deltas under ruling record 6595514258 and amendments 6595244387, 6595840476.",
      "tests": "node scripts/pm/record-recognisers.mjs --self-test on 32a1b5f5: ✓ 362 cases pass (360 before the two ⭐ progress rows). --mailbox-keys prints 17 keys with both progress templates. No ablation: readers and rules text added, no existing key's tested behaviour changed.",
      "gates": "dispatch-gates --commands --repo objectstack-ai/objectstack on 32a1b5f5 (merge base 592845b09): 38 derived; all 38 run serially, exit codes captured before any pipe; --ran: 38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN, exit 0; every command exit 0 (incl. check:pm-record-recognisers, check:pm-skill-ratchet, check:pm-skill-id-lint, check:pm-dispatch-gates, check:pm-governed-merges, check:skill-frame-sync, check:ratchet-remedy-authority, check:scripts-symbol-anchors, check:nul-bytes, check:doc-formula-expressions after turbo build formula+lint under os-verify-lock VERDICT command-exit 0). CI check-runs on PR 29887: in_progress at report time; the seat reads them at ACCEPT.",
      "line_budget": "project-forms.md 56 to 58 (+2, ceiling 58); lanes/triage.md 17 to 20 (+3, ceiling 20); seat-lifecycle.md 96 to 98 (+2, ceiling 98); every edited line at most 120 bytes; three lines rewritten in place (the 不敲 line, the sign-off line); map total +7; no CROSS_FILE_MOVES touched. Ruling of record quoted in each CEILINGS row comment and in the PR body table.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "6 — read-only GitHub MCP: issue_read x5 (29754 get/comments x2, 29775 get/comments), pull_request_read x1 (29887 get, the body read-back); no MCP write tool",
      "api_writes": "2 — relay fleet-write pr_create (run 41612740274, PR 29887, body landed identical 14243 bytes, labels skip-changeset, assignees none) and this os-dev-report comment via post-stamped.mjs; plus 2 git pushes (not REST)",
      "deviations": [
        "The relay pr_create envelope's --session flag was typed with one wrong character (…JTyLyKbj for …JTyLuKbj); the PR body, the commit trailer and this report carry the correct session id. Nothing to correct on the PR; noted for the seat's run-log read.",
        "origin/main moved again after the merge (592845b0 to 74fd4bf6) while the PR opened; no pm-dispatch or gate-script file in that range was re-measured — the seat re-reads at landing."
      ],
      "files_changed": [
        ".claude/skills/pm-dispatch/references/project-forms.md",
        ".claude/skills/pm-dispatch/references/lanes/triage.md",
        ".claude/skills/pm-dispatch/references/seat-lifecycle.md",
        "scripts/pm/record-recognisers.mjs",
        "scripts/pm/check-skill-line-ratchet.mjs"
      ],
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": []
    }
  11. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · os-support-ai · session_01WGufzhd2Ad9ANGTyAMW7pH

    ACCEPT → PR #29887 comment 6600793224 · Tier S, readied and auto-merge armed on the at-tier PASS (r1 6600776295).

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

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions