Files
.pouch/docs/ack-design-review.md
T
laily f3cd56b78e feat: rename skills/skiff to pouch and move ACK state under .pouch
Use ~/.pouch, the pouch CLI, and .pouch.yaml as the SSOT container.
Keep the inner skills/ packages, and store ACK project state in
.pouch/ack instead of docs/ack.
2026-08-25 15:20:02 +08:00

34 KiB
Raw Blame History

title, date, updated
title date updated
ACK 设计评审记录 2026-07-31T17:15:37+08:00 2026-07-31T23:31:48+08:00

ACK 设计评审记录

这是对 ACK v0.8.1 的设计评审快照,用于推动后续版本改进。文中的文件行号对应 2026-07-31 的仓库状态,不作为 ACK 的运行规范。

本文同时记录后续方案和实施结果。带“建议”“目标”或“待验证”的内容默认是设计 方向,不代表当前版本已经具备;实际运行契约仍以 skills/ack/SKILL.md、schema、 校验器和测试为准。知识护栏方案的 v0.9.0 落地边界、model-routing v0.10.0 的 实施结论见下文状态表。

背景

本轮评审覆盖 skills/ack/ 的入口、角色规范、闭环流程、项目模板、任务板 schema、校验脚本、Orca 适配器,以及 pouch init ack 的真实运行路径。

评审主要回答两个问题:

  • ACK 的三角色协作方向是否合理。
  • 当前实现是否已经能稳定完成初始化、派发、独立复测、状态恢复和结果审计。

结论

ACK 的核心方向合理。显式触发、三角色分权、可观测验收、用户确认、Test 独立 复测、Coordinator 单写任务板和三轮止损都值得保留。

当前版本适合描述为“任务级受监督验收闭环”。它可以组织单个工作空间里的实现和 复测,但还没有覆盖批准状态持久化、跨 worktree 交接、编排状态恢复、目标分支集成 和交付状态,因此暂时不应把 verified 等同于“已集成”或“已交付”。

概念设计约为 8/10,当前可操作性约为 5 至 6/10。下一阶段应该补齐控制面契约, 不需要推翻三角色模型。

值得保留的设计

  • Coordinator、Developer 和 Test 的职责分开,Developer 不能给自己的实现做最终 判定。
  • 新需求先写产品文档、任务拆分和可观测验收信号,用户确认后再派发。
  • tasks.yaml 由 Coordinator 单写,worker 消息只负责传递证据。
  • Test 在复测前核对 worktree、服务实例和构建产物,减少测错代码和旧进程造成的 假通过。
  • 每个任务最多三轮,失败后进入 leftover,不会无限消耗同一个 worker。
  • 通用规范留在 Skill,项目只保存覆盖层与任务状态。
  • 闭环核心不依赖 Orca,手动模式仍能保留相同的角色与验收逻辑。

P0:状态和证据必须先成为可验证协议

verified 目前可以没有证据

roles-and-permissions.md 定义的完成条件包括 Developer 白盒证据、Test 独立证据、 环境对齐和 Coordinator 终检,但任务 schema 只强制 idtitlestatus。 内置校验器同样没有检查 verified 所需的证据。

本轮探针确认,下面这种任务可以通过内置校验:

version: 1
project:
  name: demo
tasks:
  - id: T-1
    title: hollow green
    status: verified

相关位置:

  • skills/ack/templates/tasks.schema.json:76
  • skills/ack/scripts/validate_tasks.py:70
  • skills/ack/references/roles-and-permissions.md:140

建议为不同状态定义语义约束。verified 至少要求:

  • Developer 的修改文件、验证命令和结果。
  • 独立 Test 的身份、逐条验收结果和原始证据。
  • 被测代码或构建产物的不可变指纹。
  • worktree、服务进程、Base URL 和测试时间。
  • Coordinator 的 gate 结果与写入时间。

用户确认没有持久化

Skill 要求用户确认后再派发,但状态机从 open 直接进入 dispatched。会话在确认前 中断后,新的 Coordinator 无法知道任务是待确认,还是已经批准。

建议增加 proposedapproved,并记录 approvedAtapprovedBy 与验收版本。

推荐状态流

proposed
  -> approved
  -> implementing
  -> retesting
  -> verified_in_workspace
  -> integrated
  -> verified

blocked
  -> approved
  -> cancelled

