Files
laily 12e00bd594 Merge branch 'main' into rename
Keep pouch naming and .pouch/ack project state, and bring in ACK
regression mode, deployer test-environment binding, and manage-release
updates from main.
2026-08-25 15:23:48 +08:00

17 KiB
Raw Permalink Blame History

闭环流程(稳定核心,编排无关)

本文件定义与具体编排工具无关的三角色协作闭环。运行时调度可以用 Orca(见 orca-adapter.md),也可以手动跑(见下方「手动模式」)。

原则:调度消息只是运行时载体,任务结论必须回写到 tasks.yaml;已经验证且可跨 任务使用的项目经验必须由 Coordinator 回写到 knowledge.yaml。不要把消息当最终记录。 角色定义见 roles-and-permissions.mdCoordinator 只编排、Test 只验证、 Developer 只实现。


编排抽象

无论用什么工具,闭环都由这几个能力组成。注意 dispatch 有两个目标(Developer 与 Test):

抽象动作 含义 Orca 实现 手动实现
prepare(task) Coordinator 把任务和验收信号写进 tasks.yaml,按 scope 推荐知识并确认显式 knowledgeRefs 同左 同左
dispatch(task, developer) 把修复任务连同上下文交给 Developer orca orchestration dispatch 复制 prompt 到 Developer 终端/会话
dispatch(task, test) 把复测任务连同验收信号交给 Test orca orchestration dispatch 复制 prompt 到 Test 终端/会话
wait() 等待 worker_done / retest_result / escalation / decision_gate orca orchestration check --wait 人工等待回报
gate(task) Coordinator 读 Test 证据、knowledgeChecks 并对齐原始意图(不重测) 同左 同左
writeback(task, result) Coordinator 把任务结果写回 tasks.yaml,把验证通过的跨任务经验按权限写入 knowledge.yaml 同左 同左

派发用的 prompt 见 prompt-templates.md。状态流转见 roles-and-permissions.md §「任务状态机」。独立复测由 Test 执行,不是 CoordinatorCoordinator 只做读证据的终检。


标准闭环

