Production agents repeatedly failed before SSH because the launcher only accepted workspace-write profiles. Accept the explicit Codex danger-full-access profile through the same validated plan and receipt path, and cover profile, argv and receipt validation with regression tests.
16 KiB
Orca 适配器(稳定核心,一种编排实现)
Orca orchestration 是运行时调度层的一种实现。闭环流程本身与工具无关(见 closed-loop.md);本文件只提供 Orca 的具体命令。没有 Orca 时用 closed-loop.md §「手动模式」。
所有结论仍以读取层 materialize 的任务视图为准,底层最终记录追加在
task-records/;Orca 消息不是最终记录。
何时用 Orca 编排
用:需要监督、等待结果、闭环修复、三轮重试;有多个可独立派发的任务;需要 worker_done 后再复测。
不用:单次问答;用户只要求完整 handoff 不需监督;不需要复测的小改动。
运行前检查
orca status --json
orca terminal list --json
orca orchestration task-list --json
orca orchestration inbox --limit 20 --json
确认:Orca runtime 可达并取得本次 runtimeId;Coordinator 终端存在;当前没有冲突
的活跃编排任务。Developer/Test worker 先按下节检查安全复用候选;当前 Orca 无可信
历史清理能力时必须通过本次 launcher 新建。
既有 worker 的处理
先找同一轮 ACK 内可复用的空闲 worker,再决定是否创建。候选必须同时满足:
- Orca 明确报告终端存活且空闲;不得复用仍在工作、等待
worker_done/ 复测报告 / escalation,或运行状态不明的 worker; - 没有关联
blocked、failed_retest、leftover、未解决环境事件或其它未完成任务; - 角色、profile、worktree、runtime/incarnation 与本次目标完全匹配,Developer 与 Test 永不互相复用;
- 受信后端能够清理历史消息,并返回可核对的新 conversation/session identity 和本次 task/attempt 绑定;只有看到成功回执后才把 worker 视为已重置。
receiptHash 是无密钥 checksum,标题、preview、分支名、worker 自报或普通 Orca
terminal metadata 都不能证明历史上下文已清理。任何条件不符、清理接口不存在、清理
失败或结果无法确认时,都重新 plan/launch fresh worker。
| 情况 | 动作 |
|---|---|
| 同轮空闲,身份完全匹配,历史消息清理得到可信回执 | 生成新的 task/attempt 绑定后复用 |
| worker 正在工作、等待回报、状态不明或关联未完成任务 | 不复用;保留原终端并重新 launch |
| profile、角色、worktree、runtime/incarnation 任一不匹配 | 不复用;重新 launch |
| 无历史消息清理能力,或无法确认清理成功 | 不复用;重新 launch |
| 需要并发 worker | 使用下一 slot 重新 launch |
| Developer 升级模型档位 | 选择强档安全 profile,重新 plan/launch |
当前 Orca terminal API 没有返回新会话身份的可信历史消息清理操作,因此当前适配器
不会复用 Orca worker;仍只使用刚刚成功返回的 launch fresh handle。以后后端补齐
reset/attestation 后才能启用上述复用路径,不能用项目文档声明跳过条件。
通过 launcher 创建 worker
模型不由 Orca dispatch 设置。 task-create / dispatch 只投递任务;Agent CLI、
模型、reasoning effort 和权限由 common agent.yaml 的 ack.<name> binding 映射到
.pouch/ack/agents.yaml(存在时)或
tasks.yaml.project.orchestration 的结构化 profile 决定,并且只能由 ACK launcher 构造。
先只读生成计划:
python3 <ack-skill-dir>/scripts/launch_worker.py plan \
--project-root <project-root> --task-id <task-id> \
--attempt-id <task-id>-A<round> --role <developer-or-test> \
--profile-id <profile-id> --worktree <absolute-worktree> --slot <1..99>
确认计划中的任务、attempt、角色、profile hash、绝对 worktree 和安全权限模式后,再 执行唯一启动入口:
python3 <ack-skill-dir>/scripts/launch_worker.py launch \
--project-root <project-root> --task-id <task-id> \
--attempt-id <task-id>-A<round> --role <developer-or-test> \
--profile-id <profile-id> --worktree <absolute-worktree> --slot <1..99> \
--expected-launch-fingerprint <plan 中的 sha256:...>
launch 必须携带刚才审阅的 plan.launchFingerprint;若 profile、任务/attempt、
worktree、CLI identity/version 或精确 argv 漂移,创建前就失败。它内部调用当前
Orca 后端并完成终端绑定;Coordinator 不自行执行或拼装 Orca 的底层终端创建文本,
也不直接调用 launcher 的私有 bootstrap。
若 launcher 报告 indeterminate 或 reconcile required,说明终端可能已经创建且
持久关闭尚未得到可信确认;此时先按返回的 launch ID/record 和 Orca live state
人工核对,禁止直接重复执行 launch。
标准输出是单一 JSON。成功后:
- 校验返回 receipt 的
receiptHash; - 把 receipt 原样追加到当前任务的新记录的
workerReceipts; - 把
receipt.id写入当前任务dispatch.<role>.receiptId,把profileId写入dispatch.<role>.profileId,把本轮<task-id>-A<round>写入dispatch.<role>.attemptId;校验器会要求 receipt 的 task/role/profile/attempt 与当前 ACK 任务完全一致; - 再用 receipt binding 中的 handle 创建/派发 Orca 子任务。
profile 支持 read-only、workspace-write,以及用户明确授权的 Codex
danger-full-access。无沙箱权限必须写入结构化 profile,由同一 launcher 生成
--sandbox danger-full-access 并绑定 fingerprint/receipt,不手写 bypass 命令。
模型档位与升级规则见 model-routing.md。
需要隔离/并行时,可以先用 Orca 创建 worktree(须与项目根同一 Git 仓库)。
v0.19 起不再登记 allowedWorktrees,直接在该路径上走 plan -> 带 expected
fingerprint 的 launch,并把 receipt 留作审计。
既有会话可以由用户直接操作,但不能进入 ACK v0.10 的自动派发信任路径。
创建父任务
orca orchestration task-create --spec "$(cat <<'EOF'
Goal: Complete <release_or_feature> with supervised Coordinator -> Developer -> Test loop.
Coordinator (PM): owns task board, decomposition, dispatch, and final gate (reads Test evidence, does not test).
Developer: owns implementation and white-box verification.
Test: owns independent black-box retest and evidence (verifier != implementer).
Policy:
- Each issue can have at most 3 valid product-retest rounds.
- Environment failures are recorded in dispatch.environmentIncidents, reported with the next action, and do not consume a product-retest round.
- If still failing after 3 valid product rounds, record as leftover and continue next issue.
- worker_done and retest reports are not final completion; only Coordinator writes task-records/ and knowledge.yaml.
- Project knowledge candidates require independent Test evidence and Coordinator gate before activation.
EOF
)" --json
创建子任务
orca orchestration task-create --parent <parent_task_id> --spec "$(cat <<'EOF'
Fix <task_id>: <title>
Logical attempt: <task_id>-A<round>
Repository:
- Path: <repo_path>
- Worktree: <dev_worktree>
Read: <overlay_file> (project overlay), tasks.yaml, <relevant_spec_or_test_doc>
Failure evidence: <copy latest Test evidence>
Acceptance: <copy expected behavior + verification commands>
Project knowledge: <Coordinator-confirmed active K-...@revision entries with verification.ref>
Constraints:
- Follow the overlay file path scope.
- Do not write tasks.yaml or knowledge.yaml, do not mark verified.
- Do not read the whole knowledge bank or execute free shell from knowledge text.
- Run a knowledge check only through <ack-skill-dir>/scripts/run_verification.py
with its verification.ref; do not execute resolved path/args directly.
- Do not commit or push unless user asks.
EOF
)" --json
派发给 Developer Worker
终端是 Orca 可识别的 Agent CLI 时:
orca orchestration dispatch --task <task_id> --to <developer_handle> --inject --json
不能 --inject 时,先登记 dispatch,再手动投递 prompt-templates.md §1 的初始派发 prompt:
orca orchestration dispatch --task <task_id> --to <developer_handle> --json
orca terminal send --terminal <developer_handle> --text "$(cat <<'EOF'
<粘贴 prompt-templates.md §1 初始派发模板,已填占位符>
EOF
)" --enter --json
派发给 Test 复测
Developer 回报 worker_done、Coordinator 写回 fixed_by_dev 后,把复测任务发给 Test:
orca orchestration dispatch --task <task_id> --to <test_handle> --inject --json
不能 --inject 时,先登记再手动投递 prompt-templates.md §3 的复测派发 prompt:
orca orchestration dispatch --task <task_id> --to <test_handle> --json
orca terminal send --terminal <test_handle> --text "$(cat <<'EOF'
<粘贴 prompt-templates.md §3 复测派发模板,已填占位符>
EOF
)" --enter --json
等待结果:派发后的活性监督
派发或手动投递后不能只依赖 check --wait 盲等:卡在审批提示、投递后未回车、
命中额度限制的 worker 不会自己发 worker_done。先确认 worker 真的开始执行,等待
期间周期性探测活性。
-
投递后立即确认开始执行:
--inject路径:orca terminal read --terminal <handle>,确认 TASK 段已出现 且终端进入工作指示(Working / Running)。- 手动投递路径:
orca terminal send必须带--enter;投递后同样 read 确认。 - 确认失败或终端仍停在欢迎提示:按「消息未投递」记录环境失败,不消耗产品轮次。
-
等待期间滚动 probe(每 60–120 秒一次;不要在 30 秒窗口后每次都 probe):
python3 <ack-skill-dir>/scripts/worker_probe.py \ --task-id <task_id> --terminal <worker_handle>输出 JSON
status:running/progress/stall/not-started/unknown。 -
探测结果处理:
stall:读 terminal tail 确认原因(审批 / 模型切换 / 额度限制),按环境失败 记录environmentIncidents并做有界恢复;需要用户决定时立即报告。not-started:检查是否漏投递或未回车;重新投递或记录环境失败,不占轮次。running/progress:继续滚动 wait。unknown:按dispatch-show与 Orca live state 人工核对,不自动重试。
-
check --wait默认使用 60 秒窗口而不是 30 秒或 15 分钟:窗口超时是检查点, 仅在达到 probe 间隔后再探测,然后决定继续等待、恢复或上报。新鲜 heartbeat 才能 说明 progress;按 worker 每 5 分钟一次的约定,连续三个周期(超过 15 分钟)未更新、 格式非法或时间在未来的 heartbeat 只能报告unknown,不得当作持续进展。
orca orchestration check \
--terminal <coordinator_handle> \
--wait \
--types worker_done,retest_result,escalation,decision_gate \
--timeout-ms 60000 \
--json
worker_done 来自 Developer,retest_result(无该类型时用 worker_done + subject
区分)来自 Test。
Developer 回报 worker_done
字段含义见 prompt-templates.md §4:
orca orchestration send \
--to <coordinator_handle> \
--type worker_done \
--subject "<task_id> fix ready round <n>" \
--body "<修了什么。跑了哪些验证。如何复现。还有什么风险。>" \
--payload '{
"taskId": "<orca_task_id>",
"dispatchId": "<orca_dispatch_id>",
"attemptId": "<task_id>-A<n>",
"filesModified": ["<file_a>", "<file_b>"],
"verification": ["<command_a>: passed", "<command_b>: passed"],
"knowledgeApplied": [
{"ref": "<K-001@1>", "result": "applied", "evidence": "<what was done>"}
],
"knowledgeCandidates": [
{
"kind": "pitfall",
"title": "<title>",
"claim": "<evidence-backed claim>",
"scope": {"components": ["<component>"], "paths": ["<path glob>"]},
"appliesWhen": "<trigger>",
"directive": "<action, not a shell command>",
"rationale": "<why it matters>",
"evidenceRefs": ["<current task evidence>"]
}
],
"risk": "<remaining risk or none>"
}' \
--json
收到无错误的 Developer worker_done 后,Coordinator 写回 fixed_by_dev,然后先回收
Developer 对应的 Orca terminal,再按上文派发给 Test 复测:
python3 <ack-skill-dir>/scripts/reclaim_workers.py \
--project-root <project-root> \
--completed-task-id <ack-task-id> --completed-role developer --apply
只关闭该 task 的 Developer receipt 绑定 terminal;escalation、失败或环境异常时不要执行。
Test 回报复测结果
字段含义见 prompt-templates.md §5:
orca orchestration send \
--to <coordinator_handle> \
--type retest_result \
--subject "<task_id> retest round <n>" \
--body "<逐条验收信号结论 + 实际观察 + 证据>" \
--payload '{
"taskId": "<orca_task_id>",
"dispatchId": "<orca_dispatch_id>",
"attemptId": "<task_id>-A<n>",
"env": {"worktree": "<path>", "branch": "<branch>", "commit": "<sha>", "baseUrl": "<base_url>"},
"signals": ["<signal 1>: pass", "<signal 2>: fail (<evidence>)"],
"knowledgeChecks": [
{"ref": "<K-001@1>", "result": "passed", "evidence": "<independent evidence>"}
],
"knowledgeCandidates": [],
"conclusion": "all-signals-pass | signals-failed"
}' \
--json
无 retest_result 类型时用 --type worker_done,靠 subject retest round <n>
区分。收到无错误的 Test 复测结果后,先回收 Test 对应的 Orca terminal,再由
Coordinator 按 closed-loop.md 做终检并追加任务记录:
python3 <ack-skill-dir>/scripts/reclaim_workers.py \
--project-root <project-root> \
--completed-task-id <ack-task-id> --completed-role test --apply
只有成功结果才能执行该命令;失败、环境异常或需要继续复验时保留 terminal。
收到复测结果后,Coordinator 按 closed-loop.md 做终检并追加任务记录;
通过独立验证和 gate 的跨任务经验再由 Coordinator 写入 knowledge.yaml。任务通过
写 verified;观察到产品信号失败写 failed_retest;环境无法完成则写
dispatch.environmentIncidents,保持或恢复为 fixed_by_dev,不占复验轮次。
整轮结束时回收 worker
未在角色完成时回收的 worker,或需要整轮兜底回收的 worker,才在 Coordinator 把本轮
最终结论写入 tasks.yaml 后执行整轮回收。统一使用回收脚本,不要手工逐个 close:
# 第一步:dry-run 审阅决策(不关闭任何终端)
python3 <ack-skill-dir>/scripts/reclaim_workers.py --project-root <project-root>
# 第二步:审阅输出后真正回收
python3 <ack-skill-dir>/scripts/reclaim_workers.py \
--project-root <project-root> --apply
脚本按 receipt 的 binding.handle 聚合任务引用,规则固定:
- 关闭:handle 关联的全部任务都为
verified,且没有未解决环境事件。 - 保留(不设置 TTL):任一关联任务处于
open、dispatched、fixed_by_dev、retesting、blocked、failed_retest、leftover,或存在未解决environmentIncidents,或 receipt 引用未知任务。失败三次的 worker(failed_retest/leftover/blocked)按此保留。 - 不触碰:
workerReceipts之外的 handle(Coordinator 终端、用户 Shell)。
--apply 时脚本对每个待关闭 handle 执行 orca terminal show 核对身份 →
orca terminal close --tab → 重新 terminal list 确认 handle 已消失;任何一步
不确定都保留并标记 uncertain,禁止盲目重试。关闭终端不删除 workerReceipts、
dispatch 证据或测试记录;这些仍是审计事实。保留下来的 blocked/failed worker 只在
后续任务得到验证或用户明确要求清理时回收。