Files
laily ef22c6829e refactor(skills): slim ack/builder/deployer for layered loading
Move mode-specific steps into references so SKILL.md only keeps routing and fail-closed rules.
2026-08-26 11:26:58 +08:00
..
2026-08-25 15:23:48 +08:00
2026-08-25 15:23:48 +08:00
2026-08-25 15:23:48 +08:00

ACK

ACK 是一个显式调用的 Agent Skill,用三种独立角色运行工程协作闭环:

  • Coordinator 拆解需求、派发任务并终检。
  • Developer 实现并执行白盒验证。
  • Test 独立执行黑盒复测。

关键约束是验证者不等于实现者。每个任务最多修复三轮,仍未通过时记录为 leftover,然后继续处理其它任务。

测试环境部署由 ACK 触发、内部调用 deployer 执行。发版仍写在同一份 .pouch/ack/delivery.yaml。功能或 bug 验证通过后,把黑盒用例收进 .pouch/ack/regression.yaml;之后可以单独跑回归。

ACK 只在用户显式调用 /ack$ack 时运行。

使用场景

场景 怎么说 结果
初始化 /ack 初始化 生成并补全 .pouch/ack/;缺项按统一格式列出
检查 /ack 检查配置 只读校验,默认不改文件;测试环境缺 deployer 时转交
做需求 /ack 处理这个需求:… 产品文档 + 拆任务 → 确认 → 三角色闭环
修 bug /ack 修这个 bug:… 或处理飞书收件 短描述 + 验收 → 确认(飞书须你点「已确认」)→ 同一闭环
交付配置 说明怎么布测试环境 / 怎么发版 写入同一份 delivery.yaml;测试环境绑定 deployer
运行测试环境 /ack 重新布测试环境 内部加载 deployer,布 .pouch/deployer/<env>
运行版本发布 /ack 发布一个版本 intents.releasestable/生产仍要单独批准
回归 /ack 回归 先布测试环境,再按 regression.yaml 用浏览器或 API 跑

做需求和修 bug 在 verified 之后,都要更新回归目录。

安装

全局安装:

pouch add ack -g

或只安装到当前项目:

pouch add ack

初始化项目

pouch init ack
pouch init ack --project ~/code/my-app

初始化后,项目只保存自己的 ACK 状态:

.pouch/ack/
├── project.md
├── tasks.yaml
├── knowledge.yaml
├── delivery.yaml       # 默认 enabled: false
└── regression.yaml     # 默认 cases: []

不会在项目中复制或链接 ACK Skill。通用规范、模板和脚本始终从已安装的 Skill 目录读取。

ACK 从当前命令指定的 --project-root/.pouch/ack/ 定位项目状态,不要求在 tasks.yaml 中持久化 repoPathdevWorktree。自动 worker 的实际工作目录由 --worktree 指定;默认在 --project-root 工作,v0.19 起不再配置 allowedWorktrees 白名单。

Skill 结构

skills/ack/
├── SKILL.md
├── README.md
├── VERSION
├── references/     # 三角色规范、闭环流程和初始化说明
├── templates/      # project.md、tasks.yaml、knowledge.yaml、delivery.yaml、regression.yaml 模板和 schema
├── examples/       # 完整示例
└── scripts/        # 状态校验、任务/知识/回归选择、安全验证执行与结构化 worker launcher

SKILL.md 是 Agent 的工作流入口。references/ 是按需读取的稳定规范; .pouch/ack/project.md 只保存当前项目的命令、路径和权限差异; .pouch/ack/tasks.yaml 保存当前任务状态;.pouch/ack/knowledge.yaml 保存跨任务复用、 已经独立验证的项目知识护栏。 .pouch/ack/delivery.yaml 是测试环境绑定和版本发布的唯一契约;测试环境由 ACK 内部调用 deployer,运行证据记在 tasks.yaml.deliveryRuns.pouch/ack/regression.yaml 是黑盒回归用例目录,运行证据记在 tasks.yaml.regressionRuns

检查项目状态