Coordinator 发现或读取 open 任务
  -> prepare:写/补全 tasks.yaml 验收信号
  -> 从 knowledge.yaml 按 scope 推荐 active 知识,Coordinator 确认固定 revision 的 knowledgeRefs
  -> 为新轮次生成稳定 attemptId<task-id>-A<round>),Developer 与 Test 共用
  -> 决定 worktree:当前 worktree 起子 agent,还是新建隔离 worktree(见下节「子任务放哪」)
  -> 解析安全 profile:机器配置只读 tasks.yaml.project.orchestration
  -> 运行 launcher plan 并审阅 launchFingerprint
  -> 检查同轮空闲 worker;可信清理历史消息成功才复用,否则带 expected fingerprint 启动 fresh worker
  -> 把本次 task/attempt receipt 写回 tasks.yaml(见 orca-adapter.md
  -> dispatch 给 Developer--to <worker handle>
  -> 确认 Developer 已开始执行(terminal read 确认任务注入;未开始按环境失败处理)
  -> wait:滚动 check --wait + 定期 worker_probe(识别审批/未回车/额度停滞)
     直到 Developer 的 worker_done / escalation(含 knowledgeApplied / knowledgeCandidates
  -> writeback fixed_by_dev
  -> 若 delivery.yaml intents.testEnvironment 已启用:Coordinator 先按 deployer
     绑定拉起 `.pouch/deployer/<env>`,再派 TestTest 不发明编译或启动命令
  -> 为 Test 独立解析安全 profile;安全重置同角色空闲 worker,或重新 plan/launch fresh worker
  -> dispatch 给 Testretesting
  -> 确认 Test 已开始执行(terminal read 确认任务注入;未开始按环境失败处理)
  -> wait:滚动 check --wait + 定期 worker_probe(识别审批/未回车/额度停滞)
     直到 Test 的 retest_result(含 knowledgeChecks 和 candidate 独立证据)
  -> Test 通过:gateCoordinator 读证据对齐意图)
        -> 通过 gatewriteback verified
        -> gate 不满足意图:writeback failed_retest,带意图差异再派发 Developer
  -> Test 因环境无法完成:记录 environmentIncidents,不计轮次;有界恢复并明确告知用户下一步
  -> Test 观察到产品失败:writeback failed_retest,追加证据,再派发 Developer(最多累计三轮有效产品复验)
  -> 累计三轮有效产品失败:writeback leftover,继续下一个任务

一次派发只修一个明确问题(细则见 optimization-method.md §「每轮派发只修一个明确问题」)。 「决定 worktree」「解析 profile/receipt」几步的决策见下节与 model-routing.md / orca-adapter.md。历史 receipt、标题、preview、分支名、worker 自报和无密钥 receipt checksum 都不能代替可信启动 attestation 或历史消息清理证明。只复用同一轮内明确空闲、 身份完全匹配且得到新会话身份的 worker;清理能力缺失或结果不确定时必须 fresh launch。 Coordinator 默认给新逻辑轮次生成 <task-id>-A<round>,并在记录轮次结果时写入 tasks[].dispatch.rounds[].attemptId。它独立于编排工具产生的 taskIddispatchId:前者用于知识来源追溯,后两者只用于查询运行时。0.9.0 之前的历史 轮次允许暂时缺省;但要把该轮证据晋升为知识前,必须按确定性格式补齐。晋升时, provenance.taskIdprovenance.attemptId 必须能精确回到该任务及轮次。

知识选择与晋升

prepare(task) 时可以使用 Skill 自带的 scripts/select_knowledge.py 按 component、path、dependency、version 和 tag 确定性推荐条目。选择器只返回 active,并受条目数限制;stalesupersededarchived 不默认派发。自动 匹配只是推荐。条目中每个非空 scope 维度都必须被任务上下文命中,因此调用时应 提供当前任务已知的全部 component、path、dependency、version、tag、symbol 和错误 特征。Coordinator 确认并写入当前任务的显式 knowledgeRefs 后才成为本轮权威 上下文。

scope.paths 使用 POSIX 路径 glob* 不跨目录分隔符,** 才能跨目录。多个 pattern 是同一维度内的 OR,候选越多表示范围越宽;超过选择预算时,选择器优先保留 命中维度更多、OR 候选更少、字面约束更多且通配符更少的条目。

派发时只内联本轮引用的少量知识,不要求 worker 全量读取 knowledge.yaml。这也 避免隔离 worktree 读不到 Coordinator 工作树中尚未提交的项目状态。

进行中的任务只能引用 active 条目。已经进入 verifiedleftover 的终态任务 可以继续保留固定 revision 的历史引用,即使对应知识后来变成 stalesupersededarchived;这些旧条目不会再次被选择器派发。

Developer 或 Test 发现经验时只能通过 knowledgeCandidates 提名,并带上当前任务 的独立观测、scope、触发条件和证据。candidate 留在任务证据中,不进入知识选择器, 也不能被下一轮当作 active 指令。只有 Test 独立验证、Coordinator gate 通过后, Coordinator 才能写入或更新 knowledge.yaml;全项目强制或权限类规则还需 User / Decision Owner 确认。

Test 对显式引用回报 not_applicable 时,说明 Coordinator 的选择需要纠正。该引用 仍在 knowledgeRefs 中就不能把任务标为 verifiedCoordinator 应记录原因、移除 误选引用并重新校验,或继续补充验证。

知识中的 verification.ref 只能引用 knowledge.yaml.verificationRegistry 里已审查的仓库内相对 path 和结构化 args, 不能从知识正文拼接或执行自由 shell。Developer/Test 只把 verification.ref 交给 <ack-skill-dir>/scripts/run_verification.py;该入口从项目根目录逐段安全打开检查 文件,拒绝 symlink 路径,并从匿名稳定快照执行。关键约束应下沉为测试、lint、CI 或正式规范。检查进程从固定的项目根 fd cwd 运行;检查脚本应使用 cwd 或 ACK_PROJECT_ROOT 定位资源。后者是 fd 路径,原始展示路径只在 ACK_PROJECT_ROOT_DISPLAY 中用于日志;不能依赖 $0 / __file__ 的目录。


子任务放哪:新 worktree 还是当前 worktree

Coordinator 派发前先决定 Developer/Test 在哪工作。两种方式:

方式 1:当前 worktree 复用安全重置的空闲子 agent,或起 fresh 子 agent(终端)

# 当前 Orca 不能可信清理历史消息,因此先审阅 fresh launch plan
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-current-worktree> --slot <1..99>
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-current-worktree> --slot <1..99> \
  --expected-launch-fingerprint <plan 中的 sha256:...>
  • 适合:串行闭环、一次一个 Developer 任务、小改动、Test 要复测的正是 Developer 改的那棵树。
  • 优点:单一服务实例、无跨 worktree 对齐困扰、开销小。
  • 风险:多个 agent 同时改同一棵树会互相踩(半构建状态、git 冲突)。
  • 记录:launch 成功后把 receipt 追加到权威 tasks.yaml.workerReceipts,并把 receipt.id 写入 dispatch.<role>.receiptId、把 profileId 写入 dispatch.<role>.profileId、把本轮稳定 ID 写入 dispatch.<role>.attemptId receipt 的 task/role/profile/attempt 必须与当前 dispatch 完全一致,不能只记录 一个裸 handle,也不能引用旧任务或旧轮次 receipt。

方式 2:新建隔离 worktree,再在其中起子 agent

创建成功后,确认新 worktree 与权威项目根属于同一 Git 仓库(launcher 按 git worktree list 注册表 + 同 common-dir 约束校验,v0.19 起不再需要 allowedWorktrees 白名单登记)。

orca worktree create --name <feature> --base-branch <base> --json
# 对返回的绝对路径调用 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-new-worktree> --slot <1..99>
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-new-worktree> --slot <1..99> \
  --expected-launch-fingerprint <plan 中的 sha256:...>
  • 适合:并行多个互不依赖的子任务、大/高风险/实验性改动、要保持基线分支干净(如 prod 不动、feature 走独立分支)、要独立 build 或跑独立服务实例、best-of-N 尝试。
  • 优点:隔离 + 并行 + 易回滚(删 worktree 即可)。
  • 成本:各自 build/依赖、服务要用不同端口、必须处理下节的 worktree/服务对齐。

决策速查:

情况 选择
一次一个任务、串行修复 当前 worktree 子 agent
多个任务并行、互不依赖 每个任务一个新 worktree
高风险 / 实验 / 可能整体丢弃 新 worktree
要保持基线分支干净 新 worktreefeature 分支)
小改动、追求快 当前 worktree