product_failed x 3
  -> leftover

verified_in_workspace 只说明指定工作空间中的代码已经通过独立复测。只有目标分支 集成并完成集成后验证,才能进入最终 verified

P0:Orca 适配器需要改成双任务模型

当前文档让 Developer 对一个 Orca task 发送 worker_done,然后把同一个 task 再次 派给 Test。截至评审日期,当前 Orca 的 orchestration 规则会在收到有效 worker_done 后自动把 task 和 dispatch 标记为 completed。第二次派发同一个 task 缺少可靠的生命周期语义。

相关位置:

  • skills/ack/references/orca-adapter.md:144
  • skills/ack/references/orca-adapter.md:164
  • skills/ack/references/orca-adapter.md:199

建议每个 ACK attempt 创建两个 Orca 子任务:

ACK task
  Developer task
  Test task, depends on Developer task

任务板分别保存:

devTaskId: null
devDispatchId: null
testTaskId: null
testDispatchId: null

Developer 和 Test 都对自己的 dispatch 发送 worker_doneCoordinator 最后只读 证据并执行 gate。

P0:明确 worktree 和代码交接方式

当前流程先在 Coordinator worktree 写 PRD 和 tasks.yaml,随后才决定是否创建隔离 worktree。权威任务板只保留在 Coordinator worktree,但 worker prompt 又要求在自己 的 worktree 读取相对路径。Developer 的未提交代码如何传给独立的 Test worktree 也没有定义。

相关位置:

  • skills/ack/references/kickoff.md:30
  • skills/ack/references/closed-loop.md:65
  • skills/ack/references/closed-loop.md:87
  • skills/ack/references/prompt-templates.md:31
  • skills/ack/references/orca-adapter.md:74

建议默认让 Developer 和 Test 串行使用同一个 worktree。必须隔离时,在 attempt 中 明确:

transfer:
  type: commit | patch | artifact
  source: "<immutable reference>"
  digest: "<sha256 or diff hash>"

派发内容应携带验收快照和规范的绝对路径,不能假设每个 worktree 都有同一份未提交 文档。

P0:Worker 启动策略改为安全默认

v0.10 已以结构化 profile 和可信 launcher 取代本节描述的自由 command。下方是 当时的评审记录,不再代表当前实现;其中“full-access 写入任务板授权”的建议已被 v0.10 决策取代,当前明确为 Deferred。

当前校验器强制 Codex 使用 bypass、Cursor 使用 YOLO,并写死模型和 CLI。项目文档 允许收紧权限或替换模型,但合法的安全覆盖会被校验器拒绝。

校验器还只检查自由 shell 字符串里的部分 token。本轮探针确认,带有 shell 控制符 和额外命令的字符串仍可通过校验。这样的结果会给调用方错误的安全感。

相关位置:

  • skills/ack/scripts/validate_worker_command.py:49
  • skills/ack/references/model-routing.md:98
  • skills/ack/templates/project.template.md:31

建议把项目覆盖层改成结构化配置:

orchestration:
  mode: orca

workers:
  developer:
    cli: codex
    model: "<project-approved-model>"
    effort: medium
    permissionMode: sandbox
  test:
    cli: codex
    model: "<project-approved-model>"
    effort: low
    permissionMode: sandbox

可信代码根据这些字段构造 argv,不接受自由 shell 拼接。安全模式默认通过。 原建议设想 full-access 由用户单独授权并写入任务板;v0.10 没有实现这条授权通道, 项目文件也不能充当授权证据。full-access 的可信授权、期限、撤销和外层隔离均为 Deferred,当前 launcher 必须 fail closed。

P0:初始化需要原子化

pouch init ack 会先写 project.mdtasks.yaml,再运行任务板校验。缺少 PyYAML 时,命令会失败但保留两个文件。再次运行又会因为拒绝覆盖而失败。

相关位置:

  • requirements.txt:1
  • skills/ack/scripts/validate_tasks.py:37
  • pouch/cli.py:1144
  • pouch/cli.py:1156

本轮在不含第三方包的隔离 Python 环境中复现了这个状态。

建议:

  • 在临时目录渲染和校验,全部通过后再原子 rename。
  • 失败时只清理由本次调用创建的临时文件。
  • 提供 pouch init ack --repair 或等价恢复路径。
  • 默认模板使用 tasks: [],完整示例继续放在 examples/
  • CLI 输出“脚手架已创建,待配置”,检查通过后再称为“初始化完成”。