Agent 会从当前 ACK Skill 目录解析校验脚本:

python3 <ack-skill-dir>/scripts/validate_tasks.py .pouch/ack/tasks.yaml
python3 <ack-skill-dir>/scripts/validate_knowledge.py .pouch/ack/knowledge.yaml \
  --tasks .pouch/ack/tasks.yaml
python3 <ack-skill-dir>/scripts/validate_delivery.py .pouch/ack/delivery.yaml \
  --tasks .pouch/ack/tasks.yaml --project-root <project-root>
python3 <ack-skill-dir>/scripts/validate_regression.py .pouch/ack/regression.yaml \
  --tasks .pouch/ack/tasks.yaml

Coordinator 可以按当前任务上下文做确定性推荐:

python3 <ack-skill-dir>/scripts/select_tasks.py .pouch/ack/tasks.yaml
python3 <ack-skill-dir>/scripts/select_tasks.py .pouch/ack/tasks.yaml \
  --task-id BUG-001

python3 <ack-skill-dir>/scripts/select_knowledge.py .pouch/ack/knowledge.yaml \
  --component web --path web/app.py --tag long-running-service --limit 10

python3 <ack-skill-dir>/scripts/select_regression.py .pouch/ack/regression.yaml
python3 <ack-skill-dir>/scripts/select_regression.py .pouch/ack/regression.yaml \
  --suite full --case-id REG-login-001

任务选择器会解析并执行完整任务板的内置语义校验,但只输出 projectsummary、 默认可工作状态或显式 --task-id 命中的任务,以及这些任务引用的 receipt 和 delivery run。默认最多 20 条,超过预算时显式失败;Agent 不应回退为把完整 tasks.yaml 注入 上下文。

默认 JSON 输出会同时给出固定知识引用和已解析的 verificationTarget.path/args 选择器只输出数据,不执行检查。scope.all=true 的全项目 active 规则优先占用 --limit;如果全项目规则本身超过预算,选择器会显式失败,不会静默漏派。

需要执行知识项引用的检查时,只传 registry ID 给 ACK 的安全执行入口:

python3 <ack-skill-dir>/scripts/run_verification.py \
  .pouch/ack/knowledge.yaml check-api-contract --project-root <project-root>

该入口会在执行前重新校验知识库,只打开一次项目根目录 fd,再从同一个 fd 逐段以 O_NOFOLLOW 打开知识库和检查文件;检查内容复制到匿名、尽可能 sealed 的稳定 快照,再以结构化 argv 和 shell=False 启动。它不接受临时命令或额外参数。 选择器输出的 path/args 只用于审阅,不应由 Agent 自行拼接执行。Runner 只读取 项目内无 symlink 的权威 .pouch/ack/knowledge.yaml,不接受替代知识文件或放宽后的项目根。检查进程的 cwd 和 ACK_PROJECT_ROOT 都固定到该根 fd;后者是只在检查进程存活期间有效的 /proc/self/fd/.../dev/fd/... 路径。原始可读路径另放在 ACK_PROJECT_ROOT_DISPLAY,只能用于日志,不能用于资源访问。Runner 还提供 ACK_VERIFICATION_REFACK_VERIFICATION_PATH;检查脚本必须据此定位资源, 不能依赖 $0__file__ 所在目录,因为实际执行的是匿名快照。

知识先由 Developer 或 Test 作为 candidate 提名,经独立验证和 Coordinator gate 后才能成为 active。Coordinator 按路径、组件、依赖、版本和标签推荐相关知识, 确认后将固定 revision 的 knowledgeRefs 写入任务上下文;每轮只派发命中的少量 条目,不全量注入知识库。

旧项目只有 project.mdtasks.yaml 时,不要重跑初始化。由 /ack 检查现有 状态,获得用户授权后补一个空的 knowledge.yaml;如果任务板尚未声明知识库, 同时只补 project.knowledgeFile: .pouch/ack/knowledge.yaml,再运行跨文件校验。

