feat(ack): shard task records for merge-safe workspaces

This commit is contained in:
2026-09-20 19:15:43 +08:00
parent fd13dad2b0
commit 130dcc36c5
29 changed files with 985 additions and 218 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
- [ ] ACK Skill 已全局安装或安装到当前项目。
- [ ] 已运行 `pouch init ack --project <project-root>`。
- [ ] `.pouch/ack/` 只包含项目自己的 `project.md`、`tasks.yaml`、`knowledge.yaml`、
- [ ] `.pouch/ack/` 只包含项目自己的 `project.md`、`tasks.yaml`、`task-records/`、`knowledge.yaml`、
默认关闭的 `delivery.yaml` 与空的 `regression.yaml`。
- [ ] 旧项目缺少 `knowledge.yaml` 时,只补空文件及缺失的
`project.knowledgeFile` 指针,没有重跑初始化或覆盖其它项目状态。
+16 -13
View File
@@ -2,7 +2,8 @@
本文件定义**与具体编排工具无关**的三角色协作闭环。运行时调度可以用 Orca(见 `orca-adapter.md`),也可以手动跑(见下方「手动模式」)。
原则:调度消息只是运行时载体,任务结论必须回写到 `tasks.yaml`;已经验证且可跨
原则:调度消息只是运行时载体,任务结论必须追加到 `task-records/`(由读取层
materialize 成任务视图);已经验证且可跨
任务使用的项目经验必须由 Coordinator 回写到 `knowledge.yaml`。不要把消息当最终记录。
角色定义见 `roles-and-permissions.md`:Coordinator 只编排、Test 只验证、
Developer 只实现。
@@ -15,12 +16,12 @@ Developer 只实现。
| 抽象动作 | 含义 | Orca 实现 | 手动实现 |
|----------|------|-----------|----------|
| `prepare(task)` | Coordinator 把任务和验收信号写进 `tasks.yaml`,按 scope 推荐知识并确认显式 `knowledgeRefs` | 同左 | 同左 |
| `prepare(task)` | Coordinator 把任务和验收信号写进 `task-records/`,按 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` | 同左 | 同左 |
| `writeback(task, result)` | Coordinator 把任务结果追加到 `task-records/`,把验证通过的跨任务经验按权限写入 `knowledge.yaml` | 同左 | 同左 |
派发用的 prompt 见 `prompt-templates.md`。状态流转见 `roles-and-permissions.md` §「任务状态机」。**独立复测由 Test 执行,不是 Coordinator**;Coordinator 只做读证据的终检。
@@ -30,14 +31,14 @@ Developer 只实现。
```text
Coordinator 发现或读取 open 任务
-> prepare:写/补全 tasks.yaml 验收信号
-> prepare:写/补全 task-records/ 中的任务验收信号
-> 从 knowledge.yaml 按 scope 推荐 active 知识,Coordinator 确认固定 revision 的 knowledgeRefs
-> 为新轮次生成稳定 attemptId(<task-id>-A<round>),Developer 与 Test 共用
-> 决定 worktree:当前 worktree 起子 agent,还是新建隔离 worktree(见下节「子任务放哪」)
-> 解析安全 profile:机器配置只读 agents.yaml(存在时),否则读取 tasks.yaml.project.orchestration
-> 运行 launcher plan 并审阅 launchFingerprint
-> 检查同轮空闲 worker;可信清理历史消息成功才复用,否则带 expected fingerprint 启动 fresh worker
-> 把本次 task/attempt receipt 写回 tasks.yaml(见 orca-adapter.md)
-> 把本次 task/attempt receipt 追加到 task-records/(见 orca-adapter.md)
-> dispatch 给 Developer(--to <worker handle>)
-> 确认 Developer 已开始执行(terminal read 确认任务注入;未开始按环境失败处理)
-> wait:滚动 check --wait + 定期 worker_probe(识别审批/未回车/额度停滞)
@@ -133,7 +134,7 @@ python3 <ack-skill-dir>/scripts/launch_worker.py launch \
- 适合:串行闭环、一次一个 Developer 任务、小改动、Test 要复测的正是 Developer 改的那棵树。
- 优点:单一服务实例、无跨 worktree 对齐困扰、开销小。
- 风险:多个 agent 同时改同一棵树会互相踩(半构建状态、git 冲突)。
- 记录:`launch` 成功后把 receipt 追加到权威 `tasks.yaml.workerReceipts`,并把
- 记录:`launch` 成功后把 receipt 追加到当前任务记录的 `workerReceipts`,并把
`receipt.id` 写入 `dispatch.<role>.receiptId`、把 `profileId` 写入
`dispatch.<role>.profileId`、把本轮稳定 ID 写入 `dispatch.<role>.attemptId`;
receipt 的 task/role/profile/attempt 必须与当前 dispatch 完全一致,不能只记录
@@ -173,9 +174,10 @@ python3 <ack-skill-dir>/scripts/launch_worker.py launch \
| 要保持基线分支干净 | 新 worktree(feature 分支)|
| 小改动、追求快 | 当前 worktree |
**项目状态(SSOT)只落一处**:无论开几个 worktree,`tasks.yaml`、
**项目配置 SSOT 只落一处**:无论开几个 worktree,`tasks.yaml`、
`knowledge.yaml`、可选 `delivery.yaml` 和可选 `regression.yaml` 都只认一个权威
副本(通常在基线/协调所在 worktree)。Coordinator 单写任务、知识、回归目录、
副本(通常在基线/协调所在 worktree)。任务执行状态追加到
`.pouch/ack/task-records/<recordId>.yaml`;Coordinator 单写任务记录、知识、回归目录、
`deliveryRuns` 与 `regressionRuns`;交付能力只在显式配置维护时修改。`project.orchestration`、顶层 `workerReceipts` 和任务 dispatch 也只写入这个
副本;不要每个 worktree 各留一份会分叉的项目状态。profile 解析、launcher 与
receipt 规则见 `model-routing.md` 和 `orca-adapter.md`。
@@ -190,20 +192,20 @@ v0.10 的 full-access 授权与撤销机制仍是 Deferred;launcher 遇到 ful
没有编排工具时,闭环不变,只是 `dispatch` / `wait` 由人工承担:
1. Coordinator 在 `tasks.yaml` 写好任务和验收信号。
1. Coordinator 在 `task-records/` 写入包含完整任务快照的初始记录和验收信号。
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`。
6. Coordinator 做终检并追加新记录:通过 `verified`,不过 `failed_retest`。
7. 产品失败则用「复测失败再派发模板」重新发给 Developer,最多累计三轮有效产品
复验;环境失败写入 `dispatch.environmentIncidents`,恢复环境后重新派发 Test,
不派 Developer、不消耗产品轮次。
手动模式下同样遵守:worker_done / 复测报告都不等于最终结论、只有 Coordinator
写 `tasks.yaml` 和 `knowledge.yaml`、三轮失败留档。若本次确认计划还包含交付,所有
写 `task-records/` 和 `knowledge.yaml`、三轮失败留档。若本次确认计划还包含交付,所有
选中任务 `verified` 后由 Coordinator 继续按 `delivery.md` 执行并写 `deliveryRuns`。
手动交给用户已打开的会话不等于产生 ACK receipt。该会话可以完成本次显式 handoff,
@@ -233,7 +235,7 @@ actual:
snapshot evidence:
```
Test 只回传证据,不写 `tasks.yaml` 或 `knowledge.yaml`;由 Coordinator 落盘。
Test 只回传证据,不写 `task-records/` 或 `knowledge.yaml`;由 Coordinator 追加落盘。
每条适用的显式 `knowledgeRef` 还应报告 `passed`、`failed` 或
`not_applicable` 及证据。
@@ -277,7 +279,8 @@ worktreePath:
## 结果回写
Coordinator 回写 `tasks.yaml` 时按状态填写(字段结构见 `templates/tasks.schema.json`):
Coordinator 追加任务记录时按状态填写(记录内的 `task` 字段结构见
`templates/tasks.schema.json`):
```yaml
# 通过(Test 复测 + Coordinator 终检)
+2 -2
View File
@@ -3,7 +3,7 @@
本文件定义可选的 `verified -> validation_ready/review_ready/released` 交付阶段。开发、独立复测和
Coordinator 终检仍由 ACK 原有闭环负责;只有选中的任务全部 `verified` 后才能进入
交付。项目配置位于 `.pouch/ack/delivery.yaml`,运行证据写入
`.pouch/ack/tasks.yaml.deliveryRuns`。
任务记录的 `deliveryRuns`(读取时 materialize 到任务视图)。
## 1. 配置与授权不是一回事
@@ -78,7 +78,7 @@ intents:
口头「发版」不能代替 stable/production 的 `approval` 步骤。
- 对应 intent 为 `null` 或交付未启用:停止,请用户说明怎么做,按「交付配置维护」
写入同一文件后再执行。不猜测 Makefile、镜像仓库或发布通道。
- 用户触发的 intent 运行写入 `tasks.yaml.deliveryRuns`,`intent` 填
- 用户触发的 intent 运行追加到任务记录的 `deliveryRuns`,`intent` 填
`testEnvironment` 或 `release`,`taskIds` 可为空。测试环境 run 的 `profile` 记
`deployer-<env>`。绑定任务的常规交付 run 不填 `intent`,仍只能引用
`verified` 任务。
+2 -2
View File
@@ -33,7 +33,7 @@
2. 写产品文档到 docs/(PRD / 交互 / 验收),把需求拆成任务,每个任务的验收写成可观测信号(可见文本 / API 结果 / 交互结果)。
3. 按任务 scope 从 knowledge.yaml 推荐 active 知识,确认后把固定 revision 的
knowledgeRefs 写入任务;不要派发 candidate 或全量知识库。
4. 把任务写进 .pouch/ack/tasks.yaml(只有你写),校验 tasks.yaml 和 knowledge.yaml。
4. 把任务作为完整快照追加到 `.pouch/ack/task-records/`(只有你写),校验任务视图和 knowledge.yaml。
5. 先把「产品文档 + 任务拆分 + 验收信号 + 适用知识引用」给我确认;若启用了交付,
同时列明本次 profile、目标、停止点与审批步骤。不要急着派发或交付。
6. 我确认后,按 ack 闭环循环:先用 `scripts/launch_worker.py` 校验结构化
@@ -41,7 +41,7 @@
只有历史消息已可信清理并取得新会话身份才复用,否则审阅 plan 后用 expected
fingerprint 创建 fresh worker;
dispatch 开发 → worker_done → 若 intents.testEnvironment 已启用则先用 deployer 拉起测试环境 →
dispatch 测试独立复测 → 你读证据终检 → 回写 tasks.yaml;
dispatch 测试独立复测 → 你读证据终检 → 追加 task-records;
每个任务最多三轮有效产品复验,三轮不过记 leftover 并升级我复盘;环境失败单独
记录、恢复并告诉我下一步,不占产品复验轮次。
7. 所选任务都 verified 后,按 SKILL.md「运行回归」给出新增/更新/退役/无回归,确认后写入
+6 -5
View File
@@ -2,7 +2,8 @@
Orca orchestration 是运行时调度层的一种实现。闭环流程本身与工具无关(见 `closed-loop.md`);本文件只提供 Orca 的具体命令。没有 Orca 时用 `closed-loop.md` §「手动模式」。
所有结论仍以 `tasks.yaml` 为准,Orca 消息不是最终记录。
所有结论仍以读取层 materialize 的任务视图为准,底层最终记录追加在
`task-records/`;Orca 消息不是最终记录。
---
@@ -96,7 +97,7 @@ Orca 后端并完成终端绑定;Coordinator 不自行执行或拼装 Orca 的
标准输出是单一 JSON。成功后:
1. 校验返回 receipt 的 `receiptHash`;
2. 把 receipt 原样追加到 `tasks.yaml.workerReceipts`;
2. 把 receipt 原样追加到当前任务的新记录的 `workerReceipts`;
3. 把 `receipt.id` 写入当前任务 `dispatch.<role>.receiptId`,把 `profileId` 写入
`dispatch.<role>.profileId`,把本轮 `<task-id>-A<round>` 写入
`dispatch.<role>.attemptId`;校验器会要求 receipt 的 task/role/profile/attempt
@@ -129,7 +130,7 @@ 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 tasks.yaml and knowledge.yaml.
- 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
@@ -324,7 +325,7 @@ orca orchestration send \
无 `retest_result` 类型时用 `--type worker_done`,靠 subject `retest round <n>`
区分。收到无错误的 Test 复测结果后,先回收 Test 对应的 Orca terminal,再由
Coordinator 按 `closed-loop.md` 做终检并回写 `tasks.yaml`:
Coordinator 按 `closed-loop.md` 做终检并追加任务记录:
```bash
python3 <ack-skill-dir>/scripts/reclaim_workers.py \
@@ -334,7 +335,7 @@ python3 <ack-skill-dir>/scripts/reclaim_workers.py \
只有成功结果才能执行该命令;失败、环境异常或需要继续复验时保留 terminal。
收到复测结果后,Coordinator 按 `closed-loop.md` 做终检并回写 `tasks.yaml`;
收到复测结果后,Coordinator 按 `closed-loop.md` 做终检并追加任务记录;
通过独立验证和 gate 的跨任务经验再由 Coordinator 写入 `knowledge.yaml`。任务通过
写 `verified`;观察到产品信号失败写 `failed_retest`;环境无法完成则写
`dispatch.environmentIncidents`,保持或恢复为 `fixed_by_dev`,不占复验轮次。
+2 -2
View File
@@ -10,10 +10,10 @@
项目状态是 `.pouch/ack/regression.yaml`。任务板用
`project.regressionFile: .pouch/ack/regression.yaml` 声明,运行证据写在
`tasks.yaml.regressionRuns`。新项目初始化会生成空目录;旧项目没有该文件时,
任务记录的 `regressionRuns`(读取时 materialize 到任务视图)。新项目初始化会生成空目录;旧项目没有该文件时,
「运行回归」先停下来,用户授权后再从模板补齐。
只有 Coordinator 写 `regression.yaml`。Test 在复测报告里提名
只有 Coordinator 写 `regression.yaml` 和任务记录。Test 在复测报告里提名
`regressionCandidates`;用户确认后 Coordinator 落盘,并把 case id 写入任务的
`regressionRefs`。不要把用例散落到第二份文档,也不要让 Test 直接改
`.pouch/ack/`。
@@ -12,12 +12,12 @@ ACK 默认三个独立 Agent:**Coordinator 只编排、Test 只验证、Develo
| 角色 | 主要职责 | 验证方式 | 不应做的事 |
|------|----------|----------|------------|
| Coordinator (PM) | 需求拆解、定验收信号、排优先级、单写 `tasks.yaml` / `knowledge.yaml` / `regression.yaml`、选择知识、向 Developer/Test 派发、跑三轮闭环、做最终 gate;经确认后编排可选交付与回归 | 读 Test 证据并对齐原始意图(不亲自跑测试);核对交付与回归证据 | 修改源码、亲自复测、凭 worker_done 直接标 `verified`、自动激活未验证知识、把配置当作发布授权 |
| Coordinator (PM) | 需求拆解、定验收信号、单写 `task-records/` / `knowledge.yaml` / `regression.yaml`、选择知识、向 Developer/Test 派发、跑三轮闭环、做最终 gate;经确认后编排可选交付与回归 | 读 Test 证据并对齐原始意图(不亲自跑测试);核对交付与回归证据 | 修改源码、亲自复测、凭 worker_done 直接标 `verified`、自动激活未验证知识、把配置当作发布授权 |
| Test | 黑盒复测、回归验证、执行知识检查、独立验证知识候选、沉淀可执行测试、产出证据 | 浏览器、API、集成脚本、用户可见行为 | 修改应用源码、修改产品规格、写 `tasks.yaml` 或 `knowledge.yaml` |
| Developer | 实现修复、写单元测试、运行构建和白盒验证、提名项目知识 | 单元测试、类型检查、构建、本地运行 | 修改产品规格与集成测试、写项目状态、标记 `verified`、绕过测试声称完成 |
| User / Decision Owner | 决定范围、优先级、阻塞项是否继续 | 审阅报告和遗留清单 | 直接替代复测证据 |
**独立验证权归 Test。** Coordinator 不亲自复测,它读 Test 的证据,并对照任务的原始意图做一次终检(见「完成定义」)。`worker_done` 不等于完成的原则同时适用于 Developer 和 Test:结论只有落到 `tasks.yaml` 才算数。
**独立验证权归 Test。** Coordinator 不亲自复测,它读 Test 的证据,并对照任务的原始意图做一次终检(见「完成定义」)。`worker_done` 不等于完成的原则同时适用于 Developer 和 Test:结论只有追加到 `task-records/` 才算数。
**模型档位(正交层)。** 三角色默认按成本分层:Coordinator 用强模型,Test 与 Developer 用中低模型,必要时升级。完整档位表与升级规则见 `model-routing.md`。Coordinator 用强模型但不跑测试,这一分工天然省 token 又不破坏「验证者 ≠ 实现者」。
@@ -108,7 +108,8 @@ ACK 默认三个独立 Agent:**Coordinator 只编排、Test 只验证、Develo
| `<unit_test_paths>` | Read-only | Read-only | R/W | 单元测试 |
| `<shared_config_templates>` | Read-only | Read-only | R/W | 可提交配置模板 |
| `<local_config>` | Read-only | Read-only | Read-only | 本地私有配置,不提交 |
| `tasks.yaml` | R/W | Read-only | Read-only | 见下方「项目状态写入约定」 |
| `tasks.yaml` | R/W | Read-only | Read-only | 只保存稳定项目配置;任务状态见 `task-records/` |
| `task-records/` | R/W | Read-only | Read-only | 见下方「项目状态写入约定」 |
| `knowledge.yaml` | R/W | Read-only | Read-only | Coordinator 单写;Developer/Test 通过回报提名或验证 |
| `regression.yaml` | R/W | Read-only | Read-only | Coordinator 单写;Test 通过 `regressionCandidates` 提名 |
| `delivery.yaml` | 仅显式维护时 R/W | Read-only | Read-only | 声明项目交付能力,不保存凭据或执行授权 |
@@ -143,7 +144,7 @@ launch / service / data / browser / tooling environment failure
-> 环境恢复后 retesting
```
状态定义(所有状态都只由 Coordinator 写入 `tasks.yaml`,来源不同):
状态定义(所有状态都只由 Coordinator 追加到 `task-records/`,来源不同):
| 状态 | 依据来源 | 含义 |
|------|----------|------|
@@ -179,11 +180,11 @@ planned -> skipped
## 项目状态写入约定(并发安全)
`tasks.yaml` 是任务、交付运行与回归运行事实源,`knowledge.yaml` 是跨任务项目知识
事实源,`regression.yaml` 是黑盒回归用例事实源,`delivery.yaml` 是项目交付能力
事实源。为避免多 Agent 并发写冲突:
`task-records/` 是任务、交付运行与回归运行事实源,`tasks.yaml` 是稳定项目配置,
`knowledge.yaml` 是跨任务项目知识事实源,`regression.yaml` 是黑盒回归用例事实源,
`delivery.yaml` 是项目交付能力事实源。为避免多 Agent 并发写冲突:
- **只有 Coordinator 写 `tasks.yaml`、`knowledge.yaml` 和 `regression.yaml`**。
- **只有 Coordinator 写 `task-records/`、`knowledge.yaml` 和 `regression.yaml`**。
Test 与 Developer 对它们都是只读的。
- Developer 的实现状态、Test 的复测证据都通过消息回传(`worker_done` / 复测报告),由 Coordinator 落盘。
- Developer 和 Test 只能通过 `knowledgeCandidates` 提名知识;candidate 保存在