P1:任务板改成追加式 attempts

当前 dispatch.rounds 只记录轮次、结果和一段证据,无法支持恢复、并发和审计。 建议改成追加式 attempts[]

attempts:
  - id: "T-1-A1"
    round: 1
    idempotencyKey: "<stable key>"
    startedAt: "<timestamp>"
    workspace:
      path: "<worktree>"
      baseCommit: "<sha>"
      diffHash: "<hash>"
    developer:
      worker: "<identity>"
      taskId: "<runtime task id>"
      dispatchId: "<runtime dispatch id>"
      evidence: {}
    test:
      worker: "<independent identity>"
      taskId: "<runtime task id>"
      dispatchId: "<runtime dispatch id>"
      evidence: {}
    gate:
      result: pending | passed | failed
    failureKind: null

failureKind 建议区分:

  • product_failed:实现不满足验收,消耗三轮预算。
  • environment_blocked:环境或服务不可用,不消耗轮次。
  • needs_decision:需要用户决定范围,不消耗轮次。
  • acceptance_invalid:验收标准有误,返回 proposed
  • worker_lostworker 消失,由 Coordinator 重新派发。

外部 dispatch 前先持久化 intent。Coordinator 重启后,用 idempotencyKey 和 runtime ID 查询 Orca,再决定继续等待、恢复状态或重新派发。

P1:统一 schema 和语义校验

安装 jsonschema 时,validate_tasks.py 只运行 schema;未安装时只运行内置规则。 两条路径的约束不同。schema 会放过重复 ID、四轮 dispatch 和空 leftoverReason,内置规则也会放过部分错误结构。

建议:

  • 始终先执行 schema,再无条件执行语义 invariant。
  • structuralready 提供两个显式模式。
  • ready 模式检查状态对应的证据、环境、批准和轮次。
  • 显式传入的 schema 路径不存在时直接失败,不能静默降级。
  • summarytasks 派生,避免双写。
  • 收紧 additionalProperties,扩展字段统一放入 extensions

P1:补齐完成边界和批次验证

ACK 默认不提交、不推送。隔离 worktree 中的任务即使复测通过,也可能尚未进入目标 分支。最终报告需要明确区分:

  • 已在指定工作空间验证。
  • 已集成到目标分支。
  • 已完成集成后回归。
  • 已提交、已推送或已发布。

多个任务分别通过后,还需要一次批次级集成回归,避免组合后出现冲突或行为变化。

P2:减少规范重复和模型漂移

  • 保留一份权威状态机、一份角色权限表和一份模型档位规则。
  • kickoff.md 只做一页运行手册,adapter 只保存工具命令。
  • 具体模型名称放到可更新的映射或项目覆盖层,稳定核心只描述能力档位和升级条件。
  • ackVersion 不能只记录旧版本。需要独立的 schemaVersion、兼容范围和迁移命令。
  • 用真实运行数据观察首轮通过率、环境失败率、平均轮次、leftover 原因、耗时和 token,再决定三轮规则是否需要按任务风险调整。
  • 为低风险文档或机械改动提供轻量模式,高风险和用户可见行为继续使用完整三角色 闭环。

低成本清理

  • skills/ack/SKILL.md:66 的旧字段应为 kitVersion
  • skills/ack/templates/project.template.md:8 建议修改或替换 AGENTS.md,与 Skill 的禁止规则冲突。
  • skills/ack/references/orca-adapter.md:201 应引用 prompt §4。
  • skills/ack/scripts/validate_worker_command.py:2 残留 “Music Pilot”。
  • skills/ack/examples/tasks.example.yaml 缺少 checklist 要求的 overlayFile
  • Test 负责黑盒与集成测试,Developer 负责单元测试;当前优化文档对单元测试所有权 的表述需要统一。

建议实施顺序

  1. 收紧任务状态、批准状态和 verified 证据门。
  2. 把 Orca adapter 改成每轮 Developer/Test 双任务。
  3. 定义同 worktree 默认策略和跨 worktree transfer。
  4. 改造 worker launcher 与安全授权。
  5. 原子化 pouch init ack,空任务板作为默认模板。
  6. 引入追加式 attempts、幂等恢复和失败分类。
  7. 统一 schema 与语义校验,补齐对抗性 fixture。
  8. 区分工作空间验证、集成验证和发布状态。
  9. 去重文档,补版本迁移和运行指标。