只有 Coordinator 写 tasks.yamlknowledge.yamlregression.yaml。知识正文 不能作为自由 shell 执行;关键约束应继续下沉到测试、lint、CI 或正式规范。ACK 不自动修改项目的 AGENTS.mdCLAUDE.md 或其它 Agent 指令文件。

配置与运行交付

测试环境走 deployer 的项目内布局(通常是 .pouch/deployer/test),发版仍用 delivery profile。可以直接说:

/ack 测试环境用项目里的 .pouch/deployer/test;发版方式以后再告诉你。

ACK 把测试环境写成 intents.testEnvironment.via: deployer,把发版写成 intents.release 指向的 profile。.pouch/deployer/<env> 还没就绪时,ACK 会转去 deployer 的初始化,而不是自己编 compose。首次配置保持关闭,确认后才启用。 之后可以说:

/ack 重新布一下测试环境,我要测试
/ack 发布一个版本

对应 intent 未配置时先问清楚并写回同一文件,不猜测。运行测试环境时 ACK 加载 deployer skill,不复制 compose 命令。本地进程启动写在 project.md,不算这个 模式。intent 运行不要求当前有 verified 任务;deliveryRuns.intent 记录是 测试环境还是发版。

交付配置只允许声明式工具 target 或仓库内可执行脚本,不接受自由 shell,也不保存 凭据值。任务进入 verified 后的常规交付仍按确认过的 profile 执行。默认 profile 只能停在 validation_readyreview_ready;稳定发布或生产部署必须经过 对应 approval 步骤。具体契约见 references/delivery.md

启动 Worker

worker 的机器配置位于 tasks.yaml.project.orchestration:项目显式维护模型 allowlist、结构化 profile、默认 profile 和允许的 worktree。不得在 project.md 或任务里保存完整启动命令、额外 argv 或环境变量。

先审阅计划,不产生终端:

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 \
  --profile-id codex-dev-standard \
  --worktree <allowed-worktree>

确认后执行 launch,并显式绑定刚审阅的 fingerprint

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 \
  --profile-id codex-dev-standard \
  --worktree <allowed-worktree> \
  --expected-launch-fingerprint <plan 中的 sha256:...>

launcher 是自动创建 worker 的唯一入口:它从权威任务板重读 profile,构造固定 argv,忽略调用者 PATH、使用环境 allowlist,并验证真实 Git worktree 注册;然后 通过仓库外的单次启动记录、terminal-bound nonce/proof 和受限 bootstrap 调用 Orca。 返回的 receipt 含 runtimeId、handle、incarnation、profile hash、slot 和 worktree identity。Coordinator 将 receipt 追加到顶层 workerReceipts,再把 receipt ID 写入任务的 dispatch.developerdispatch.test,并同步写入本轮 attemptId。 校验器要求 receipt 与当前 ACK task、角色、profile 和 attempt 完全一致;历史 receipt 不能跨任务或跨轮次改挂。

v0.10 自动 launcher 仅支持 read-onlyworkspace-write。full-access、 Codex bypass、Cursor YOLO/force、Grok --yolo / bypassPermissions 和关闭 sandbox 都会 fail closed;在有可信平台审批或独立签发通道之前,不用项目文件 伪装成用户授权。Grok worker 由 launcher 固定带 --always-approve,避免工具调用 停在确认框,sandbox 仍必须启用。v0.17 起 cli: grok 是一等 worker CLIcli: omp 使用 OMP 的结构化模型、thinking 和 approval-mode 参数,workspace-write 默认 yolo。旧任务板没有结构化 project.orchestration 时仍可读取和手动协作,但不得自动创建 worker。

持久化 receiptHash 是无密钥 checksum,不是 launcher 身份证明。ACK 只复用同一轮 内明确空闲、角色/profile/worktree 匹配,并且可以可信清理历史消息、取得新会话身份的 worker;正在执行、等待回报、状态不明或关联未完成任务的 worker 不复用。由于当前 Orca 没有可验证的历史消息清理接口,Orca 派发仍重新 plan 并用 expected fingerprint 启动 fresh worker。 fingerprint 只校验完整计划没有漂移,不是一次性令牌;成功后不得用同一 fingerprint 重复启动,结果不确定时必须先 reconcile。 若创建或关闭回执不完整,或外部 launch record 状态无法可靠持久化,launcher 会返回 indeterminate/reconcile-required;必须先核对 record 与 Orca live state,不能 直接重试。

