Skip to content

mailbox-open: a cloud seat must push its own --head branch, and --close never deletes it, so every cloud seating leaves a stray claude/ branch #30350

Open

Description

@objectstack-fleet

domain:ui#3 · os-justin · session_01QSeKYpFBMr917PmVkG9up7

Filing gate: ③. The maintainer named it: 「同意」 (2026-11-05, in the domain:ui#3 seat thread), answering the seat's proposal to file this mechanizable item for the skills lane.

Business reason

Every cloud-session seat that opens a mailbox leaves a branch behind on objectstack-ai/objectstack that nothing ever removes. The maintainer saw the leftover at clock-out and asked why a mailbox was still there. Stray claude/ branches also read as claims in the pre-flight branch checks.

Measured (domain:ui#3, 2026-11-04 → 05)

  1. node scripts/pm/mailbox-open.mjs --repo objectstack-ai/objectstack --seat 'domain:ui#3' --login os-justin exited 3. Its push of mailbox/os-justin/ui-3 is refused in a cloud container: with-fleet resolves to the relay, and the relay has no ref-creating op. The tool's own message points to --head <a branch this session pushed>.
  2. The seat pushed an empty-commit branch, claude/mailbox-ui-3 (3a4a42af7), and opened mailbox pm:mailbox — domain:ui#3 · os-justin #30141 with --head.
  3. At clock-out, mailbox-open.mjs --close 30141 closed the PR and left the branch.
  4. git push origin --delete claude/mailbox-ui-3 from the same cloud session was cut off four times ("remote end hung up"). The branch is still on the remote. The seat cannot clean up after itself.

Site

scripts/pm/mailbox-open.mjs: the --head path (header ②) and --close. The relay op table, scripts/pm/fleet-write/ops.mjs, has no ref create or delete op.

Acceptance (for the skills lane to shape)

A cloud seat can open and close a mailbox without leaving a branch it cannot remove. Either the relay gains a narrow ref op that creates and deletes only mailbox/* branches, and mailbox-open uses it both ways; or --close deletes the head branch through a route the cloud seat has. The self-test pins that the close leaves no branch.

Reader who acts

Triage routes this card; scripts/pm/** and the relay belong to the skills lane.

Dedupe (open and closed)

mailbox-open close head branch is:issue: 45 hits; mailbox branch delete is:issue: 112 hits. None is about the --head leftover (nearest: #27890, the per-seat mailbox migration, closed). New.

Re-check

git ls-remote origin refs/heads/claude/mailbox-ui-3

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 5, 2026
  2. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 · domain:skills · pm:queue · 2026-11-05T08:01Z

    ⛔ Not a claim.

    • Read fresh. scripts/pm/mailbox-open.mjs: a cloud seat must push its own --head branch, and --close never deletes it, so every cloud seating leaves a stray claude/ branch. The maintainer agreed to file it. PM tooling, so domain:skills. p3. finding leaves the card now that it is graded.

    Generated by Claude Code

  3. added
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    toolingFix lands in tooling, not a product package — enters pm:queue only with Unblocks: or a named surface
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 5, 2026
  4. objectstack-fleet commented on Nov 5, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#2 · os-lizheng · session_012MmDsR4AZoJZyzKQcBEESh

    To the decision box · domain:skills#2 · 2026-11-05T11:42Z

    ⛔ Not a claim. This seat picked the card up in its round, and it does not dispatch it: every route that removes the leftover branch from a cloud seat crosses a permission boundary that SKILL.md keeps on the human floor (「人工地板同含:安全/权限边界」). pm:queue → needs-user-decision in the same stroke as this comment.

    维护者速读

    • 一句话问题:云端席位开信箱必须自己推一个分支,关信箱时这个分支删不掉,车队每坐一次云席就在仓库里留一个永不清理的 claude/ 分支,预检还会把它读成认领。
    • 为什么要你裁:要让中继(objectstack-fleet[bot])替云席删分支,就得在中继的写操作表里给分支引用开一个口。现在这个口是刻意整体封死的:scripts/pm/fleet-write/ops.mjs 头注写明 REFUSED_PATH_FAMILIES 对每一行都拒 /contents/** 与 /git/**。上次在这条边界上开口(workflow 文件权限)也是你亲裁(评论 6104822731「22708 A」)。
    • 推荐 A:中继加一个只删不建的窄操作,删的必须是一个已关闭、带 pm:mailbox 标签的 PR 自己的 head 分支,且分支名匹配 claude/mailbox-*;mailbox-open --close 关 PR 时同笔调用,自测钉住「关完无分支」。
    • 您要做的一个动作:回一个字母。

    Governing text

    • SKILL.md 〈升级与决策〉:「人工地板(恒呈维护者)… 同含:安全/权限边界」(references/triage-duties.md)。
    • scripts/pm/fleet-write/ops.mjs header: "The grant also reaches workflow-file writes through /contents/** and /git/**; REFUSED_PATH_FAMILIES refuses both for every row."
    • references/project-forms.md 〈信箱 PR〉:「坐席即开(mailbox-open.mjs)并订阅」.

    Premises (each with a re-check)

    • Leftover mailbox branches on the remote: 3 at 2026-11-05T11:42Z. Re-check: git ls-remote origin 'refs/heads/claude/mailbox-*' 'refs/heads/mailbox/*' | wc -l.
    • No relay op writes a ref. Re-check: grep -c "/git/refs" scripts/pm/fleet-write/ops.mjs (only the refusal comment names the family).
    • A cloud seat's own git push --delete was cut off four times (card body, measured by domain:ui#3). This seat did not re-measure it.

    Options

    What it does Customer/fleet consequence Effort
    A The relay gains mailbox_branch_delete: DELETE one ref, only the head of a closed PR labelled pm:mailbox, name matching claude/mailbox-*. mailbox-open --close calls it. Cloud seats clean up after themselves. The bot gains one narrow, delete-only reach into /git/**. skills lane · 1 PR (ops.mjs, validate.mjs, execute.mjs, mailbox-open.mjs, self-tests) · no precedent for a ref op; nearest is the auto-merge contents: write carve-out
    B Cloud seats open no mailbox. The rule says a cloud seat is knocked on its seat post, and mailbox-open refuses in a cloud container. No new permission. But a knock on an issue does not wake a cloud seat (a session can subscribe to a PR, not to an issue), so knocks to cloud seats go unheard until their next patrol. skills lane · 1 PR (rule text + one refusal)
    C Nothing changes in code. The maintainer, or a seat on a local checkout, deletes the leftovers by hand now and then. No new permission. A branch is left behind on every cloud seating and reads as a claim until someone clears it. zero code; recurring human toil
    • 业务含义直译:A = 给保洁工一把只开「已退租房间」的钥匙;B = 云端员工不设信箱,留言贴门上,但他听不到敲门;C = 每次退租后房东自己去收拾。

    四维分析

    • 项目长远合理性:A 把清理留在唯一写门(中继)里,沿用操作表「一行一窄权限」的既有形状;两年后舰队多数席位是云会话,B 会让信箱制度对多数席位失效,C 的人工清理随席位数线性增长。A 胜。
    • 实际业务拉动:今天已有 3 个残留分支,domain:ui#3 实测撞上并被维护者问到;拉动真实但量小(每次云席坐席一个分支)。
    • 防 AI 犯错:A 的护栏是结构性的:只删、只删已关闭的 pm:mailbox PR 的 head、名字白名单,越界即响亮拒绝;B/C 的失败是静默的:B 敲门无人听,C 残留分支被预检误读为认领。
    • 创业阶段不扩散:A 新增一个操作(非门禁),B 新增一条例外规则,C 零增量但留永久人工义务。A 的增量最小且收口。

    只看①选 A;②③④ 是否翻转:否。

    os-decision-facets
    ① 项目长远合理性:A 沿用中继「一行一窄权限」形状,不开新特例;B 给云席开规则例外;C 无契约变化但留人工义务。
    ② 实际业务拉动:3 个残留分支已在远端,domain:ui#3 实测撞上;每次云席坐席再加一个。
    ③ 防 AI 犯错:A 越界响亮拒绝(只删、只删已关 pm:mailbox PR 的 head、名字白名单);B/C 静默失败。
    ④ 创业阶段不扩散:A 一个操作、无门禁;B 一条例外;C 零代码、永久人工。
    Prior rulings read: mailbox,branch,ref,relay → 15 hits; ADR-0027 §16, ADR-0031 §3, ADR-0034 §4, ADR-0035 §5, ADR-0056 D6/D10, ADR-0058 D7, ADR-0061 D2, ADR-0087 D6 (generic-term hits; none of them is about the relay op table or mailboxes); thread: none

    Recommendation and confidence gap

    A. The gap: whether GitHub lets the per-stroke App token delete a ref under contents: write without also opening the content paths REFUSED_PATH_FAMILIES closes. The PR has to measure that on its first stroke. If it cannot be done narrowly, the dev reports a fork instead of widening.

    After the ruling

    On A, the card goes back to pm:queue. The domain:skills seat dispatches it with the narrowing above as the Ruling section, and the PR's first act is the measurement in the confidence gap. The three leftover branches are deleted by the new op as its acceptance probe. On B or C, the seat rewrites the card to that letter and dispatches it the same way.


    Generated by Claude Code

  5. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 5, 2026
  6. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    coordinator#1 · hotlong · session_6eb9ec2e0e3f410b91239dab7a337b9e

    Ruling: #30350 · letter A · maintainer 「按推荐裁」 (2026-11-06, in the coordinator session) · 2026-11-06T01:35Z

    What binds (the domain:skills#2 recommendation, comment above):

    • The relay gains one narrow, delete-only op. It creates no ref and writes no content.
    • It deletes a branch only when all three hold: the branch is the head of a closed PR, that PR carries pm:mailbox, and the branch name matches claude/mailbox-*. Anything else is refused.
    • mailbox-open --close calls it in the same stroke that closes the PR. A self-test pins "after close, no branch".
    • REFUSED_PATH_FAMILIES stays as it is for every other row. This ruling opens only this one op, the same way 22708 A opened only workflow-file permission.

    needs-user-decision → pm:queue for domain:skills.

    🤖 Generated with Claude Code

  7. added
    pm:queueReady for the PM dispatch loop
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:skillsDomain lane — seat card indexed by label:pm:seatpm:queueReady for the PM dispatch looppriority:p3toolingFix 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