269 lines
12 KiB
Markdown
269 lines
12 KiB
Markdown
# ACK
|
||
|
||
ACK 是一个显式调用的 Agent Skill,用三种独立角色运行工程协作闭环:
|
||
|
||
- Coordinator 拆解需求、派发任务并终检。
|
||
- Developer 实现并执行白盒验证。
|
||
- Test 独立执行黑盒复测。
|
||
|
||
关键约束是验证者不等于实现者。每个任务最多修复三轮,仍未通过时记录为
|
||
`leftover`,然后继续处理其它任务。
|
||
|
||
项目还可以在同一份 `docs/ack/delivery.yaml` 里声明测试环境部署和版本发布。
|
||
用户告诉 ACK 这两件事怎么做之后,再说「重新布测试环境」或「发布一个版本」,
|
||
ACK 按对应 intent 执行。任务全部验证后仍可按 profile 做常规交付。配置默认关闭,
|
||
稳定发布与生产部署始终保留人工批准点。
|
||
|
||
## 安装
|
||
|
||
全局安装:
|
||
|
||
```bash
|
||
skiff add ack -g
|
||
```
|
||
|
||
或只安装到当前项目:
|
||
|
||
```bash
|
||
skiff add ack
|
||
```
|
||
|
||
ACK 只在用户显式调用 `/ack` 或 `$ack` 时运行。
|
||
|
||
## 初始化项目
|
||
|
||
```bash
|
||
skiff init ack
|
||
skiff init ack --project ~/code/my-app
|
||
```
|
||
|
||
初始化后,项目只保存自己的 ACK 状态:
|
||
|
||
```text
|
||
docs/ack/
|
||
├── project.md
|
||
├── tasks.yaml
|
||
├── knowledge.yaml
|
||
└── delivery.yaml # 默认 enabled: false
|
||
```
|
||
|
||
不会在项目中复制或链接 ACK Skill。通用规范、模板和脚本始终从已安装的 Skill
|
||
目录读取。
|
||
|
||
ACK 从当前命令指定的 `--project-root/docs/ack/` 定位项目状态,不要求在
|
||
`tasks.yaml` 中持久化 `repoPath` 或 `devWorktree`。自动 worker 的实际工作目录仍由
|
||
`--worktree` 指定,并且必须命中绝对路径白名单 `allowedWorktrees`。
|
||
|
||
## Skill 结构
|
||
|
||
```text
|
||
skills/ack/
|
||
├── SKILL.md
|
||
├── README.md
|
||
├── VERSION
|
||
├── references/ # 三角色规范、闭环流程和初始化说明
|
||
├── templates/ # project.md、tasks.yaml、knowledge.yaml、delivery.yaml 模板和 schema
|
||
├── examples/ # 完整示例
|
||
└── scripts/ # 状态校验、任务/知识选择、安全验证执行与结构化 worker launcher
|
||
```
|
||
|
||
`SKILL.md` 是 Agent 的工作流入口。`references/` 是按需读取的稳定规范;
|
||
`docs/ack/project.md` 只保存当前项目的命令、路径和权限差异;
|
||
`docs/ack/tasks.yaml` 保存当前任务状态;`docs/ack/knowledge.yaml` 保存跨任务复用、
|
||
已经独立验证的项目知识护栏。
|
||
`docs/ack/delivery.yaml` 是测试环境部署和版本发布的唯一契约,也声明常规构建、
|
||
发布和部署能力;每次执行结果另记在 `tasks.yaml.deliveryRuns`。
|
||
|
||
## 检查项目状态
|
||
|
||
Agent 会从当前 ACK Skill 目录解析校验脚本:
|
||
|
||
```bash
|
||
python3 <ack-skill-dir>/scripts/validate_tasks.py docs/ack/tasks.yaml
|
||
python3 <ack-skill-dir>/scripts/validate_knowledge.py docs/ack/knowledge.yaml \
|
||
--tasks docs/ack/tasks.yaml
|
||
python3 <ack-skill-dir>/scripts/validate_delivery.py docs/ack/delivery.yaml \
|
||
--tasks docs/ack/tasks.yaml --project-root <project-root>
|
||
```
|
||
|
||
Coordinator 可以按当前任务上下文做确定性推荐:
|
||
|
||
```bash
|
||
python3 <ack-skill-dir>/scripts/select_tasks.py docs/ack/tasks.yaml
|
||
python3 <ack-skill-dir>/scripts/select_tasks.py docs/ack/tasks.yaml \
|
||
--task-id BUG-001
|
||
|
||
python3 <ack-skill-dir>/scripts/select_knowledge.py docs/ack/knowledge.yaml \
|
||
--component web --path web/app.py --tag long-running-service --limit 10
|
||
```
|
||
|
||
任务选择器会解析并执行完整任务板的内置语义校验,但只输出 `project`、`summary`、
|
||
默认可工作状态或显式 `--task-id` 命中的任务,以及这些任务引用的 receipt 和 delivery
|
||
run。默认最多 20 条,超过预算时显式失败;Agent 不应回退为把完整 `tasks.yaml` 注入
|
||
上下文。
|
||
|
||
默认 JSON 输出会同时给出固定知识引用和已解析的 `verificationTarget.path/args`;
|
||
选择器只输出数据,不执行检查。`scope.all=true` 的全项目 active 规则优先占用
|
||
`--limit`;如果全项目规则本身超过预算,选择器会显式失败,不会静默漏派。
|
||
|
||
需要执行知识项引用的检查时,只传 registry ID 给 ACK 的安全执行入口:
|
||
|
||
```bash
|
||
python3 <ack-skill-dir>/scripts/run_verification.py \
|
||
docs/ack/knowledge.yaml check-api-contract --project-root <project-root>
|
||
```
|
||
|
||
该入口会在执行前重新校验知识库,只打开一次项目根目录 fd,再从同一个 fd 逐段以
|
||
`O_NOFOLLOW` 打开知识库和检查文件;检查内容复制到匿名、尽可能 sealed 的稳定
|
||
快照,再以结构化 argv 和 `shell=False` 启动。它不接受临时命令或额外参数。
|
||
选择器输出的 path/args 只用于审阅,不应由 Agent 自行拼接执行。Runner 只读取
|
||
项目内无 symlink 的权威
|
||
`docs/ack/knowledge.yaml`,不接受替代知识文件或放宽后的项目根。检查进程的 cwd
|
||
和 `ACK_PROJECT_ROOT` 都固定到该根 fd;后者是只在检查进程存活期间有效的
|
||
`/proc/self/fd/...` 或 `/dev/fd/...` 路径。原始可读路径另放在
|
||
`ACK_PROJECT_ROOT_DISPLAY`,只能用于日志,不能用于资源访问。Runner 还提供
|
||
`ACK_VERIFICATION_REF` 和 `ACK_VERIFICATION_PATH`;检查脚本必须据此定位资源,
|
||
不能依赖 `$0` 或 `__file__` 所在目录,因为实际执行的是匿名快照。
|
||
|
||
知识先由 Developer 或 Test 作为 `candidate` 提名,经独立验证和 Coordinator gate
|
||
后才能成为 `active`。Coordinator 按路径、组件、依赖、版本和标签推荐相关知识,
|
||
确认后将固定 revision 的 `knowledgeRefs` 写入任务上下文;每轮只派发命中的少量
|
||
条目,不全量注入知识库。
|
||
|
||
旧项目只有 `project.md` 和 `tasks.yaml` 时,不要重跑初始化。由 `/ack` 检查现有
|
||
状态,获得用户授权后补一个空的 `knowledge.yaml`;如果任务板尚未声明知识库,
|
||
同时只补 `project.knowledgeFile: docs/ack/knowledge.yaml`,再运行跨文件校验。
|
||
|
||
只有 Coordinator 写 `tasks.yaml` 和 `knowledge.yaml`。知识正文不能作为自由 shell
|
||
执行;关键约束应继续下沉到测试、lint、CI 或正式规范。ACK 不自动修改项目的
|
||
`AGENTS.md`、`CLAUDE.md` 或其它 Agent 指令文件。
|
||
|
||
## 配置与运行交付
|
||
|
||
用户可以直接向 `/ack` 说明两件独立操作,并写进同一份契约:
|
||
|
||
```text
|
||
/ack 测试时先 go build -o garden ./cmd/garden,再启动这个二进制;
|
||
发版方式以后再告诉你。
|
||
```
|
||
|
||
ACK 把它维护成 `docs/ack/delivery.yaml` 的 `intents.testEnvironment` /
|
||
`intents.release`、entrypoint、artifact、environment 和 profile。首次配置保持
|
||
关闭,确认后才启用。之后用户可以说:
|
||
|
||
```text
|
||
/ack 重新布一下测试环境,我要测试
|
||
/ack 发布一个版本
|
||
```
|
||
|
||
对应 intent 未配置时先问清楚并写回同一文件,不猜测。intent 运行不要求当前有
|
||
`verified` 任务;`deliveryRuns.intent` 记录是测试环境还是发版。
|
||
|
||
交付配置只允许声明式工具 target 或仓库内可执行脚本,不接受自由 shell,也不保存
|
||
凭据值。任务进入 `verified` 后的常规交付仍按确认过的 profile 执行。默认
|
||
profile 只能停在 `validation_ready` 或 `review_ready`;稳定发布或生产部署必须经过
|
||
对应 approval 步骤。具体契约见 `references/delivery.md`。
|
||
|
||
## 启动 Worker
|
||
|
||
worker 的机器配置位于 `tasks.yaml.project.orchestration`:项目显式维护模型
|
||
allowlist、结构化 profile、默认 profile 和允许的 worktree。不得在 `project.md`
|
||
或任务里保存完整启动命令、额外 argv 或环境变量。
|
||
|
||
先审阅计划,不产生终端:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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.developer` 或 `dispatch.test`,并同步写入本轮 `attemptId`。
|
||
校验器要求 receipt 与当前 ACK task、角色、profile 和 attempt 完全一致;历史 receipt
|
||
不能跨任务或跨轮次改挂。
|
||
|
||
v0.10 自动 launcher 仅支持 `read-only` 与 `workspace-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 CLI;`cli: 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
|
||
终端。仍关联 `blocked`、`failed_retest`、`leftover`、其它未完成任务或未解决环境事件
|
||
的终端继续保留且不设置 TTL;receipt 与测试证据不会随终端删除。
|
||
|
||
## 开始一个需求
|
||
|
||
初始化完成后可以直接说:
|
||
|
||
```text
|
||
/ack 处理这个需求:<一句话需求>
|
||
```
|
||
|
||
Coordinator 会先读取项目状态和 `references/kickoff.md`,生成产品文档、任务拆分与
|
||
可观测验收信号;用户确认后才派发实现和复测。
|
||
|
||
首次配置交付可以说:
|
||
|
||
```text
|
||
/ack 更新项目交付配置:用 make build-deb 构建 DEB,发布到 preview APT 仓库,
|
||
部署到 test-server 并跑健康检查;完成后创建 PR,停在 review_ready 给我审核。
|
||
```
|
||
|
||
之后处理需求时只需在确认计划中选择 profile:
|
||
|
||
```text
|
||
/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.deliveryFile` 与 `deliveryRuns`;从 `0.13.0` 起,Coordinator 使用
|
||
`select_tasks.py` 获取有预算的任务上下文,不再把完整任务板注入模型;从 `0.16.0` 起,
|
||
`delivery.yaml` 可用 `intents.testEnvironment` 与 `intents.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-approve`,sandbox 仍必开。旧项目可以不迁移而继续使用原闭环。旧项目的
|
||
`kitVersion` 可以继续读取,但建议迁移为 `ackVersion`。
|