Coordinator 最后标记整轮任务完成后,会关闭所有只关联 verified 任务的 worker 终端。仍关联 blockedfailed_retestleftover、其它未完成任务或未解决环境事件 的终端继续保留且不设置 TTL;receipt 与测试证据不会随终端删除。

开始一个需求

初始化完成后可以直接说:

/ack 处理这个需求:<一句话需求>

Coordinator 会先读取项目状态和 references/kickoff.md,生成产品文档、任务拆分与 可观测验收信号;用户确认后才派发实现和复测。任务 verified 后会把本轮黑盒路径 收进 .pouch/ack/regression.yaml,确认后才写入。

修复 bug

可以直接说:

/ack 修这个 bug<现象、复现、期望>

Coordinator 写短问题说明、复现步骤和可观测验收,不写大 PRD;你确认后再派发。 Developer 先补会失败的用例再修,后续闭环与做需求相同。

配了飞书 bugIntake 时,飞书是审核前的唯一协作区。你只需维护标题、详细描述和 附件;Coordinator 整理问题说明、期望效果和验收标准并写回飞书。你针对当前 revision 审核通过,并亲自把状态改成「已确认」之前,不创建任务、不派 worker。

/ack 处理飞书里待整理的 bug

运行回归

平时做需求和修 bug 结束后,ACK 按本轮内容更新 .pouch/ack/regression.yaml。 之后可以单独跑:

/ack 回归
/ack 跑 full 回归
/ack 回归 REG-login-001

ACK 先按 deployer 布测试环境,再派独立 Test 按用例用浏览器或 API 执行。失败只 报告,不会自动开修;要修再说 /ack 修这些回归失败。默认跑 smoke。细则见 references/regression.md

首次配置交付可以说:

/ack 更新项目交付配置:用 make build-deb 构建 DEB,发布到 preview APT 仓库,
部署到 test-server 并跑健康检查;完成后创建 PR,停在 review_ready 给我审核。

之后处理需求时只需在确认计划中选择 profile:

/ack 处理这个需求:<一句话需求>。任务验证通过后执行 review profile。

ACK 会自动读取 delivery.yaml,无需再逐步提醒它构建、上传、部署或开 PR;目标或 权限发生漂移、缺少凭据、进入 stable/production approval 时才停下来请求决策。

版本

当前 Skill 版本见 VERSION。新项目在 tasks.yaml 中以合法 SemVer 记录 ackVersion。从 0.10.0 起,project.orchestration 与顶层 workerReceipts 必须 同时存在;从 0.11.0 起,新项目还会生成默认关闭的 delivery.yaml,并在任务板声明 project.deliveryFiledeliveryRuns;从 0.13.0 起,Coordinator 使用 select_tasks.py 获取有预算的任务上下文,不再把完整任务板注入模型;从 0.16.0 起, delivery.yaml 可用 intents.testEnvironmentintents.release 把测试环境部署和 版本发布写成用户可单独触发的操作;从 0.17.0 起,结构化 worker 路由支持 cli: grok(与 Codex、Cursor 并列);从 0.18.0 起支持 OMP 的 cli: omp profile(精确 provider/model、thinking 与 approval-mode);从 0.17.1 起 Grok worker argv 固定带 --always-approvesandbox 仍必开;从 0.19.0intents.testEnvironment 改为 deployer 绑定,ACK 内部调用 deployer skill 布测试环境,并增加 .pouch/ack/regression.yaml 与「运行回归」模式。旧的测试环境 profile ID 字符串不再 执行,需要迁到 {via: deployer, env: <env>}。旧项目可以不迁移回归目录而继续使用 原闭环。旧项目的 kitVersion 可以继续读取,但建议迁移为 ackVersion