验证记录

本轮执行了:

  • pouch check ack:通过。这个命令只证明 Skill 的元数据和基础结构有效。
  • validate_tasks.py examples/tasks.example.yaml:通过,当前机器使用内置规则。
  • validate_worker_command.py --self-test7 项通过。
  • python3 -m unittest discover -s tests -v58 项通过。
  • 隔离全局安装 smoke:通过,安装结果为指向 ACK SSOT 的 symlink。
  • 隔离初始化探针:缺少 PyYAML 时失败,留下半初始化文件,重试被拒绝。
  • 对抗性任务板探针:无证据的 verified 可以通过。
  • 对抗性 worker 命令探针:附加 shell 控制符的命令字符串可以通过。
  • 当前 Orca orchestration 指南复核:有效 worker_done 会自动完成对应 task 和 dispatch。

现有 ACK 测试主要覆盖字符串、Skill 元数据和初始化冒烟,没有覆盖状态机语义、 schema 与 fallback 一致性、Orca 双阶段生命周期、Coordinator 崩溃恢复和跨 worktree 代码交接。

待验证

  • 用真实项目跑一轮同 worktree 的 Developer/Test 闭环。
  • 用独立 worktree 验证 commit、patch 和 artifact 三种交接方式。
  • 验证 Coordinator 在 task-create、dispatch 和 Test 完成三个时间点崩溃后的 恢复行为。
  • 为安全 worker profile、路径 containment 和 shell 注入增加对抗性测试。
  • 定义 ACK v0.9 的 schema 迁移策略,再决定是否保留旧状态名称。

扩展方案:项目知识护栏库

v0.9.0 落地边界

能力 v0.9.0 状态
knowledge.yaml 模板、schema、初始化和跨文件校验 已实现
active/stale/superseded/archived、作用域、冲突、复查时间和来源校验 已实现
确定性选择、全项目规则优先、固定 revision 引用 已实现
registry ID + 结构化 argv + fd 固定根目录的安全检查入口 已实现
Developer candidate、Test check、Coordinator 单写的协作约定 已实现为协议和校验字段
不同 revision 的历史内容不可篡改或可独立恢复 延后;v0.9.0 没有外部不可变账本
依赖或路径变化后自动转 stale 延后;当前由 reviewAfter 和人工复核驱动
在运行时强制只有获授权身份能写入或激活知识 延后;当前依赖 Coordinator 单写边界
自动识别任意提示注入、PII 或所有秘密 延后;当前只有结构禁区和常见秘密模式
approved、追加式 attempts、崩溃恢复和最终集成 gate 延后到控制面改造

定位

ACK 需要增加第三类项目事实,用来保存跨任务复用、会改变后续开发或验证行为的已 验证知识。它不保存聊天记忆,也不承担项目 Wiki 的职责。

项目事实 保存内容 写入者
project.md 相对稳定的项目配置、路径和命令 Coordinator 或项目维护者
tasks.yaml 当前任务状态、attempt 和执行证据 Coordinator
knowledge.yaml 跨任务复用的已验证经验 Coordinator

建议新增项目级 SSOT.pouch/ack/knowledge.yaml。知识归项目所有,与 Orca 等编排 工具无关;ACK 负责在任务闭环中生产、选择和消费这些知识。

这项设计会修改当前“.pouch/ack/ 只保存 project.mdtasks.yaml”的边界。 新增文件保存项目事实,不复制 ACK Skill 的通用规范,因此不违反 Skill 内容仍以 skills/ack/ 为 SSOT 的原则。

知识类型

第一版只支持三类知识:

类型 含义 例子
guardrail 必须执行或明确禁止的项目约束 修改数据库迁移时必须验证回滚
pitfall 已证实的失败模式、触发条件和避免方法 Test 连到了另一个 worktree 的旧服务
verification 特定条件下必须增加的检查 修改缓存键后执行跨版本兼容测试

架构决策正文继续写入 ADR 或正式规格,知识项只引用决策及其适用条件。任务进度和 单次失败证据继续留在 tasks.yaml。通用且可跨项目复用的规则应回流 ACK Skill, 不能作为某个项目的知识长期保存。

