From afbdde157f9633ac5fdab933ff9fc0a62272d35a Mon Sep 17 00:00:00 2001 From: laily Date: Tue, 28 Jul 2026 17:08:33 +0800 Subject: [PATCH] feat: add explicit ack workflow skill --- AGENTS.md | 1 + README.md | 1 + skills/ack/SKILL.md | 93 +++++++++++++++++++++++++++++++++++ skills/ack/agents/openai.yaml | 6 +++ skills/skiff/SKILL.md | 17 ++++++- tests/test_ack_skill.py | 35 +++++++++++++ tests/test_project_skill.py | 2 + 7 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 skills/ack/SKILL.md create mode 100644 skills/ack/agents/openai.yaml create mode 100644 tests/test_ack_skill.py diff --git a/AGENTS.md b/AGENTS.md index 56e2f0c..8d0d5d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,6 +60,7 @@ AGENTS.md # 本文档 | Skill | 说明 | | ---------------------------------------------------------------------- | ------------------------------------------------- | +| [ack](skills/ack/SKILL.md) | ACK 入口:显式初始化、检查并运行项目三角色协作闭环 | | [skiff](skills/skiff/SKILL.md) | 本项目工作流:创建、使用、反馈与更新 owned skill | | [declarative-openspec-loop](skills/declarative-openspec-loop/SKILL.md) | 声明式编程循环:用户提供校验方式,Agent 自动 propose/apply/校验并迭代直到通过 | | [discussion-notes](skills/discussion-notes/SKILL.md) | 讨论沉淀:边讨论边维护 Markdown 笔记,无 .raw.md | diff --git a/README.md b/README.md index a2e3ae8..8acf290 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ AGENTS.md # 详细规范与架构说明 | Skill | 说明 | |-------|------| +| [ack](skills/ack/SKILL.md) | 显式初始化、检查并运行 ACK 三角色协作闭环 | | [skiff](skills/skiff/SKILL.md) | 在项目中创建、安装、反馈和维护 owned skill | | [declarative-openspec-loop](skills/declarative-openspec-loop/SKILL.md) | 声明式编程循环:用户提供校验方式,Agent 自动迭代直到通过 | | [discussion-notes](skills/discussion-notes/SKILL.md) | 讨论沉淀:边讨论边维护 Markdown 笔记 | diff --git a/skills/ack/SKILL.md b/skills/ack/SKILL.md new file mode 100644 index 0000000..652a74e --- /dev/null +++ b/skills/ack/SKILL.md @@ -0,0 +1,93 @@ +--- +name: ack +description: >- + 初始化、检查并运行 ACK(Agent Collaboration Kit)三角色协作闭环。仅在用户显式调用 + /ack 或 $ack,并要求初始化 ACK、检查 docs/ack 配置、按 ACK 规划需求或指挥 + Coordinator/Developer/Test 工作时使用。 +--- + +# ACK 项目协作入口 + +把全局 skill 作为入口,把项目状态留在 `docs/ack/`,把通用规范留在 +`~/.skills/kits/ack/`。不要在本 skill 复制或改写 kit 的核心规范。 + +## 选择模式 + +- 用户要求初始化、接入或安装 ACK:执行“初始化”。 +- 用户要求检查 ACK 是否可用、配置是否完整:执行“检查”。 +- 用户要求用 ACK 做需求、修复问题或继续任务:执行“工作”。 + +始终先解析真实项目根目录。优先使用 `git rev-parse --show-toplevel`;不是 Git +项目时使用用户指定目录或当前目录。不要修改项目的 `AGENTS.md`、`CLAUDE.md` +或其它 Agent 指令文件。 + +## 初始化 + +1. 确认 `skiff` 可执行,并检查 `/docs/ack` 是否存在。 +2. 不存在时执行: + + ```bash + skiff kit init ack --project + ``` + + 默认使用软链接模式。只有用户明确要求项目自带完整副本时才加 `--copy`。 +3. 如果 `docs/ack` 已存在,不重复初始化、不覆盖文件;转入“检查”,报告缺失项并 + 只补用户授权且能安全确定的内容。 +4. 读取项目的公开配置和文档,例如 README、语言清单、包管理清单、测试配置与 + CI,确定项目名、技术栈、源码/规格/测试路径及真实可执行命令。 +5. 完善 `docs/ack/project.md`: + - 用实际项目值替换全部占位符。 + - 无服务地址时把 Base URL 写为 `n/a`,不要虚构端口。 + - 无法从项目证据确定的命令写为 `n/a`,并在结果中列为待配置项。 + - 保留 `docs/ack/kit/core/` 引用,不复制 core 内容。 +6. 完善 `docs/ack/tasks.yaml` 的项目信息。纯初始化且用户没有提供真实任务时, + 删除模板示例任务并保留 `tasks: []`;不要虚构需求或缺陷。 +7. 更新 `updatedAt`,并运行: + + ```bash + python3 docs/ack/kit/scripts/validate_tasks.py docs/ack/tasks.yaml + ``` + +8. 检查 `project.md` 与 `tasks.yaml` 是否仍有 `<...>` 占位符。结构校验通过且 + 必填项目事实完整时才称“初始化完成”;否则称“部分完成”并列出缺失值。 +9. 报告创建的路径、软链接或复制模式、检测到的命令、校验结果和下一步。除非用户 + 明确要求,不提交、不推送。 + +## 检查 + +1. 检查以下路径: + - `docs/ack/kit` + - `docs/ack/project.md` + - `docs/ack/tasks.yaml` +2. 确认 `kit` 可访问 `VERSION`、`core/`、`templates/` 和 `scripts/`。软链接模式下 + 同时报告其真实目标。 +3. 对比 `tasks.yaml` 的 `kitVersion` 与 `kit/VERSION`。 +4. 查找未替换占位符,并核对项目路径、覆盖层路径、Developer 白盒命令、Test + 黑盒命令和 Base URL。 +5. 运行任务板校验器。只报告证据明确的问题,不因可选字段缺失而宣称失败。 +6. 检查不会自动修复或覆盖现有配置;用户明确要求修复后再修改。 + +## 工作 + +1. 若 `docs/ack` 不存在,停止并建议先用 `/ack` 初始化;不要静默初始化。 +2. 依次读取: + - `docs/ack/project.md` + - `docs/ack/tasks.yaml` + - `docs/ack/kit/core/kickoff.md` + - kickoff 指定且与当前任务相关的 core 文件 +3. 当前会话担任 Coordinator,遵守项目覆盖层中的命令、路径权限、模型路由和 + worker 复用规则。项目覆盖层优先于通用示例命令。 +4. 新需求先写产品文档、任务拆分与可观测验收信号,更新 `tasks.yaml` 并校验, + 然后交给用户确认;确认前不派发实现。 +5. 用户已确认的任务按 ACK 闭环执行:Developer 实现与白盒验证,Test 独立黑盒 + 复测,Coordinator 读取证据终检并唯一写入 `tasks.yaml`。 +6. 不把 `worker_done` 或 Test 自报成功直接当作完成。每项最多三轮,仍失败则记录 + `leftover` 并继续其它任务。 + +## 边界 + +- 不修改或追加任何项目 Agent 指令文件,包括 `AGENTS.md`。 +- 不在 skill 中维护第二份 ACK core、模板或任务 schema。 +- 不猜测项目命令、服务地址、worker handle 或模型名称。 +- 不覆盖已有 `docs/ack` 文件,不擅自提交、推送、创建终端或新 worktree。 +- kit 初始化的机械操作始终委托给 `skiff kit init ack`。 diff --git a/skills/ack/agents/openai.yaml b/skills/ack/agents/openai.yaml new file mode 100644 index 0000000..d896c30 --- /dev/null +++ b/skills/ack/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "ACK" + short_description: "初始化、检查并运行项目里的 ACK 三角色协作闭环" + default_prompt: "Use $ack to initialize ACK for this project or coordinate work from docs/ack." +policy: + allow_implicit_invocation: false diff --git a/skills/skiff/SKILL.md b/skills/skiff/SKILL.md index 173036a..d5b9187 100644 --- a/skills/skiff/SKILL.md +++ b/skills/skiff/SKILL.md @@ -2,8 +2,9 @@ name: skiff description: >- 创建和维护 ~/.skills 自研 skill:把项目开发中产生的想法提炼为草稿,完善并校验后发布, - 或用 skiff add/remove 在项目及全局挂卸 skill。触发词:skiff、自研 skill、创建 skill、 - 想做一个 skill、publish skill、安装自研 skill、更新 skill 到项目。 + 用 skiff add/remove 在项目及全局挂卸 skill,或用 skiff kit init 初始化项目规范包。 + 触发词:skiff、自研 skill、创建 skill、想做一个 skill、publish skill、安装自研 skill、 + 更新 skill 到项目、初始化 kit。 --- # skiff 自研 Skill 工作流 @@ -130,6 +131,17 @@ skiff rm discussion-notes -g -y # rm 别名 skiff add --list ``` +初始化项目 kit: + +```bash +skiff kit init ack # 当前项目,默认软链接到 SSOT +skiff kit init ack --project ~/app # 指定项目 +skiff kit init ack --copy # 用户明确要求时整份复制 +``` + +`skiff` 只负责可靠地创建 kit 文件。需要分析项目并完善 ACK 配置、检查接入状态或 +运行三角色闭环时,显式调用全局 `/ack` skill。 + --- ## 与 Vercel `npx skills` 的分工 @@ -155,6 +167,7 @@ skiff add --list | `create --idea TEXT [--from-project PATH]` | 创建自研 skill 草稿 | | `check ` | 校验草稿或正式 skill | | `finalize ` | 校验草稿并转为正式 skill | +| `kit init [--project DIR] [--copy]` | 在项目中初始化 kit | --- diff --git a/tests/test_ack_skill.py b/tests/test_ack_skill.py new file mode 100644 index 0000000..022abfd --- /dev/null +++ b/tests/test_ack_skill.py @@ -0,0 +1,35 @@ +from __future__ import annotations + +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +class AckSkillContentTests(unittest.TestCase): + def test_ack_skill_routes_to_kit_without_modifying_agent_instructions(self) -> None: + content = (REPO_ROOT / "skills" / "ack" / "SKILL.md").read_text(encoding="utf-8") + + for expected in ( + "skiff kit init ack --project ", + "docs/ack/project.md", + "docs/ack/tasks.yaml", + "tasks: []", + "validate_tasks.py", + "不要修改项目的 `AGENTS.md`", + "当前会话担任 Coordinator", + ): + self.assertIn(expected, content) + + def test_ack_skill_is_explicit_only(self) -> None: + metadata = (REPO_ROOT / "skills" / "ack" / "agents" / "openai.yaml").read_text( + encoding="utf-8" + ) + + self.assertIn('display_name: "ACK"', metadata) + self.assertIn("allow_implicit_invocation: false", metadata) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_project_skill.py b/tests/test_project_skill.py index 1fb4419..e02dfe2 100644 --- a/tests/test_project_skill.py +++ b/tests/test_project_skill.py @@ -19,6 +19,8 @@ class ProjectSkillContentTests(unittest.TestCase): "skiff check ", "~/.skills/skills//", "第三方 skill", + "skiff kit init ack", + "显式调用全局 `/ack` skill", ): self.assertIn(expected, content)