PM 统一控制入口
scripts/pm-orchestrate.sh;本页适配multi-agent-orchestrationv2.28.0。
目录
- 模式解析
- 命令
- Supervised 收口顺序
- PR 先行与本地集成
- 安全边界
1. 模式解析
脚本读取 <worktree>/.claude/agent-sessions/<session>/METADATA.json:
| METADATA | 模式 | 控制面 |
|---|---|---|
有 supervised.dispatch_id |
orca_supervised |
Dispatch/Delivery/worker-read |
仅有 terminal_handle |
orca_terminal |
terminal send/read/wait |
| 两者都无 | tmux |
send-keys/capture-pane |
不要手工覆盖模式;缺 METADATA 时 fail-loud。
1.1 手动 register 的路由恢复(Task-092)
orca-supervised-register.sh 在 worker-start 和 Dispatch 绑定完成后,会从精确 worktree id/path + terminal handle 反查唯一 Session Context,并原子补写完整的 .session.orca.supervised 合同。成功输出:
ORCAREG_METADATA_BIND=ok如果 worktree 查询失败、Session Context 缺失/不唯一、terminal handle 不匹配、目标是符号链接或写入失败,脚本输出 ORCAREG_METADATA_BIND=manual-required,但不重启已经活跃的 worker。此时 PM:
- 用
orca worktree show --worktree id:<worktree_id> --json核对返回的 id/path 与 register 回执完全一致; - 在该精确 path 下查找唯一
.claude/agent-sessions/*/METADATA.json,并核对.session.orca.terminal_handle; - 仅在身份唯一时,按 register 的
ORCAREG_RUN_ID/TASK_ID/DISPATCH_ID/COORDINATOR_HANDLE/DISPATCH_BIND补写与正常 spawn 相同的 supervised 合同; - 立即用
pm-orchestrate show复验路由。身份仍不唯一时保留现场并升级人工处理,不猜 session、不重试 spawn。
在 metadata 尚未恢复时,只能把 orca terminal show --terminal <handle> --json 的 preview 与 lastOutputAt 作为临时活性证据;它们不能证明业务完成,也不能替代 Dispatch/Delivery 生命周期。
2. 命令
# 每个 Wave 一次;输出 .result.run.id
pm-orchestrate.sh run-create --objective "Wave objective" --from "$PM_TERMINAL"
# 三种模式通用
pm-orchestrate.sh send --worktree "$WT" --session "$S" --text "..."
pm-orchestrate.sh read --worktree "$WT" --session "$S" --lines 50
pm-orchestrate.sh read --worktree "$WT" --session "$S" --lines 5000 --cursor 0
pm-orchestrate.sh peek --worktree "$WT" --session "$S"
pm-orchestrate.sh wait --worktree "$WT" --session "$S" --timeout 900
# supervised 专用
pm-orchestrate.sh inbox --worktree "$WT" --session "$S" \
[--thread-id "task.TASK-123" --correlation-id "TASK-123.review.1"]
pm-orchestrate.sh show --worktree "$WT" --session "$S"
pm-orchestrate.sh reply --worktree "$WT" --session "$S" --message-id "$MID" --text "..." \
[--retry-request "<UUID Orca reported for this unknown-outcome reply>"]
pm-orchestrate.sh release --worktree "$WT" --session "$S"
pm-orchestrate.sh retain --worktree "$WT" --session "$S"
pm-orchestrate.sh ack --worktree "$WT" --session "$S" --delivery-id "$DID"
pm-orchestrate.sh settle --worktree "$WT" --session "$S" --reason "..." [--force] [--destroy]
pm-orchestrate.sh reauthorize --worktree "$WT" --session "$S" \
--allow-cmd "make test" --resume-text "断点续接说明" [--task-id ID]supervised send 是结构化 inbox mail,不是 terminal prompt injection;read 输出 Orca JSON 并保留 source/cursor/fallbackReason,便于 PM 判断精确 transcript 与 terminal fallback。
2.1 跨 session 消息合同
普通兼容性 send 保持原参数不变;需要跨 PM、Worker、reviewer 追踪重要请求时,显式启用版本化合同:
pm-orchestrate.sh send --worktree "$WT" --session "$S" \
--message-contract \
--subject "Review frozen head" \
--message-type decision_gate \
--priority high \
--thread-id "task.TASK-123" \
--correlation-id "TASK-123.review.1" \
--expected-action "审查冻结 head,并用 reply 返回 verdict 与证据引用" \
--evidence-ref "git:0123456789abcdef" \
--evidence-ref "path:skills/example/SKILL.md" \
--text "请只审查该冻结提交,不修改实现。"合同复用 Orca 原生 send/check/reply/ask,不创建第二套聊天系统。路由始终是 metadata 中的精确 dispatch:<id>;发送前通过只读 worker-show 证明该 Dispatch 当前属于同一 Run、Task 和 worker terminal,且仍是 live authoritative attempt,再把这些身份与 coordinator handle、业务 thread、correlation、expected action 和 evidence refs 写进受控 payload。原生 send --thread-id 使用 correlation,业务 thread 只写入 payload;这样当前 Orca 原生 reply 即使只继承顶层 Run/from/to/thread、未复制 payload,接收方仍可用原生 thread 精确关联本次请求。当前 CLI 的 raw --payload 与结构化 --task-id/--dispatch-id 互斥,因此不重复传后两项,身份权威来自前置 worker-show,payload 只承载冻结副本。expected_action 只是任务说明,authority=informational_only,不会扩大 Shell、安装、Git 或发布权限。
新 send/reply 必须省略 --retry-request。只有 Orca 明确报告 mutation outcome unknown 并给出 orchestrationRequestId UUID 时,先按其 request-show 指引只读核查,再把同一 UUID 与原命令其余参数原样用于一次精确恢复。该 UUID 是 Orca transport mutation identity,不是自定义业务幂等键,也不进入 message-contract payload 或业务请求摘要;业务去重继续使用 thread/correlation。不可自行编造 TASK-123... 一类 retry 值。
| 状态 | 最小证据 | 明确不代表 |
|---|---|---|
durably_enqueued |
send 返回 .ok=true;Dispatch relay 回执还须精确匹配 destination=worker、dispatchId 与 messageId。脚本 receipt 同时绑定 sender、thread、correlation、完整业务请求的 SHA-256,以及仅在未知结果恢复时出现的 Orca retry UUID |
已可见、已消费、已回复、已执行、已完成 |
delivered_visible |
inbox 的只读 check --peek 快照包含精确归属的结构化 message,或在双过滤下包含精确关联的原生无 payload message |
已消费、执行过 reply 或会采取行动 |
consumed |
非 peek check 交付的 Delivery 包含该 message |
已回复、已执行或业务完成;整批处理后仍需显式 ack |
replied |
reply --id <message-id> 或 ask 恢复返回成功回执 |
请求动作已经开始或完成 |
action_started |
接收方返回与 correlation/thread 对齐的进度及首个真实工作证据 | 业务完成 |
business_completed |
任务合同要求的真实产物、测试、review/worker_done 与结算证据全部满足 |
不能由 send、peek、heartbeat 或一段自报代替 |
合同字段规则:
message-type仅接受 coordinator 可发送的status|dispatch|merge_ready|handoff|decision_gate|question;拒绝伪造worker_done、heartbeat或未知类型。priority仅接受normal|high|urgent;normal只留在合同 payload,避免依赖原生 CLI 的缺省值漂移。thread-id和correlation-id必填并使用稳定安全标识;前者是业务分组,保存在 payload,后者同时作为 Orca 原生 thread。同一业务请求恢复沿用 correlation。--retry-request只接受 Orca 对原 unknown-outcome mutation 回传的 UUID;首次发送省略。Session Context 只保存该 UUID、thread、correlation 和不含 transport retry 字段的完整业务请求 SHA-256,不复制正文;同一 UUID 改变 body、subject、路由或 payload 会在首次 Orca 调用前拒绝,完全相同的业务请求才交给 Orca 原生恢复。- evidence refs 仅接受
git:|path:|pr:|test:|message:|task:|report:;path:必须是无..穿越的仓库相对路径。 - body、subject、显式或 metadata sender、worker handle、thread、correlation、retry request、expected action 或 evidence 命中密钥、Token、密码、Authorization、私钥等模式时,在第一次 Orca 调用前拒绝。无 supervised Dispatch、缺身份、Run/Task/Dispatch/worker 关系不符、非 live 发送目标、runtime 漂移或 stale sender 同样失败关闭。
inbox始终执行check --peek,只验证当前 coordinator/Run/runtime,不做run-use、不写 metadata、不 ack。顶层 Run 必须与 metadata 精确相等,sender/recipient 必须分别等于worker-show复验的 worker handle 和当前 coordinator;snake_case/camelCase 以及原生 from/to/thread 等所有已出现别名都必须彼此一致并满足期望,不能用一个正确字段遮住冲突字段。结构化入站消息还须由 payload 内成对的 Task+Dispatch 身份证明归属;payload 若声明当前消息的sender、recipient或message.type,必须分别与当前 worker、kind=dispatch/当前 Dispatch 和顶层消息类型一致,不把这些字段解释成原请求快照。提供 thread+correlation 双过滤时,同时要求 payload 业务 thread、payload correlation 和原生 correlation thread 精确匹配。- 当前 Orca 原生
reply不复制 Task/Dispatch payload。只有显式同时传入业务 thread 与 correlation 时,inbox才允许一条受限的原生 thread bridge:消息不得携带 Task/Dispatch 或 payload correlation 别名,顶层 Run、worker sender、coordinator recipient 与原生 thread 必须分别精确匹配。receipt 以match_basis=native_thread_correlation标识这种关联,并把业务 thread 留为null,避免声称消息本身携带了该字段。它只证明与该请求关联的消息可见,不证明接收方确实执行过reply;无双过滤时,这类无 provenance 消息保持排除。零匹配输出none_visible;有精确匹配只说明delivered_visible且仍未消费。
非 Orca PM 可对控制命令传 --from <本轮PM终端>;显式参数优先,缺省使用当前 Session Context 已记录的 coordinator。已有绑定不被环境覆盖;仅没有既有 session 绑定的新 Run 才兼容宿主 ORCA_TERMINAL_HANDLE,且仍需全部验证。禁止以 terminal current/UI 焦点自动挑选 sender。
发送、等待、reply、ack 与资源结算等变更型控制命令先验证终端精确 handle、connected/writable、非 orphaned/无 exitCause 与 runtime;以 run-use --id ... --from ... 绑定后再 run-current --from ... 读回精确 Run/coordinator 并复查。metadata 保存 .session.orca.runtime_id;旧记录缺字段时只可正向重验当前绑定后回填,历史连续性仍 NOT_VERIFIED,非空 runtime 漂移不可被 --from 绕过。inbox/read/peek/show/reconcile/pr-audit 保持只读;其中 inbox 只用 run-current 验证既有绑定,零 rebind/metadata 写入。
官方 argv 各不相同:send/reply/Run 命令带 --from;wait/ack 的 check 带 --terminal,不传陈旧 --run;worker-list 显式 --run。release/retain 仅接受 --dispatch,不注入不存在的 --from,但仍做相同 sender/Run 前置核验。reply 在 mutation 前先以 coordinator consuming check 重放当前未 ack Delivery;当前 Orca question 行的顶层路由是 dispatch:<dispatch> → run:<run>,thread 等于 question message ID,Task/Dispatch 身份位于 JSON-string payload。wrapper 必须按这一真实形状验证所有出现的 aliases、payload 与 worker-show 绑定,目标 ID 才能作为当前 Delivery 中精确 Run/Task/Dispatch 的唯一 question;worker terminal 在 post-reply 的 question.asker_handle 再次核对。该预检不 ack,已不在当前批次或同 Run 另一 Dispatch 的 question 均拒绝。reply --retry-request 仅用于同一未知结果的精确恢复:同 question、body、sender 与 Orca UUID 原样重放;已确认成功后不应主动再答一次。当前 Orca 对同一 question+answer 的重复 reply 返回原 reply message 并标记 duplicate,wrapper 还会逐项核对所有出现的 question/reply aliases、question 的 Run/Dispatch/asker/answer 与 reply message 的 run:<run> sender、dispatch:<dispatch> recipient、question thread 和 body;reply message ID 必须是不同于原 question 的独立非空 ID。只有全部一致才输出 reply_committed 或 reply_existing_same_answer,显式 null alias、复用 question ID、不同 answer 或路由漂移均失败关闭。reply receipt 写入经双重验证的 Task/Dispatch/worker,只证明回复已持久化,不证明 Worker 消费或执行。CLI 合同变化时先读当前 --help,不用宽松 fake 接受未知参数。
Orca terminal-managed read 同样透传 --cursor。alternate-screen TUI 首次从 0 读取并保存响应里的 nextCursor;后续按 cursor 增量读取,避免默认 tail 只剩 spinner。wait 的 tui-idle 只表示当前可交互/空闲,不是业务终态。
terminal/tmux 的超长 prompt(>500 字或含反引号、$、|)会写入 session context 的 WORKER_PROMPT.md,再投短 Read 指令。supervised guidance 直接写消息 body,不创建新的 prompt 文件。
reauthorize(Task-058)用于 worker 被 SHELL_COMMAND_NOT_ALLOWLISTED 拦验证且根因是 spawn 授权快照缺命令时:guard 读 launch.sh 内联的 WORKER_INSTALL_AUTH_B64(进程环境,运行中改授权文件无效),本命令合并 --allow-cmd 进授权文件后重写 B64(回验解码一致)、把被提问/中止翻成 failed 的 Task 复位 ready、在同一 worktree 创建新终端并复用 Task 重注册(worker-start 重注入完整任务)、改写 METADATA 的 terminal_handle/dispatch_id、可选发送 --resume-text、最后关闭旧终端句柄。重注册前必须从 Git common-dir 推导原始 authority receipt,并交叉核对 receipt、runtime、session、worktree、branch 与受信 METADATA;任一缺失、软链或漂移都在创建新终端前失败。register 的显式 metadata 替换和 completion receipt 轮换只在这条已核对路径开放,普通手动 register 不能借此换权威;轮换时旧 receipt 保留到 METADATA 原子写回成功,写回失败则恢复旧 receipt,随后回滚新终端,不能留下“旧路由 + 新完成权限”的撕裂状态。未提交的工作区改动全部保留;provider lease 的 transport 记账留给 release/clean-worktree 阶段。
reauthorize --allow-cmd 只扩充普通 Shell 精确命令,不能修改或覆盖 spawn 时封存在 PM receipt 的 allowed_write_paths。git rm 高风险分类先于该白名单;即使把 git rm -r、-f、--cached、多路径、范围外路径或复合命令原样加入 --allow-cmd,仍必须拒绝。只有 hook-enabled backend 能机械执行 receipt 绑定的单 tracked 文件删除;prompt-only degraded worker 应交由 PM 或新建 hook-enabled worker 处理。
3. Supervised 收口顺序
wait获取完整 Delivery;不要立即 ack。- 按 receipt 的
ordered_messages顺序处理每条question/escalation/worker_done;当前 Orca 单批最多 50 条,类型过滤只控制 wait 唤醒,不过滤 Delivery。ack 前重复 wait 必须重放同一批,不能跳到下一批。 - 用
show核对 accepted settlement,用read和真实 diff/tests 验收。只读状态与业务验收不能替代生命周期 settlement。 - 每个 settled worker 选择立即复用、
release或用户明确要求时retain。 - 全部处理完后
ack --delivery-id ...;ack 回执中的acknowledged只确认上一批,若同一响应携带新的非空deliveryId/messages,立即按next_ordered_messages处理下一批,不能丢弃或视为已确认。 - 继续
wait,直到所有预期 Dispatch settle。
wait receipt 把 question 标为 reply_required、escalation 标为 intervention_required、worker_done 标为 validate_and_account_terminal;它的 delivery_consumed_unacknowledged 仍不证明这些动作已经完成。wrapper 要求原生 result 与每条 message 的 Run 精确等于 metadata Run,count 为与 messages 等长的非负整数,非空批次的 Delivery/message ID 为一致的非空字符串,空批次必须显式返回 null Delivery ID;所有出现的兼容 alias 必须一致。ack 只有在 Orca 回执正向包含同一 Run 和精确 acknowledged Delivery ID,且同一响应携带的下一批也通过上述完整批次校验时成功;非空 next Delivery 的 ID 必须不同于刚确认的上一批。receipt 分开记录 acknowledged_delivery_id 与 next_delivery_id/next_ordered_messages,不把“已确认上一批”冒充“下一批已处理”。wait timeout 是 checkpoint,不是 failure;不要因此 stop/release worker。
4. PR 先行与本地集成
Orca worktree/terminal 是高频执行面;PR 是 PM 收口时的审阅边界。默认顺序是:
worker 分支提交
→ safe-push
→ 创建或接管唯一匹配 PR
→ 冻结 PR base/head SHA、diff、checks 与 review
→ 在最新 origin/main 上建立本地集成候选
→ 复跑最终门禁
→ 按仓库规则本地推入 main,或交给 GitHub PR merge
→ 核对远端结果后再清理这只是默认顺序,不是外部写入授权。没有用户或项目授权时,PM 停在只读 PR 审计与本地候选验证,不 push main、不 merge、不 close PR。
4.1 先查已有 PR,避免双开
worker 可能已经自行 push/开 PR。先运行只读审计:
bash scripts/pm-orchestrate.sh pr-audit \
--worktree "$WT" --base-ref main --head-ref "$BRANCH" --head-sha "$HEAD_SHA" \
--task-id Task-097 --agent-id agent-name- stdout 只有一个
pr-audit.v1JSON;stderr 只写摘要 receipt,机器消费者不得混读。 exact同时要求 canonical repo/Git common dir、base ref/OID、head owner/ref/OID、真实 diff 指纹相等以及独立Task:/Agent:trailer 一致;恰好一个 exact 且零 suspected 才返回adopt。- 同 head 错 SHA、同内容异分支、fork/cross-repository、归属不完整、diff/候选事实未知或 101 条候选截断都归
suspected/ambiguous,禁止 push/create。 create只表示当前只读证据允许进入授权门禁;不是 push 或创建权限。- 接管 worker 自建 PR 不降低门禁:仍检查完整 diff、identity、checks、review、敏感文件和声明范围。
4.2 授权回执与 pm-closeout
所有 mutation 授权只接受本次 CLI 的显式参数,不从可继承环境变量取得。push/create 的第一阶段回执必须与脚本打印的 expected 字符串逐字一致:
operation=<branch-push|pr-create|main-push|remote-merge|pr-close>;
repo=<HOST/OWNER/REPO>;pr=<PR号或none>;head=<branch>;sha=<40-hex>实际值为单行、无换行;上方仅为字段说明。典型调用:
bash scripts/pm-closeout.sh \
--worktree "$WT" --main-worktree "$MAIN_WT" \
--mode local-after-pr --main-protection auto \
--task-id Task-097 --agent-id agent-name \
--integration-path skills/multi-agent-orchestration \
--title "feat(multi-agent-orchestration): ..." \
--safe-push-script /absolute/path/to/git-workflow/scripts/safe-push.sh \
--verify-cmd bash --verify-arg scripts/test-pm-closeout.sh \
--authorize-main-push 'operation=main-push;repo=github.com/OWNER/REPO;pr=123;head=feat/x;sha=<40-hex>' \
--authorize-main-candidate 'operation=main-push-candidate;repo=github.com/OWNER/REPO;pr=123;head=feat/x;sha=<40-hex>;base=<40-hex>;candidate=<40-hex>;tree=<40-hex>'若预审为 zero,还需在任何写入前同时提供绑定相同 repo/head/SHA 的 --authorize-branch-push 与 --authorize-pr-create;worker 已自建 exact PR 时两者都不需要。--authorize-pr-close 独立可选:省略时本地集成完成后保留 PR open;提供但不匹配时在 main push 前失败。
候选完成后还有第二阶段 mutation challenge,绑定最终 base/candidate/tree;调用方必须把完整 expected 值原样传回 --authorize-main-candidate 或 --authorize-remote-candidate。main 前移会改变 challenge,旧回执不可复用:首次调用可以停在 exit 8 的 VALIDATE_ONLY,审阅 challenge 后再用同一参数重跑。粗粒度 main-push/remote-merge 回执与候选回执缺一不可。
调用方 body-file 不得自带 Task:/Agent: trailer;脚本在任何 push/create 前拒绝,由唯一写入点追加,避免重复或冲突归属导致“PR 已创建但无法接管”。
--main-protection auto 读取 GitHub branch metadata 的类型化 .protected 布尔值;该字段同时覆盖 classic branch protection 与 rulesets。只有明确 false 才认定 unprotected;403/404、缺字段、畸形响应或未知状态都降为非成功 VALIDATE_ONLY。本地 main push 前再次读取该字段,候选验证期间从 false 变为 true/unknown 时不沿用旧结论。--main-protection protected 只允许显式选择更保守的远端路径,不提供 unprotected 绕过开关。
4.3 三种收口结果
| 结果 | 适用条件 | 行为 |
|---|---|---|
LOCAL_AFTER_PR |
branch metadata 正向证明 main unprotected,存在唯一 clean/idle main worktree,且两阶段 main-push 授权均匹配 | 在隔离 main clone 对冻结 worker patch 做三方应用并验证;从隔离 clone safe-push,远端确认后才 --ff-only 同步真实 main;提交主题带 (#PR) |
REMOTE_PR |
main 有 classic protection/ruleset,或项目明确以 GitHub 为合并权威 | 同样先建本地候选并验证;mutation 前重审唯一 PR 集合与冻结快照,确认无原生 merge queue 后用 --match-head-commit 合并,并复核 state/mergedAt/mergeCommit、merge 第一父提交等于已审 base、merge tree 等于候选 tree,且 merge commit 已进入 main |
VALIDATE_ONLY |
用户显式只读,或 main/PR/checks/review/授权/范围/保护状态任一不明 | 显式请求时退出 0;由写入模式自动降级时退出 8,不 push、不 create、不 merge、不 close |
两种写入模式都必须至少提供一个仓库相对的 --integration-path;拒绝绝对路径、..、symlink 逃逸与 pathspec magic。候选从冻结 WORKER_BASE..WORKER_TIP 生成限定范围的 binary/full-index patch,在 fresh main 上 --3way --index 应用;同文件非重叠修改可保留,语义冲突则停在零 main mutation。
候选验证后、任何 main push/GitHub merge 前都重新 fetch main、重跑 pr-audit 并核对同一 PR 的 base/head/diff/checks/review;任何漂移回到审计,不沿用旧结论。Monorepo 禁止直接 git merge <feature>;最终本地同步只允许将已经远端确认的隔离 main 候选 --ff-only 到同一 Git common dir 的唯一 clean main worktree。
Task-097 不消费 GitHub 原生 merge queue:远端 mutation 前必须读到类型化 rules 数组且确认没有 merge_queue;发现 queue 或 API 状态未知都停在 exit 8 的 VALIDATE_ONLY,不得让 gh pr merge 留下稍后异步修改 main 的排队项。队列消费和延迟复核属于 Task-070。
普通失败(exit 2–8)都发生在 main commit point 前,因此必须保持 main 未修改。分布式写入存在不可消除的“服务端已提交、客户端回执丢失”窗口;写入调用开始后若无法确认,不得伪称零 mutation,也不得误报成功,而以 exit 9 输出可恢复状态:PR_CREATE_OUTCOME_UNKNOWN、PR_CREATED_REVIEW_REQUIRED、REMOTE_MERGE_OUTCOME_UNKNOWN、REMOTE_MERGED_REVIEW_REQUIRED、MAIN_PUSH_OUTCOME_UNKNOWN、REMOTE_MAIN_APPLIED_LOCAL_PENDING 或 LOCAL_AFTER_PR_CLOSE_OUTCOME_UNKNOWN。看到这些状态必须先读取远端真实 PR/main 再决定恢复动作,禁止盲重试 mutation。
gh pr create 本身也是分布式 commit point,GitHub 不提供本流程可用的幂等键,另一个 creator 可能在最终审计与 create 之间同时提交。因此本脚本能机械保证的是“commit point 前零 create、单次调用至多一次 create、结果不明时不重试”,不能承诺仓库最终全局零重复 open PR。post-create 重审发现多个候选时保留新建 PR 回执并进入 PR_CREATED_REVIEW_REQUIRED;不得在没有独立 close 授权时用自动关闭补偿掩盖竞态。
4.4 远端结果与清理
- 本地集成提交成功推入 main 后,原 PR 若未被 GitHub 自动标为 merged,使用包含 main commit SHA 的说明关闭;不得把
CLOSED伪报成 GitHubMERGED。 - GitHub 合并路径以
state == MERGED、非空mergedAt和mergeCommit.oid为成功证据。 - 只有远端结果已确认且 worker/worktree 无未提交改动,才进入 release、分支和 worktree 清理。标准路径由
pm-closeout.sh把冻结的 worker tip、PR、delivery mode/commit、integration target、worktree、Session identity 与分支生命周期交给pm-cleanup-worker.sh --execute;--keep-branch是显式 opt-out,必须输出保留理由。supervised 路径先从 metadata 读取精确 Run/Dispatch,以worker-list --run <run> --limit 100遍历所有 opaque cursor;只有唯一、同 Run 的目标行才能进入状态分支。库存scope接受官方run及兼容的runId/run_id;所有出现的字段必须非空且等于请求Run,冲突或null仍拒绝。前置分页/身份异常必须保留全部资源;reclaimablerelease 后的重读异常则保留 terminal、worktree 与远端/本地分支,并明确 release 可能已发生。只有 PR 已确认合并、但遗留 worker 未走标准 closeout 时,才单独使用scripts/post-merge-cleanup.sh:唯一 MERGED PR、head 精确一致、无 stacked child、非长期分支等删除门禁全过后才执行,远端删除失败或残留验证不过以 exit 9 报告;门禁不过则输出 deferred 理由保留现场。两条路径执行前均先 dry-run 审阅计划,post-merge-cleanup.sh不替代标准 closeout,也不用于批量扫描。 remote-pr只有 PR 的 exact head 与MERGED + mergedAt + mergeCommit全部匹配才删远端分支;local-after-pr必须证明 delivery commit 已进入origin/main,PR 仍OPEN时保留远端 head,避免把活 PR 的来源分支删掉。远端查询失败、未知 PR 状态、dirty worktree、tip 漂移或生命周期未结算均失败关闭。- 本地删除在 worktree 已安全移除后,以 expected tip 作为 old-value 执行精确 ref 删除。这样 squash/rebase merge 不依赖
git branch -d的祖先判断,也不使用无条件git branch -D。 - 清理结果固定为
CLEANED、RETAINED_WITH_REASON、CLEANUP_PENDING。delivery commit 已确认后,清理失败是独立资源债务,禁止重跑 push/merge;但CLEANUP_PENDING未显式记录和继续处置前,不得把整个任务报告为完全闭环。
5. 安全边界
- 脚本不自动 ack Delivery、不自动 release active worker、不删除 worktree(
settle例外兜底,但需--destroy显式升级)。worker 仍活着却漏发worker_done时先发结构化提醒;确认已死才 settle。 release/retain/reply/ack/settle仅对有 supervised metadata 的 worker 生效。settle需--reason并先持久审计,默认以worker-stop原子 fence+stop 后不动文件;stop 失败时worker-abandon只作 fence 兜底且禁止 destroy。--destroy仅在 stop 成功后释放 lease并删除精确 Orca/Git worktree。--force只覆盖 liveness gate;不会绕过仓库身份、审计落盘、worker-stop、lease 或 worktree 删除失败。- stale terminal handle 要先按 worktree 重新解析;禁止同时给旧/新 handle 双发。
- 普通 terminal worker 没有
worker_done义务;不要用 terminal 文本伪造 Dispatch 完成。 - 对 external supervised terminal,
release后 retained 不必然是错误;文件清理仍须由clean-worktree.sh验证 settled 状态、external ownership、retained reason 和精确句柄后处理。 pm-orchestrate account release的 provider lease 结算同样使用完整分页后的唯一目标行;第一页未命中或 WorkerList 不可证时保留 lease,不把 release 回执单独扩大为terminal=released。
派发计划与官方下一动作
派发profile 给出启动方式与唯一初始指引;它不执行Orca或认证,不是第二控制器。正式worker-show projection经原runtime/Run/Task/Dispatch/WT/terminal绑定核对后优先,stale仍保留原标签。composer残留不能证明未投递,completed/succeeded不能再submit,user_owned/retained不能靠启动时ownership自动关闭。terminal-managed须沿同一原生Session/Run核产物与退出;不能补造Task/Dispatch完成回执。