生命周期

Developer / Test 发现经验
  -> candidate
  -> Test 独立验证 + Coordinator gate
  -> active
  -> stale
  -> superseded | archived
  • Developer 和 Test 只能提交 candidate,不能直接写入或激活知识。
  • candidate 保存在当前 task 或 attempt 的证据中,不参与后续任务的自动选择。
  • 根因得到证实、修复通过独立 Test、Coordinator 完成 gate 后,candidate 才能转为 active
  • 全项目范围的 mustnever 或权限类规则需要 User 或 Decision Owner 确认。
  • 依赖、配置、路径或适用版本发生变化后,相关知识转为 stale,默认不再派发。
  • 新知识替代旧知识时必须记录 supersedes,不能静默改写历史。
  • 临时 workaround 必须有复查时间和移除条件,不能无限期保持 active

同一 Agent 不能把自己读到的旧知识直接作为新证据再次激活。新的 candidate 必须 包含当前任务产生的独立观测,避免形成自我强化的错误闭环。

最小数据结构

每条知识至少包含:

id: K-001
revision: 1
kind: pitfall
status: active
title: "复测前确认服务来自当前 worktree"

scope:
  components: [web]
  paths: ["web/**"]
  dependencies: []
  versions: []
  tags: [long-running-service]

appliesWhen: "修改常驻 Web 服务或前端构建产物"
directive: "复测前重启服务,并核对服务实例对应的 commit"
rationale: "曾因复测旧进程产生假通过"

verification:
  ref: service-worktree-alignment
  expected: "服务实例、worktree 和 commit 一致"

provenance:
  taskId: BUG-017
  attemptId: BUG-017-A2
  codeRef: "<commit or tree hash>"
  evidenceRef: "tasks.yaml#BUG-017"

owner: "<owner>"
author: "<candidate author>"
reviewer: "<independent reviewer>"
createdAt: "<timestamp>"
lastValidatedAt: "<timestamp>"
reviewAfter: "<timestamp or null>"
removalCondition: null
supersedes: []
conflictsWith: []

revision 是逻辑版本标识。修改知识的约束含义时必须新增 revision,并保留被引用 的旧条目;任务引用 K-001@1 后,可以说明当时选择的逻辑版本。v0.9.0 尚未用 content hash、签名或外部账本封存条目内容,因此不能只凭这个字符串证明历史字节 不可变;项目需要把状态纳入版本控制,强不可变审计留待后续实现。

directive 只能描述应采取的动作。需要执行命令时,verification.ref 应引用项目中 已审查的测试或检查 ID,由可信配置解析成结构化 argv。知识库不保存可自动执行的 自由 shell 命令。

与三角色闭环的集成

角色 权限和职责
Coordinator 单写 knowledge.yaml;选择本轮适用知识;激活、废弃和处理冲突
Developer 只读本轮知识;回报遵守情况;提交 knowledgeCandidates
Test 只读本轮知识;执行额外检查;独立验证 candidate
User / Decision Owner 批准全项目强制规则、权限规则和无法通过测试证明的政策

prepare(task) 时,Coordinator 按 component、path、dependency、version、tag 和失败 特征筛选 active 知识。匹配结果只作为候选,Coordinator 确认后把固定版本引用 写入本轮上下文:

knowledgeRefs:
  - K-001@1
  - K-014@2

引入前文建议的追加式 attempts[] 后,引用和回报建议放在:

attempts[].context.knowledgeRefs
attempts[].developer.knowledgeApplied
attempts[].developer.knowledgeCandidates
attempts[].test.knowledgeChecks

派发时把已引用知识的必要内容内联到 Developer 和 Test 的 prompt,避免 worker 因 worktree 不同而读不到 Coordinator worktree 中未提交的知识文件。每次只派发当前 任务命中的少量条目,不全量注入知识库。

Developer 回报实际遵守了哪些知识,以及新发现的 candidate。Test 对每条适用的 verification 回报 pass、fail 和证据。要求执行的知识检查没有覆盖时, Coordinator 不得把任务写成 verified_in_workspaceverified

检索和冲突规则