项目状态(SSOT)只落一处:无论开几个 worktreetasks.yamlknowledge.yaml、可选 delivery.yaml 和可选 regression.yaml 都只认一个权威 副本(通常在基线/协调所在 worktree)。Coordinator 单写任务、知识、回归目录、 deliveryRunsregressionRuns;交付能力只在显式配置维护时修改。project.orchestration、顶层 workerReceipts 和任务 dispatch 也只写入这个 副本;不要每个 worktree 各留一份会分叉的项目状态。profile 解析、launcher 与 receipt 规则见 model-routing.mdorca-adapter.md

两种 worktree 方式都只允许 profile 中的 read-only / workspace-write 安全权限。 v0.10 的 full-access 授权与撤销机制仍是 Deferredlauncher 遇到 full-access 或等价 的 sandbox 绕过请求必须 fail closed。


手动模式(无 Orca

没有编排工具时,闭环不变,只是 dispatch / wait 由人工承担:

  1. Coordinator 在 tasks.yaml 写好任务和验收信号。
  2. knowledge.yaml 推荐相关 active 知识,Coordinator 确认固定 revision 的 knowledgeRefs;用 prompt-templates.md §1 的初始派发模板生成 prompt, 手动发给 Developer(另一个会话/终端/人)。
  3. Developer 完成后按 worker_done 模板回报。
  4. Coordinator 写回 fixed_by_dev,用 prompt-templates.md §3 的复测派发模板把任务发给 Test。
  5. Test 独立复测后按复测报告模板回报证据和 knowledgeChecks
  6. Coordinator 做终检并回写 tasks.yaml:通过 verified,不过 failed_retest
  7. 产品失败则用「复测失败再派发模板」重新发给 Developer,最多累计三轮有效产品 复验;环境失败写入 dispatch.environmentIncidents,恢复环境后重新派发 Test, 不派 Developer、不消耗产品轮次。

手动模式下同样遵守:worker_done / 复测报告都不等于最终结论、只有 Coordinator 写 tasks.yamlknowledge.yaml、三轮失败留档。若本次确认计划还包含交付,所有 选中任务 verified 后由 Coordinator 继续按 delivery.md 执行并写 deliveryRuns

手动交给用户已打开的会话不等于产生 ACK receipt。该会话可以完成本次显式 handoff, 但不能因此进入 Orca 自动派发信任路径;后续自动派发仍需重新通过 ACK launcher 创建 fresh worker。


Test 复测(编排无关)

即使 Developer 的 worker_done 写了"全部通过"Test 仍必须独立复测:

git status --short
<test_commands>
curl -s <base_url>/health-or-summary

浏览器复测建议记录:

BASE_URL:
page:
steps:
expected:
actual:
snapshot evidence:

Test 只回传证据,不写 tasks.yamlknowledge.yaml;由 Coordinator 落盘。 每条适用的显式 knowledgeRef 还应报告 passedfailednot_applicable 及证据。


Coordinator 终检(gate

Test 报通过后,Coordinator 不重测,而是做一次读证据的终检:

  • Test 证据是否覆盖了任务的每一条验收信号(见 optimization-method.md §1)。
  • 当前任务显式 knowledgeRefs 的必需 knowledgeChecks 是否全部覆盖,检查引用 是否能解析到项目已审查的入口。
  • 结果是否符合任务的原始意图,而不只是通过了字面文案。
  • 运行环境是否对齐(见下方「服务与 worktree 对齐」)。

终检不通过(例如意图漂移、验收信号写漏)时,回写 failed_retest 并把意图差异带给下一轮 Developer,必要时先补全验收信号。


服务与 worktree 对齐(防假通过/假失败)

Test 复测前记录运行环境:

pwd
git rev-parse --abbrev-ref HEAD
git rev-parse --short HEAD
serverPid:
serverCommand:
BASE_URL:
frontendDir:
worktreePath:

如果开发在 <dev_worktree> 修复,但服务跑的是另一个 worktree,必须停止并重启正确服务后再测。长跑服务或静态前端尤其要确认加载的是最新构建产物。若项目配置了 intents.testEnvironment,重启方式以 deployer 绑定为准,不另写一套启动命令。


结果回写

Coordinator 回写 tasks.yaml 时按状态填写(字段结构见 templates/tasks.schema.json):

# 通过(Test 复测 + Coordinator 终检)
status: verified
resolution:
  verifiedAt: "<timestamp>"
  verifiedBy: "test"
  evidence:
    verification: "<commands passed>"
    browser: "<snapshot or API evidence>"
# 失败但未满三轮
status: failed_retest
dispatch:
  rounds:
    - round: 1
      result: failed
      evidence: "<latest evidence from Test or gate>"
# 累计三轮失败
status: leftover
resolution:
  leftoverReason: "failed after 3 supervised developer rounds"
  evidence:
    final: "<latest failing evidence>"

环境失败不进入上面的 rounds,单独记录:

status: fixed_by_dev
dispatch:
  environmentIncidents:
    - id: "BUG-001-ENV-1"
      role: test
      phase: service
      status: open
      summary: "无法访问待测服务"
      evidence: "preflight connection refused"
      impact: "未执行产品验收信号"
      recoveryAction: "启动正确 worktree 的最新服务后重试"
      userAction: "无需操作;Coordinator 将重启服务"
      reportedAt: "<timestamp>"

Worker 收尾

Coordinator 写入本轮全部最终状态并完成已确认的 delivery 停止点后,再回收 worker。 按 terminal handle 聚合所有 receipt 引用:只关闭全部关联任务均为 verified、且没有 未解决环境事件的 handle。任何关联任务仍为 opendispatchedfixed_by_devretestingblockedfailed_retestleftover 或状态不明时都保留该终端,不设置 TTL。关闭前后按 orca-adapter.md 核对 runtime/handle/incarnation 和关闭回执;关闭 不确定时报告并保留审计记录。