第一版使用确定性匹配,不引入向量数据库、Embedding 或语义 RAG

  • 先按 path、component、dependency、version 和 tag 选择条目。
  • 失败排查时可以额外匹配错误签名和相关 symbol。
  • 只返回 active 且适用条件成立的条目。
  • 设置条目数和上下文预算,详情按需读取。scope.all=true 的全项目规则优先占用 预算;全项目规则本身超过预算时显式失败,不能静默丢弃。
  • stalesupersededarchived 默认不返回。
  • 没有匹配结果只表示本轮没有找到知识,不能据此声称项目没有相关约束。

同一 subject 和 scope 不能存在互相矛盾的 active 条目。校验器发现冲突时应阻止 进入 ready 状态,由 Coordinator 或 Decision Owner 选择保留项并记录 supersedes。运行时不能使用“最后写入者获胜”解决冲突。

自动匹配只负责推荐。Coordinator 写入当前 attempt 的显式 knowledgeRefs 才是 本轮权威上下文。这个边界可以降低作用域标注不准造成的漏选和误选。

知识晋升后的去向

知识库不是所有经验的最终归宿。不同内容应继续进入对应的权威载体:

内容 最终位置
当前任务状态和单次验证证据 tasks.yaml
稳定项目路径、命令和运行配置 project.md
架构或产品决策及其取舍 ADR 或正式规格
安全、正确性和兼容性约束 测试、lint、CI 或正式规范
原始日志、截图和构建产物 受控 artifact 存储
跨项目通用规则 ACK Skill
项目特有且跨任务复用的经验 knowledge.yaml

关键 verification 应逐步转成可执行测试或 CI gate。知识项继续保存触发条件、原因 和证据引用,不能用自然语言规则替代可执行控制。

禁止写入的内容

  • Token、密钥、Cookie、含凭据 URL、生产数据、PII、客户内容和未脱敏日志。
  • 系统提示、开发者提示、角色或权限覆盖,以及绕过审批、测试和安全限制的指令。
  • 可自动执行的破坏性命令或生产命令。
  • 原始聊天、整段 issue 或网页内容、巨量日志、截图和构建产物。
  • 未复现猜测、LLM 单方推断、一次性巧合和个人评价。
  • PID、临时端口、个人 worktree 绝对路径等短命机器状态。
  • 对代码、配置和正式文档的重复抄写。
  • 没有作用域、证据和失效条件的 alwaysnever 或 workaround。
  • 需要权限隔离的漏洞 PoC、敏感内部拓扑和安全调查材料。

issue、日志和外部网页只能作为不可信 evidence。进入知识库前必须提炼为可审查的 项目结论,不能原样晋升,也不能获得高于用户指令、批准规格、当前代码、配置和测试 的优先级。

第一版范围

第一版只实现一个 .pouch/ack/knowledge.yaml,不拆目录。活跃条目达到几十条、单文件 开始影响审阅和选择时,再平滑迁移为 .pouch/ack/knowledge/index.yaml 加独立知识卡, 条目 schema 和引用格式保持不变。

第一版包括:

  1. knowledge.yaml schema 与语义校验。
  2. task 或 attempt 的 knowledgeRefs
  3. Developer 的 knowledgeAppliedknowledgeCandidates
  4. Test 的 knowledgeChecks
  5. Coordinator 在 prepare、gate 和任务收尾三个节点处理知识。
  6. 基于 scope 的确定性匹配。
  7. stale、冲突、revision 和 supersedes 校验。

第一版不包括:

  • 自动抓取或总结全部对话。
  • Agent 自动激活、删除或提交知识。
  • 向量数据库、Embedding 和语义 RAG。
  • 自动改写 AGENTS.mdCLAUDE.md 或其它 Agent 指令文件。
  • 从知识正文直接执行 shell 命令。
  • 组织级、跨仓库知识同步。

目标验收与当前状态

目标 v0.9.0 状态
candidate 不会作为 active 派发 已实现
未授权 worker 不能激活、废弃或删除知识 协议约束;运行时身份授权延后
path、component、version 只返回匹配条目 已实现确定性匹配;准确率仍取决于 scope 标注
非 active 条目默认不返回 已实现
冲突 active 规则被拒绝 已实现显式冲突和相同 subject/scope 检查
历史 attempt 的知识内容不可变 延后;当前只有 revision 约定,没有不可变账本
verification.ref 无法解析时校验失败 已实现
evidence 中的提示注入不会变成命令 部分实现;禁止自由执行字段,语义晋升仍需人工 gate
秘密和生产数据不能进入知识库 部分实现;常见秘密模式会阻断,不能替代完整 DLP
依赖、路径变化后自动转 stale 延后;当前依赖复查日期和 Coordinator
增长后仍在预算内且不漏全项目规则 已实现;全项目规则超预算时显式失败

与 ACK 改造顺序的关系

知识护栏库最终仍依赖可信的任务状态、attempt、证据来源和 ready 校验。v0.9.0 先 落地存储、选择和基础 gate,不能据此声称前述控制面问题已经解决。后续应继续:

  1. 确定知识 schema、生命周期和角色权限。
  2. 在 attempt 中固定 knowledgeRefs 和 candidate 证据。
  3. 接入 Coordinator 的匹配、派发和晋升流程。
  4. 增加 stale、冲突、权限、注入和敏感信息的对抗性 fixture。
  5. 选一个真实项目试运行,再根据活跃条目数量决定是否拆分存储。

这套方案最依赖 scope 标注的质量。项目知识如果很难用组件、路径、依赖、版本或 触发条件限定,自动匹配会漏掉关键项或产生大量噪声。这类知识应继续由人维护在 ADR 或项目文档中,不能强行进入自动派发流程。

v0.10.0 实施结论:结构化 model-routing

当前决策

旧的 validate_worker_command.py --command '<shell>' 只能检查少量 token,无法证明 整段 shell 没有追加命令、重复参数、环境注入或 cwd 漂移。v0.10 删除这条自由命令 配置面:旧脚本只保留 fail-closed 迁移提示;自动 worker 的唯一入口是 launch_worker.py profile-hash|plan|launch

机器 SSOT 固定为 tasks.yaml.project.orchestration。profile 只声明 role、CLI、 tier、model、reasoning effort 和 permission modemodel 必须命中按 CLI/role/tier 分组的 allowlist。自动权限只允许 read-onlyworkspace-writefull-access、Codex bypass、Cursor YOLO/force 和关闭 sandbox 全部 fail closed。

已落地约束

控制面 v0.10.0 实现
自由 command / extra argv / env / cwd schema 与语义校验拒绝;旧 validator fail closed
Agent argv worker_profiles.py 按 profile 生成唯一 argv;子进程 shell=False
plan → launch 漂移 launch 强制接收刚审阅的 --expected-launch-fingerprintslot 也纳入 hash
PATH / loader / 凭据串用 不按调用者 PATH 找可执行文件;固定可信目录;控制进程无供应商凭据,worker 使用 per-cli-allowlist-v1
worktree 冒充 绝对规范路径、无 symlink、同 Git common-dir,并命中 git worktree list -z
Orca command 注入 --command 只含固定 bootstrap 和随机 launch ID
bootstrap 抢跑 先绑定 runtime/handle/incarnation/worktree,再用 terminal stdin nonce/proof 授权
cleanup / bootstrap 竞态 Popen 前在同一 record lock 内复核 awaiting 状态;cleanup 先发生则拒绝启动 Agent
create 部分失败 取得确定 handle 前的超时、transport/解码异常、中断、非零、畸形/缺字段响应均记为 indeterminate,禁止自动重试
handle 后失败清理 record 写失败不阻断 close;只有 terminal close --tab --json 完整匹配且最终 failed 状态可靠落盘才记普通失败,否则保持 indeterminate/reconcile-required
receipt 漂移 规范化 profileHash、argvHash、slot、launchFingerprint 与 receiptHash 交叉校验
dispatch 旧 receipt 改挂 每个角色显式记录 attemptIdreceipt 必须绑定当前 ACK task.id、同 role/profile/attemptreceiptId/attemptId 同空同填
配置兼容 ackVersion 必须是合法 SemVerv0.10+ 的 orchestration/workerReceipts 必须同时存在,v0.9 旧板仍可只读校验和手动协作

不能被弱证明掩盖的边界

receiptHash 是无密钥 checksum,不是签名。项目内可写方能修改 receipt 后重算 hash;而当前 Orca terminal metadata 不提供原始 Agent argv、模型或权限 attestation。因此 v0.10 不根据持久化 receipt 自动复用旧终端。每次自动派发都 重新执行 plan,并用 expected fingerprint 启动 fresh worker;持久化 receipt 只作 审计和 dispatch 关联。

launchFingerprint 只证明完整计划没有漂移,不是一次性授权或幂等键;同一计划重复 执行仍会创建新的 fresh terminal。成功后不得重放,结果不确定时必须先 reconcile。 自动防重放要依赖后端原子 idempotency/claim 或项目外可信 launch intent,不能由 checksum 伪装提供。

任务板里的 dispatch 关联也不是宽松的历史索引。dispatch.<role> 显式记录 profileIdreceiptIdattemptId,校验器要求 receipt 的 createdFor 精确绑定 当前 ACK tasks[].id、同一角色和同一 attempt,并要求 profile 一致。该约束阻止把 旧任务、旧角色或旧轮次 receipt 改挂到当前 dispatch,但不会把无密钥 receipt 升级成 可信 attestation。

同样,receipt 证明的是 launcher 请求和本地 CLI/runtime 绑定,不证明模型供应商最终 执行的模型。开放自动复用需要 Orca/ACP 提供启动参数 attestation,或项目外可信签发 与校验通道。开放 full-access 还需要不可由项目文本伪造的用户授权、期限、撤销和外层 隔离。这两项均留待后续版本。

威胁模型也明确到 Coordinator 账户边界:v0.10 防止任务板、任务内容、普通环境和 受限 worker 把数据变成第二个启动命令入口;不抵御已经完全控制 Coordinator OS 账户、Orca runtime、受信 Agent/Orca 可执行文件或用户级 Agent 配置/插件/MCP 的 攻击者。permissionMode 也不是模型供应商或外部工具能力 attestation;后者必须依赖 独立 OS 身份、受控 Agent 配置或平台能力。

后续版本提案:ACP 与可替换编排后端

当前决策

ACK 当前版本继续以 Orca 作为唯一自动编排后端。闭环语义保持工具无关,但 worker 创建、终端身份绑定、dispatch 和 wait 的可执行适配仍由 Orca 完成。

ACPAgent Client Protocol)作为后续版本的优先候选,当前只记录方案,不加入运行 时依赖、不新增半成品 adapter,也不让现有流程在 Orca 与 ACP 之间自动猜测。

能力 当前版本 后续方向
自动创建并监督 worker Orca ACP capability negotiation 后可增加 ACP adapter
结构化模型与权限 profile ACK 自己定义,Orca 只承载启动 保持为 ACK 稳定契约,不交给后端自由解释
dispatch / wait / terminal identity Orca runtime handle 映射到 ACP session / request / event identity
无自动后端时运行闭环 手动模式 可增加 PTY / Zellij 类低层 fallback,但不冒充语义协议
后端选择 项目显式配置 未来仍需显式配置,不按已安装命令静默切换

后端无关的最小语义

未来 adapter 只应实现以下能力,不应接管 ACK 的角色、状态机或安全策略:

  1. createWorker(profile, worktree):按 ACK 已验证的结构化 profile 创建 worker。
  2. inspectWorker(identity):返回可绑定的 runtime、session/incarnation 和活性。
  3. dispatch(identity, taskContext):把一个明确任务投递给已验证 worker。
  4. wait(identity, eventTypes):等待完成、复测、升级或 decision gate 事件。
  5. closeWorker(identity):只关闭本次创建且身份仍匹配的 worker。

模型、reasoning effort、权限模式、worktree 和 receipt hash 仍由 ACK 校验。adapter 不能重新开放自由 shell、任意 argv、任意环境变量或“后端默认模型”作为旁路。

ACP 采用门槛

满足以下条件后再实现 ACP adapter

  • 目标 Agent CLI 对 ACP 的启动、会话身份、取消和事件语义足够稳定。
  • 能把 Developer/Test 的独立身份、worktree 和结构化 profile 映射到可核对字段。
  • 能区分“已请求的模型/权限”和“运行时可观测事实”,不把客户端请求冒充供应商证明。
  • 超时、重连、重复 dispatch 和 runtime 重启具有明确的幂等或恢复语义。
  • 与 Orca adapter 使用同一组 ACK conformance tests,且不会降低安全默认。

在这些门槛满足前,ACP 保持 Deferred。PTY 或 Zellij 一类方案只能作为较低层的 进程/终端承载,不提供 session 语义、模型证明或任务状态机;如果以后加入,也必须 经过独立 adapter,不能散落为文档中的自由命令。

参考依据