Superpowers 的工作流程到底是什么
一次改动从"随口一说"走到"合入主干"要过哪几道门,以及每一道门的入场条件
📅 更新于 2026-09-13
0030 秒速览:读完你能做什么
读完这一篇,你能做出三个判断:一次改动该走哪条路径(选错会白干);代理说"做完了"时该信谁(评审,不是它的自述);以及它的进度会不会在上下文被压缩后丢掉(取决于有没有那个文件)。
这一篇拆它内部按什么规则运转:一次改动走哪条路径、每一步的入场条件、评审契约怎么判、账本长什么样、五轮上限与四件停机条件。如果你还没决定"这套东西我该不该用、用到哪一档",先看 《Superpowers 到底该怎么用》。两篇不重复:这篇讲机制,那篇讲选型。
① 这套流程不是"帮你写代码"的流水线,而是在你最容易偷懒的那一步插一道闸——最贵的几个环节干的事是问你问题、把答案写成文档、再派人独立核对;② 它把一次改动劈成三条路径,选哪条由改动大小决定,不是由你心情决定(05);③ 执行期间只有四件事允许它停下来问你,其他全部由它自己裁定、记账、继续;而"做到哪了"必须写进一个文件,因为对话记忆活不过上下文压缩(21)。
按你现在的处境,直接跳到对应那一节
| 你现在的状态 | 先看这一节 | 为什么 |
|---|---|---|
| "我就想改一行配置,它却要给我写设计文档" | 05 三条路径 | 这就是"分类加棘轮"要处理的问题:小改动走 spike 路径,工件缩到两句话,但批准这一步不缩 |
| "它写了个计划,我看不出好坏" | 08 / 10 | 计划有硬性禁令清单:出现 TBD、"加适当的错误处理"这类词,计划本身就不合格 |
| "它说任务做完了,我该查什么" | 16 评审契约 | 完成 = 拿到两个独立判定(规格合规 + 代码质量),缺一个都不算 |
| "跑到一半它来问我'要继续吗'" | 20 / 23 | 执行中"要继续吗"被明确定义成浪费你的时间;但它有四个必须停下问的条件,别把这四类也当故障 |
| "上下文压缩/新开一次会话后,它会不会重做一遍" | 21 / 22 | 这就是账本存在的唯一理由;判断方法在 22 节那一行 Task <N>: complete |
| "最后它要我选合并还是开 PR,我不确定它在问什么" | 24 收尾菜单 | 菜单只有三种(或两种)选项,顺序固定,且"丢弃"是隐藏项,要你亲手打出那个词 |
"读完你应该能":四条自检
- 能用自己的话说出这套流程在防什么:防的不是"写错代码",而是"没人独立看过就说做完了"和"进度活在记忆里"(见 01 节)。
- 能区分三对最容易混的东西:规划技能 vs 实现技能、任务评审 vs 末端评审、裁定 vs 停机(见 26 节末的对照表)。
- 能预判它什么时候会来问你:动工前一定问,执行中只有四类问,其余不问(23)。
- 能举一个自己的例子:把"改一行配置"和"加一个新功能"分别套进三条路径,说出各自该产出什么——这条只有你能验(99)。
01它说的"工作流程"到底指什么
先破三个错想
错想一:它是一套命令,记住就能用。不是。它是一堆带触发条件的说明文件,官方叫 skill(技能)——每份是一个 SKILL.md,写清"什么情况下该用它、用它时必须做哪几件事"。你不用敲它,代理开工前会自己去查(04 节)。
错想二:它是"帮我把代码写得更好"的工具。不是。官方 README 的定位是"a complete software development methodology"(一套完整的软件开发方法论)——重点在流程。它最值钱的几个环节做的是:向你提问、把答案落成文档、派一个没有你对话历史的代理去独立核对。
错想三:不需要任何前置知识就能看懂。半对。入口很简单(正常提需求就行),但要读懂它给的产物(设计文档、计划、评审报告),你得知道"什么叫一个任务""什么叫测试先写"。所以这篇标 🟡 进阶,不是 🟢 入门。
它是什么:一串带闸门的接力
把官方 README 的七步和技能原文对照着看,它的形状是一条接力:每一棒交出去之前都有一道门,门没过大不了停在原地,但不会"带着没确认的东西往下跑"。四个稳定特征:先问再写(动手前先把"你到底要什么"逼出来);设计 → 计划 → 派发(设计文档是权威,计划是它对设计的论证,每个任务被抽成一张独立的任务单);没人独立看过就不算完成(每任务一次窄评审,全部完成后再来一次全分支宽评审);进度写在磁盘上(都进那个叫账本的文件,见 21 节)。
下面每一条都来自官方 SKILL.md 原文,规定的是代理应当怎么做;模型是否每次都照做是另一回事——这个仓库自己就是因为这一点才维护了一套评测。所以读到"它必须……"时,请理解成流程契约要求它必须,而不是"每次运行都会这样"。
02官方七步摘要,和技能里真正强制的规则
README 的《The Basic Workflow》列了七步。它好记,但它是摘要,不是规范——真正约束行为的是每个技能自己的 SKILL.md。记住两边的差额,你才知道该盯哪里。
| # | README 七步(官方摘要) | 它在这一步做的事 | 摘要没写、但技能正文强制的东西 |
|---|---|---|---|
| 1 | brainstorming | 写代码前先激活:用提问把粗糙想法磨成设计,分块给你确认,存设计文档 | 批准闸门:任何实现动作之前必须拿到一句明确的 yes(06) |
| 2 | using-git-worktrees | 设计通过后激活:在新分支上建隔离工作区,跑项目初始化,验证测试基线是干净的 | 先检测再创建:已经隔离就别再建;创建前必须确认目录已被 git 忽略(07) |
| 3 | writing-plans | 有设计后激活:把工作拆成 2–5 分钟的小步,每步有确切文件路径、完整代码、验证步骤 | 零占位符 + 头部五件套 + 写完三步自审(10、11) |
| 4 | subagent-driven-development 或 executing-plans | 有计划后激活:每任务派一个全新子代理,配两阶段评审;或者分批执行、人工检查点 | 每任务两判定、绝不并行派实现者、绝不预判发现(16、19) |
| 5 | test-driven-development | 实现期间激活:强制先写失败测试、再看它通过、最后整理代码;删掉先于测试写下的代码 | 这是实现技能,流程技能优先于它(04) |
| 6 | requesting-code-review | 任务之间激活:对着计划评审,按严重度报问题,Critical 阻塞进度 | 摘要把"任务评审"记在这一步,但任务评审的模板与流程归 SDD 自己管;这里这套模板服务的是最后那次全分支宽评审(24) |
| 7 | finishing-a-development-branch | 任务完成时激活:验证测试、给出选项(合并/PR/保留/丢弃)、清理工作区 | 动作顺序固定成五步,且"丢弃"不是常规选项——它只在你要的时候出现,还要你亲手打出那个词(24) |
摘要和实现脱节的地方,具体是哪一处
第 6 行那个"归谁管"的问题,有一份设计文档记下了修法:任务级评审的模板与派发方式被上移到 subagent-driven-development 名下,requesting-code-review 保留的是宽评审(全分支)那套模板。README 写的是改之前的分工,照着摘要读会把"谁派任务评审"读错。
还有一层整个没进摘要:账本机制。七步里没有一步叫"记进度",但它是 SDD 里篇幅最重的一块,且有实测支撑(21)。
结论:把七步当路线图(大概会经过哪几个环节),把 SKILL.md 当规范(它到底会不会做某件事,只信后者)。摘要会漂移,实现不会。
03最小例子:一次小改动走完整条流程
抽象讲三段,不如跟一次真实的小改动。假设你只有一句话的需求:"导出页面上当前筛选出来的结果。"
它不会直接写代码,而是先确认:导出格式是什么(CSV / JSON)?是当前这一页还是全部筛选结果?空结果怎么办?答案被写进一份设计文档并分块展示给你,等你点头。接着它声明路径:这个改动只涉及一个页面加一个工具函数,属于 bounded(有边界的小工作)——设计短到可以直接在对话里给,但批准这一步照旧。
先检测当前是不是已在隔离环境里,不在才创建,创建前确认目录已被 git 忽略;建好后跑一遍现有测试,确认基线是绿的(否则之后失败了分不清是谁弄坏的)。然后把"导出"切成两三个任务,每个任务自带测试周期,内部再切成 2–5 分钟一步的固定五步;计划里带完整代码,不是"你看着办"。
派发里只有这一个任务:一句话定位、任务单路径、前序任务的接口、它对歧义的裁定、报告文件路径;报告全文写在文件里,不粘回对话。随后评审者拿到任务单、报告文件、评审包(提交列表 + 改动统计 + 完整 diff 装在一个文件里),必须回答两件事:规格合规吗(要求的都做了、没多做)和质量过关吗。缺任何一个判定,这次评审不算数。
规格不合格、或出现 Critical / Important 级发现,就进循环。第 1–3 轮把发现原样发回给原来那个实现者(它的上下文还在),第 4–5 轮换一个更强模型的新实现者。每轮修完只看修复范围内的 diff 重审。第 5 轮还不干净就跳闸,由控制者逐条裁决并记账。
所有任务完成后做一次全分支宽评审:范围是整个分支(从起点到当前提交)、用最强模型,并把账本里"延后的次要发现"和"挂起的发现"指给它分诊;有发现也只允许一次修复波。然后顺序固定地收尾——验证测试 → 探测环境 → 呈现选项 → 执行选择 → 清理;菜单在绿色测试之后才出现,选项恰好三个,等你回答,你选合并后它还会在合并结果上再跑一次测试。
04你没敲命令,它为什么自己启动
启动键不是命令,是一条 1% 规则
负责启动的是 using-superpowers 这个技能,它的原文用全大写写着一条硬规则。中文意思是:只要你认为有哪怕 1% 的可能某个技能和当前任务相关,就必须调用它;技能一旦适用,你没有"选不选"的自由。
# 原文(skills/using-superpowers/SKILL.md,2026-09-13 抓取)
If you think there is even a 1% chance a skill might apply to
what you are doing, you ABSOLUTELY MUST invoke the skill.
IF A SKILL APPLIES TO YOUR TASK, YOU DO NOT HAVE A CHOICE.
它甚至专门列了一张"自我辩解"清单来堵漏:"这只是个简单问题" → 问题是任务,先查技能;"我先看看代码库" → 技能就是告诉你该怎么看的;"我记得这个技能" → 技能会演进,读当前版本。这张表的用途是给代理看的,但对你也有用:当你看到它跳过了某个环节,先问一句"这个技能适不适用",比教它怎么做更快。
两个都在争着管你的时候,谁优先
技能分两类,冲突时有一条明确规则:
另外,你的指令优先级高于技能(AGENTS.md、CLAUDE.md、你当场说的话);只有你明确说"跳过这个流程",才允许跳过。
| 类别 | 管什么 | 例子 | 冲突时怎么办 |
|---|---|---|---|
| 流程技能 | 怎么做事的顺序与闸门 | brainstorming、systematic-debugging、writing-plans | 流程技能优先:先定做法,再选工具。反过来就会在错的框架里写得很快 |
| 实现技能 | 用什么做的领域知识 | 前端设计、某个框架的用法 | 它负责把流程的结论落实,不负责改流程 |
什么时候这条 1% 规则不生效
技能自己写了一个例外,用的是一对标签:如果一个代理是被派来执行某个具体任务的子代理,它应当忽略这个技能。原因很实际:14 节的派发契约要求子代理"只看得到自己那一个任务",如果它还跑回去加载一整套启动规则,就会被灌进与任务无关的东西。
<!-- skills/using-superpowers/SKILL.md 开头 -->
<SUBAGENT-STOP>
If you were dispatched as a subagent to execute a specific task, ignore this skill.
</SUBAGENT-STOP>
看到这个标签的意义在于:它是"上下文隔离"的第一道落实,而不只是文档细节。
05第一个决策点:三条路径,选错就白干
它凭什么把流程劈成三条
所有请求——包括你眼里"随口一问"的那种——都要先过一道分类。分类结果只影响一件事:这条路要产出多重的工件(两句话的设计,还是一份设计文档 + 一份实现计划)。
| 路径 | 什么改动走它 | 强制产出 | 最容易漏的硬规则 |
|---|---|---|---|
| spike (探针) | 你只是想先问个问题、试一下想法,还不打算真做 | 建议 / 探索结论,不写实现代码 | 探针结束不等于批准:真要做,回到分类重来 |
| bounded (有边界) | 改一个页面加一个函数这种有明确边界的小工作 | 对话内的短设计(可能就两句话) | 工件缩水,但批准闸门不缩(06) |
| architectural (架构级) | 要动多个模块、要定接口或数据结构 | 落成文件的 spec(设计文档),之后只能接 writing-plans | architectural 之后不许跳到实现;必须经过计划这一棒 |
拿不准的时候怎么选
规则很干脆:拿不准选重的一档;分类是棘轮——只能往上加,不能往下减。理由不是保守,而是纠错成本不对称:把 architectural 当成 bounded 做,等发现要改接口时,已经有一批代码建立在这个接口上了;反过来只是多花几分钟写清设计。复核这个决策的最佳时机就是它宣布分类结果的那一刻。
为什么这条把流程劈成三条的规则最容易看漏
因为绝大多数抱怨都来自同一种误读:把七步当成一条铁轨。实际上第一条决策已经把流程劈开了,只是摘要没说。现象是"流程太重",根因通常是"分类被判重了"——正确的反应是拿一句话去复核分类("这个改动要不要动接口?"),而不是让它跳过批准。
技能正文专门点了反向的错:随任务简单程度缩水的是工件(设计可以短到两句话),不是批准——沉默不算同意(06 节)。
06硬闸门:批准之前,一行实现代码都不许写
这是整套流程里语气最重的一条,也是原文可引的一段。它把"批不批准"和"任务大小"彻底解耦:
# 原文(skills/brainstorming/SKILL.md,2026-09-13 抓取)
Do NOT invoke any implementation skill, write any code, scaffold any
project, or take any implementation action until you have told your
human partner what you intend and they have approved it. This applies
to EVERY task on EVERY path below — the ceremony scales with the task;
the approval never does.
中文重述:在你告诉人类伙伴你打算做什么、并且对方批准之前,不许调用实现类技能、不许写代码、不许搭脚手架、不许采取任何实现动作。这条对每条路径上的每个任务都成立——仪式随任务缩水,批准永远不缩。
闸门到底长什么样
- 谁来批准:你,不是代理自己——自评自批会让闸门退化成装饰。
- 什么时候:它说清楚打算做什么之后、任何实现动作之前。"先写一点再问"会让批准变成事后通知。
- "行吧""随便"算吗:不算,要一个明确的 yes。"没反对"和"同意"是两件事——这条在收尾菜单(24)还会再出现一次,那里判定更严。
- 小改动能省吗:不能,但可以短到一句话——省的是展示篇幅,不是这一步本身。
你在这里该盯什么
盯两件事:它有没有说清打算做什么(而不是"我准备开始了"),以及它有没有在你回答之前就动起来。后者是真正的故障——闸门的价值全在"顺序"上,晚一秒就没了。
07第二个决策点:隔离工作区,先检测再创建
为什么要有这一步
隔离工作区(官方做法是 git worktree,宿主也可能提供等价机制)就是另开一个目录检出同一份仓库,让这次改动不碰你当前手头的代码,"改坏了"的半径因此限制在这个目录里。它在流程里的位置是场地条件:设计批准后、动工前准备好,之后所有任务都在这里跑。
三个具体动作,每个都有个"别做"
| 动作 | 怎么做 | 别做什么(原文点名) |
|---|---|---|
| 先检测 | 第一步是判断"当前是不是已经在隔离环境里" | 别上来就 git worktree add。已经隔离还再套一层,会让后面的路径判断全乱 |
| 再创建 | 不在隔离环境里,才新建;建之前确认目标目录已被 git 忽略 | 别建在没被忽略的目录里——那样它会以未跟踪文件的形式出现在你的仓库里,污染 git status |
| 验基线 | 建好后跑一遍项目现有的测试,确认基线是绿的 | 别跳过。基线本来就是红的,之后所有"测试失败"都失去意义 |
一条与它配套的硬规则
SDD 的 Setup 里有一句几乎是逐字的规定:没有人类伙伴的明确同意,绝不在 main / master 分支上开始实现。注意它和批准闸门不是同一件事——批准的是"做什么",这一条锁的是"在哪儿做"。两者都要。
# 典型的一组命令(用 git 自己的 worktree 机制)
git worktree add ../feature-export -b feat/export-filtered
cd ../feature-export
npm install # 跑项目自己的初始化
npm test # 验证基线:必须全绿再开工
# 收尾阶段清理时只动这一处(第 24 节会讲为什么只清这里)
git worktree list
git worktree remove ../feature-export
08把设计切成 2–5 分钟的步子:计划的写法是被规定死的
写计划时要假设读者是谁
writing-plans 的开篇用一句话定义了"写给谁看"。这句话决定了后面所有规则,所以值得原文引一次:
# 原文(skills/writing-plans/SKILL.md,2026-09-13 抓取)
Write comprehensive implementation plans assuming the engineer has
zero context for our codebase and questionable taste. ...
Assume they are a skilled developer, but know almost nothing about
our toolset or problem domain. Assume they don't know good test
design very well.
中文重述:写计划时要假设执行者对我们的代码库零上下文、品味可疑;假设他是技术不错的开发者,但对我们的工具链和问题域几乎一无所知,而且不太懂好的测试设计。为什么把执行者想得这么差?因为它就是一份派发材料的母本:每个任务会被抽出来单独发给一个全新子代理,那个子代理没有你的对话、没有你的权衡过程、看不到别的任务,手里只有这张任务单。这是为真实的读者写文档,不是谦虚。
任务该切多大:一条可以背下来的判据
技能正文给的定义比"2–5 分钟"更本质——它把任务和步骤分开了:
任务 = 自带一个测试周期、并且值得让一个新评审者亲自把关的最小单位。切边界时:把安装、配置、脚手架、文档这些步骤折进需要它们的那个任务;只在"评审者可以合理地拒掉一个任务、同时批准它旁边那个"的地方切开。每个任务都以一个可独立测试的交付物收尾。
而任务的内部步骤才是 2–5 分钟粒度,固定五步(写失败测试 → 跑它确认失败 → 写最小实现 → 跑它确认通过 → 提交)。这五步在计划文档里有固定格式,下面两份可以直接照抄、把名字换掉:
# 每任务循环里那固定五步,在计划文档里长这样(照抄改字即可)
- [ ] **Step 1: Write the failing test**
```python
def test_rejects_empty_input():
assert parse("") == ParseError.EMPTY
```
- [ ] **Step 2: Run test to verify it fails**
Run: `pytest tests/test_parse.py -v`
Expected: FAIL — "ParseError has no EMPTY"
- [ ] **Step 3: Write minimal implementation**
```python
def parse(s):
if not s: return ParseError.EMPTY
```
- [ ] **Step 4: Run test to verify it passes**
Run: `pytest tests/test_parse.py -v`
Expected: PASS
- [ ] **Step 5: Commit**
```bash
git add tests/test_parse.py src/parse.py
git commit -m "feat: reject empty input"
```
而一个完整的任务,除了这五步还要写清文件清单与接口——文件路径要精确到行号,接口要说清"消费什么、产出什么",因为执行者只看得见自己这一个任务:
### Task N: 导出当前筛选结果
**Files:**
- Create: `src/export/to-csv.ts`
- Modify: `src/pages/results.tsx:120-140`
- Test: `tests/export/to-csv.test.ts`
**Interfaces:**
- Consumes: `filteredRows(): Row[]`(来自 Task 2,签名见那份任务单)
- Produces: `toCsv(rows: Row[]): string`——后面的任务按这个签名调用
09计划头部五件套:每一件都在防一个具体的失败
技能正文写着"每个计划必须以这个头部开始"(原文用的就是 MUST 级别的措辞)。其中每一件都有功能,不是格式洁癖:
| 头部字段 | 写什么 | 它为什么必须存在 |
|---|---|---|
| Goal | 一句话说明这个计划要造出什么 | 给执行者一个判断"我这个任务有没有跑偏"的参照 |
| Architecture | 2–3 句话讲做法 | 避免每个执行者在局部各自做出一堆"单独看都合理、合起来互相矛盾"的选择 |
| Tech Stack | 关键技术与库 | 决定"用什么写"的那一半歧义 |
| Spec | 它所实现的设计文档路径 | 计划是从 spec 论证出来的,所以 spec 要跟着计划一起走,执行者两份都读 |
| Global Constraints | 项目级要求:版本下限、依赖限制、命名与文案规则、平台要求——逐字抄自 spec,一行一条 | 每个任务的隐含要求都包含它。这条是用血换来的,见下面的真实事故 |
头部在文件里长这样(照抄改字即可):
# 导出当前筛选结果 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development
> (recommended) or superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 结果页能把当前筛选结果导出成 CSV。
**Architecture:** 纯函数负责序列化,页面只负责取数并触发下载。
**Tech Stack:** TypeScript、React、Vitest
**Spec:** docs/superpowers/specs/2026-09-13-export-filtered-design.md
## Global Constraints
- Node >= 20.11(以 package.json 的 engines 为准)
- 不新增运行时依赖;CSV 序列化手写
- 用户可见文案统一走 `t()`,不出现硬编码中文
- 导出文件名格式:`results-YYYYMMDD.csv`
⚠️ Global Constraints 丢了会怎样:一个记录在案的事故
设计文档里记了一次评测中发现的问题:某次运行交付的模块版本下限与设计里写的不一致,而根因不是实现者写错——是没有任何一个评审者见过这条约束:控制者在把需求传给评审者时把全局约束漏掉了。所以技能现在写死了一条:控制者必须把约束逐字抄给评审者,因为它就是评审者的"注意力透镜"。
这条对你有两个用处:① 写设计文档时,把项目级硬要求单独成节,因为下游会逐字搬运它;② 看到代理交付了某个奇怪的版本号或命名,先查这条约束在不在传递链上,而不是先怀疑实现者。
还有一条相关规则:一份设计如果覆盖了多个互相独立的子系统,应当在 brainstorming 阶段就拆成多份;计划阶段发现没拆,就停下来建议拆开——因为跨子系统的任务没办法被单独派出去。
10哪些写法一律算"计划失败"
技能把下面这些称为 plan failures(计划失败)。注意措辞的分量:不是"后面再补",而是这份计划本身不合格。
| 禁止写法 | 长什么样 | 为什么它一定不合格 |
|---|---|---|
| 占位符 | TBD、TODO、implement later、"fill in details" | 它把计划变成"以后再说"的承诺,而执行者可能就是你不在场时的那个代理 |
| 开放式指令 | "加适当的错误处理"、"加校验"、"处理边界情况" | "适当"和"边界情况"是把设计决策退回给一个没有上下文的执行者 |
| 无代码的"写测试" | "为上面的逻辑写测试"(却不给测试代码) | 等于把测试设计也退回去——而前提假设恰恰是"执行者不太懂测试设计" |
同任务 N | "与任务 3 相同"(不重复代码) | 执行者可能乱序读任务;一句"同上"对他来说是一个空洞的指针 |
| 只说不做的步骤 | 描述"做什么"却不展示"怎么做"的代码步骤 | 代码步骤必须带代码块,否则执行者只能即兴发挥 |
| 悬空引用 | 引用了任何任务里都没定义过的类型、函数或方法 | 执行者只看得见自己那一个任务,找不到定义就只能猜 |
同一件事的两种写法,对照着看
- [ ] Step 3: 实现解析器
加适当的错误处理,并处理边界情况。
为上面的逻辑写测试。
"适当"和"边界情况"是把设计决策退回给一个没有上下文的执行者;"为上面写测试"不给出测试代码,等于把测试设计也退回去——而前提假设恰恰是"执行者不擅长测试设计"。结果是每个任务都变成一次即兴发挥。
- [ ] Step 1: Write the failing test
```python
def test_rejects_empty_input():
assert parse("") == ParseError.EMPTY
```
- [ ] Step 2: Run it, verify it FAILS
Run: `pytest tests/test_parse.py -v`
Expected: FAIL — "ParseError has no EMPTY"
- [ ] Step 3: Minimal implementation
```python
def parse(s):
if not s: return ParseError.EMPTY
```
- [ ] Step 4: Run, verify PASS
- [ ] Step 5: Commit
好在哪:每一步都给了可执行的动作与期望的失败信息。最后这条尤其关键——"期望看到什么"才是"验证"和"瞄一眼"的区别。
11写完必须自审:三步固定动作
计划写完后有三个动作,顺序固定,且由写计划的人自己跑——技能明确写了这不是一次子代理派发。三步各有各要抓的东西:
逐条扫设计文档的每一节、每条要求,指到一个实现它的任务。指不出来的就是缺口,补任务。这一步防的是"计划写得很漂亮,但漏了一条需求"——那种漏掉的需求不会自己出现,只会在验收时冒出来。
拿 10 节那张禁令表当关键词表,在计划里搜一遍:TBD、TODO、"适当的"、边界情况、同任务……命中就改。这一步可以机械执行,别靠"我觉得我写得挺细"。
后面任务里用的类型、方法签名、属性名,是否与前面对应的定义一致。技能给的例子很具体:Task 3 里叫 clearLayers()、Task 7 里叫 clearFullLayers(),就是一个 bug——因为两个执行者各自只看到自己那份,谁都发现不了。
发现问题的处理方式是"就地修掉,不需要再复审一轮"。这条规则在本流程里反复出现,它防的是"用一个流程去审另一个流程"的无限套娃:自审就是自己看,看到就改,改完继续。
计划的终点:把两条执行路径交给你选
计划保存后,技能要求给出两条执行路径让你选,原文给的措辞几乎可以直接用:
Plan complete and saved to `docs/superpowers/plans/<filename>.md`. Two execution options:
1. **Subagent-Driven (recommended)** - 我每个任务派一个全新子代理,任务之间评审,迭代快
2. **Inline Execution** - 在当前会话里用 executing-plans 分批执行,带检查点
Which approach?
注意这里的分工:它给选项,不给决定。两条路径的性格差别很大(见 05 节的三条路径与 12 节的循环),选错了体验完全不同。
12一个任务走五步:主循环的骨架
执行阶段最厚的一份技能是 subagent-driven-development(下文简称 SDD),单文件 568 行,是改动最频繁的一份。它开篇先解释了"为什么要用子代理",理由和我们通常想的不一样:
# 原文(skills/subagent-driven-development/SKILL.md,2026-09-13 抓取)
They should never inherit your session's context or history —
you construct exactly what they need. This also preserves your own
context for coordination work.
中文重述:子代理永远不该继承你会话的上下文与历史,你要为它精确构造它需要的东西。这么做的两个收益:它不会被你一路累积的假设带偏;你自己的上下文额度被保住,用于协调工作。第二点常被忽略,但它解释了后面一大批看起来"过于抠门"的规则——为什么派发不许贴历史、为什么 diff 要交给文件。核心原则一句话:每任务一个全新子代理 + 任务评审(规格 + 质量)+ 末端一次宽评审 = 高质量、快迭代。
Setup:开工前要做的四件事
| # | 做什么 | 硬规则 |
|---|---|---|
| 1 | 确保隔离工作区(复用 07 节的技能) | 没有人类明确同意,绝不在 main / master 分支上开始实现 |
| 2 | 解析本计划的 workspace 并检查里面的账本——用这份技能自带的 scripts/sdd-workspace PLAN_FILE,它打印这个计划专属的、被 git 忽略的目录 | 第一行是别的计划文件名 → 那不是你的进度,原地留着、自己新建一份 |
| 3 | 读一遍计划,记下上下文与 Global Constraints,为每个任务建一条 todo;计划里写了 spec 路径就一并读 | "计划内部的冲突要对着 spec 解";找不到可达的 spec 时在账本里记一条说明,此后裁定都算临时的 |
| 4 | 派发任务 1 之前,先把计划扫一遍找冲突 | "扫干净了"这句话必须有凭据(13 节) |
然后进入五步循环
| 步 | 做什么 | 它交付的证据 | 下一步的入场条件 |
|---|---|---|---|
| 1 | 派发实现者(14 节) | 派发之前先记下 BASE(git rev-parse HEAD) | 派发里必须有任务单文件路径与报告文件路径 |
| 2 | 处理报告(15 节) | 四种状态之一 + 提交号 + 一行测试结论 | 只有 DONE / 处理完疑虑的 DONE_WITH_CONCERNS 才进评审 |
| 3 | 评审这个任务(16 节) | 两个判定:规格合规 + 任务质量 | 两个都在,才可能进第 5 步;否则进第 4 步 |
| 4 | 修复循环(18 节) | 修复提交 + 修复报告(含测试、命令、输出)+ 账本轮次行 | 开口发现清零,或到第 5 轮跳闸并逐条裁决 |
| 5 | 完结这个任务 | 账本追加一行带提交号的完结记录,todo 勾掉 | 见下方那条硬约束 |
第 5 步的完结记录格式是固定的:
Task <N>: complete (commits <base7>..<head7>, review clean)
# 跳闸过的任务则是:
Task <N>: complete (commits <base7>..<head7>, <K> parked)
原文写得很直接:只要还有未被修复、也未被带裁定 park 的 Critical / Important 问题,绝不进入下一个任务。换句话说,任务之间的门不是"做完了",而是"没有未处置的高优先问题"。
13开工前的冲突预扫:产出是一张表,不是一句"没问题"
这一节是全文里最容易被跳过的,但技能写得非常具体:扫描的产出是一张表,不是一句"扫干净了"。原文对敷衍有一句直白的判词:"扫干净了"而没有这些行,等于你没扫。
表里必须有的两类行
| 行类型 | 一行写什么 | 它抓什么 |
|---|---|---|
| 共享资源对(每对一行) | 两个任务是哪两个、一个产出什么、另一个消费什么、你发现了什么 | 两个任务碰同一个文件或同一个接口时的接口错位——这是最典型的"单独看都对、合起来崩" |
| 逐任务自洽(每个一行) | 它自己的文字是否自洽:规定的测试和它规定的代码对得上吗?它创建的文件与它后面要碰的文件对得上吗? | 单份任务单内部的矛盾 |
| 计划与规则的冲突 | 任何计划明确要求、而评审规则会判为缺陷的东西 | 比如"一个什么都不断言测试"、"一段逻辑的逐字复制"——这些按常规评审标准是要报缺陷的 |
扫出来之后怎么处理
每一处冲突都要在开工前裁定,裁定写进账本、放在它那一行旁边;干净就直接开始,不必多话。这里有一条边界值得记住:预扫不是为了把实现阶段可能冒出的冲突一次算完——技能正文把后者留给评审循环当兜底。预扫管的是从计划文本本身就能看出来的冲突。
这张表也是你复核"代理是不是真的读了计划"的最便宜凭据——要它把这行表贴出来,只有真扫过才写得出来。
14派发契约:一次派发必须给的五样东西
派发之前先记坐标
技能规定:派发实现者之前先记下 BASE(git rev-parse HEAD),后面的评审包和修复轮 diff 都要用它。而且写死了一句"绝不":绝不能事后用 HEAD~1 代替——那会静默丢掉多提交任务的除最后一次之外的全部提交:评审者会看到一份不完整的 diff,却不知道它不完整。
# 派发前记下 BASE
git rev-parse HEAD # 例如 4f2a9c1…,记下来
# 拿这个计划的任务单(技能自带脚本,会打印它写出的唯一文件路径)
scripts/task-brief docs/superpowers/plans/2026-09-13-export-filtered.md 1
# → …/.superpowers/sdd/2026-09-13-export-filtered/task-1-brief.md
# 评审包:把提交列表、统计摘要、带上下文的完整 diff 装进一个文件
scripts/review-package docs/superpowers/plans/2026-09-13-export-filtered.md <BASE> HEAD
# → …/task-1-review-<BASE7>..<HEAD7>.diff (路径由脚本打印)
# 没有 bash 时的等价写法(原文给出的回退方案):三条命令重定向进同一个文件
git log --oneline > review.diff
git diff --stat >> review.diff && git diff -U10 >> review.diff
派发内容由五个部分组成
技能正文把这五条列成了一份清单,缺一条就意味着一件事要靠猜:
这个任务在整个项目里处在什么位置。作用不是交代背景,而是让实现者判断"我做到什么程度算够"。
原文的推荐措辞是"先读这个——它是你的需求,里面的确切值要逐字使用"。确切值(数字、魔法字符串、签名、测试用例)只出现在任务单里。
来自前序任务的东西:真实的函数名、参数、返回值,以及前面已经定死的取舍。这一条是"任务自足"的补丁——任务单写的是它自己的事,跨任务的接口得由你带上。
你读任务单时发现哪里可能两种理解,就在这里定死,并说明理由(裁定会进账本,见 18 节)。
实现者把完整报告写进文件,只回报状态、提交号、一行测试结论和疑虑。报告文件就是持久记忆——它在修复轮和重审里会被反复用到。
可以直接抄的派发模板
你负责计划里的 Task 1:导出序列化函数。它是整个功能的第一块——
它产出的 toCsv(rows) 后面会被页面调用。
先读这个文件,它是你的需求,里面的确切值要逐字使用:
…/.superpowers/sdd/2026-09-13-export-filtered/task-1-brief.md
任务单不知道的接口(来自已完成的调研):
filteredRows(): Row[] 已有,返回 { id: number; name: string }[]
我注意到的一处歧义,裁定如下:
任务单写"空数组返回空字符串",但 CSV 消费方要求始终有表头;
裁定:空数组返回 'id,name\n'。理由:与 Task 2 的表头复用逻辑一致。
完成后把完整报告写进:
…/.superpowers/sdd/2026-09-13-export-filtered/task-1-report.md
回报只要四样:状态、提交号、一行测试结论、你的疑虑。
约定:你不派子代理——不派助手,也不派评审者。评审我来安排。
有不清楚的地方直接问我,别猜。
派发里三条"绝不"
| 绝不 | 为什么(原文给的理由) | 你要是看到它这么做了 |
|---|---|---|
| 绝不让子代理去读整个计划文件 | 它会被塞进一堆与它无关的任务,注意力被稀释 | 子代理开始讨论"另一个任务"的事,或擅自改了别的模块 |
| 绝不把历史摘要粘进后面的派发 | 原文记了一个真实数字:某次派发的 prompt 达到 42k 字符,其中 99% 是粘贴的历史。这些内容会在你会话里常驻到结束,且之后每一轮都要重读一遍 | 你会看到派发里出现"前面三个任务的状态如下"这种段落 |
| 绝不并行派发多个实现者 | 原文对这条的规则是"绝不",理由是冲突 | 两个实现者同时改同一片区域,最后合并时才发现互相踩了 |
一条很实用的小规矩:批量小活
当计划里连着几个同形状的小改动(同一处一行修复、同一个常量变更、同一个字段添加重复出现在多个文件里),不要一个任务派一个子代理——写一份派发说明列出每个文件和它的改动,整批发给一个子代理,把它的 diff 当一个单位评审。一个任务一次派发,留给那些需要自己判断、自己测试、自己一个评审面的工作。
如果更早的某个任务在这个任务要碰的地方 park 过一条发现,就在派发里带上指向那条账本记录的指针。否则实现者会撞上一条已知问题,然后花时间重新发现它。
15四种回报状态:每一种都有对应动作
实现者只被允许报四种状态之一。好处是你不用读长篇解释就知道该怎么办——状态本身就是路由键。
| 状态 | 它的意思 | 你接下来做什么 | 别做什么 |
|---|---|---|---|
DONE | 做完了 | 生成评审包 → 派任务评审者 | 别跳过评审直接进下一个任务 |
DONE_WITH_CONCERNS | 做完了,但它自己标了疑虑 | 先读它标出的疑虑:涉及正确性或范围的先处理;纯观察类的("这个文件开始变大了")记下后继续评审 | 别把疑虑当客套直接略过——它是你唯一一次在评审前拿到信号的机会 |
NEEDS_CONTEXT | 缺信息,做不下去 | 补齐它要的上下文,然后重新派发 | 别让它"先按理解做做看" |
BLOCKED | 它卡住了 | 按下面四种原因分派对策 | 别忽略升级请求;别让同一个模型毫无改变地重试 |
BLOCKED 的四种原因,对应四种改法
① 上下文问题 → 补上下文、同模型重派;② 需要更强的推理 → 换更强模型;③ 任务太大 → 拆成更小的块;④ 计划本身错了 → 裁定修正、记账,并把这条裁定带进重派。
原文对 BLOCKED 有一句硬要求:绝不忽略升级请求,也绝不让同一个模型毫无改变地重试——"如果实现者说它卡住了,那么有些东西必须改变"。
最后一条容易忽略的规定:实现者提问时——不管开工前还是任务中途——都要清楚完整地回答它,需要就补上下文,别催它赶紧开始写。所以当你看到子代理在提问,那不是卡住的信号;真正的故障信号是它不问、直接猜。
16评审契约:两个判定,缺一个都不算完成
评审者拿到的三样东西
评审不是"再看一眼代码"。技能规定:先把 diff 交给文件(上一节的评审包;这个输出从不进入你自己的上下文),再把三个路径给评审者,外加约束这个任务的全局约束:
- 同一份任务单(它审查的规格)
- 报告文件(实现者说它做了什么)
- 评审包(提交列表 + 统计摘要 + 带上下文的完整 diff)
- 外加 Global Constraints——09 节那条"必须逐字抄给评审者"的约束块
必须拿回两个判定
| 判定 | 问的是什么 | 可能的取值 | 为什么要分开问 |
|---|---|---|---|
| 规格合规 | "计划要求的都做了吗?有没有多做?" | ✅ / ❌(外加一类 ⚠️) | 它防的是"方向错但代码漂亮"——多做了同样算不合规 |
| 任务质量 | "这份代码本身好不好?" | Approved / Needs fixes | 它防的是"照做了但很糟"——合了规格也可以是一团乱麻 |
原文对此的措辞是"绝不要接受缺少任何一个判定的报告",而且加了一句:实现者的自审永远不能替代任务评审——两者都要。理由很直白:自审用的是同一个脑子、同一批假设,它看不见自己的盲区。
那一类 ⚠️ 是什么意思
评审者可以报一类叫"无法从 diff 验证"的项:那些要求写在没被改动的代码里,或者跨了好几个任务,单看这份 diff 判断不了。它的规则和另外两类都不同:不阻塞评审的其余部分继续;但你必须逐条自己解决,才能把任务标记成完结(只有你手上有计划和跨任务上下文);如果你确认它确实是真缺口,就按规格评审失败处理,和其他发现一起进循环。
任务评审 vs 全分支评审:别混
| 任务评审(每任务一次) | 末端评审(全部任务完成后一次) | |
|---|---|---|
| 范围 | 本例任务从 BASE 到 HEAD 的 diff | 整个分支,MERGE_BASE..HEAD |
| 判定 | 两个:规格合规 + 任务质量 | 架构与设计层面的发现 + 分诊账本里延后的次要发现 |
| 模型 | 按 diff 的大小、复杂度、风险缩放 | 可得的最强模型,不是会话默认 |
| 能不能省 | 不能省,每个任务都要 | 不能省,但整个分支只有一次 |
技能对"任务评审"的定位说得很清楚:它是窄闸门。宽度的唯一合法出口在最后那次全分支评审。把任务评审做成全分支规模,结果是每个任务又慢又贵(这件事有实测数字,见 25 节)。
17重审为什么必须"范围受限"
先看它修掉的是什么病
修复之后要重审,但"重审"有两种做法,差别是决定性的。这个流程之前的那一版,循环的字面规则就是"Repeat until approved"(重复到被批准为止):没有轮次上限,而且每一次重审都是对整个 diff 的全新完整评审。结果是"一个非确定性的评审者每轮都能翻出新发现,而不是核实修复"——节奏变成"实现、评审、修、评审、评审、修、评审、修",没有断路器。
修法是把重审的范围钉死:只看修复范围内的 diff。
范围受限重审的输入与输出,都是写死的
| 内容 | 为什么必须这样 | |
|---|---|---|
| diff 范围 | FIX_BASE..HEAD,其中 FIX_BASE 是上一次评审看过的那个 head | 范围之外的一切上一轮已经审过了,再审一遍只会产生新发现,不会验证修复 |
| 输入四样 | 任务单、更新后的报告、原始发现清单、修复范围的 diff 包 | 没有原始发现清单,重审者就不知道自己在核实什么 |
| 输出三条 | ① 对每条发现判 ADDRESSED / NOT ADDRESSED;② 只报告修复 diff 里的新破坏;③ 范围之外的观察只能作为非阻塞项上报 | 把"它想顺便说说别的"这条出口关掉,循环才会收敛 |
原文的反驳很干脆:有人说"评审者反正还会发现新东西"——回答是"范围受限的重审是在核实修复,它不会漫游;未改动代码上的新发现进账本,不进循环。"
每一轮还要过一道完整性门禁
重审之前有一道检查:修复报告里必须同时有这三样,缺一样就先别派重审——
- 覆盖测试:哪些测试覆盖了被改动的代码(修复消息里要点名测试文件:"一行修复不需要整个测试套件")
- 跑的命令:实际敲的那条
- 输出:运行结果
这一轮的动作是固定的四件:实现者修 → 重跑覆盖被改代码的测试 → 把修复报告追加到同一个报告文件 → 返回短契约。技能还专门加了一条禁令:控制者绝不自己动手修发现——那会污染协调用的上下文,而且绕过评审。
18修复循环:五轮上限、换人不换题、到点跳闸
什么会触发循环
三个触发条件之一成立就进循环:
- 规格评审报了 ❌;
- 出现任何 Critical 或 Important 级发现;
- 有一条你自己确认属实的 ⚠️ 项(上一节那类"无法从 diff 验证"的)。
而在循环开始之前,有两类发现被直接分流出去,不占轮次:
| 分流的发现 | 去哪 | 为什么不让它进循环 |
|---|---|---|
| Minor(次要) | 随手记进账本,格式 Task <N>: minor (deferred): …,留给末端评审分诊 | 它不该有拦住任务的能力。原文一句点评:"一份没人看的汇总,等于静默丢弃"——所以必须有末端评审指着这份清单看 |
| 与计划文本冲突的发现 | 由控制者裁定,动工前把裁定记进账本 | 规则是"不能因为计划就是这么写的就把它驳掉",但也不因此停下来问你:以 spec 为有约束力的权威去称它 |
五轮怎么分配:前三次换题不换人,后两次换人又换脑子
| 轮次 | 谁来做 | 为什么这么设计(设计文档的原话与解读) |
|---|---|---|
| 第 1–3 轮 | 续聊原来的实现者,把开口的发现逐字发给它 | 它的上下文还完整:它知道自己当时的取舍。所有权胜过路过的补丁工——临时修复者会为每条发现重建上下文,而且没有任务框架。如果宿主不支持续聊子代理,就新派一个,带上任务单路径、报告文件路径与发现(报告文件无论如何都是持久记忆) |
| 第 4–5 轮 | 派一个全新实现者,模型至少高一档 | 带任务单、报告文件、开口发现,以及一句框架:"前一个实现者尝试了这个任务 N 次,现在归你。读报告文件看它试过什么。"设计文档的原话是:"能扛过三次 resume 的循环,通常意味着实现者看不见自己的问题——换一双眼睛和升一档能力,一步同时完成。" |
第 5 轮之后:跳闸,由你逐条裁决
第 5 轮的重审仍留着开口发现时,停止派发,控制者逐条裁决。三种处置的区别很关键:
| 发现的性质 | 处置 | 为什么不能一律 park |
|---|---|---|
| 评审错了 / 可以争议 | park,并写下为什么这段代码可以站着;末端评审会看到两边 | 你手上有计划与跨任务上下文,评审者没有——盲从评审和盲拒评审一样错 |
| 真实,但下游不建在它上面 | 同样 park,裁定写明"它是真的,但延后" | 它不阻塞任何东西,进循环只会消耗轮次 |
| 真实且承重(后续任务要建在它上面,或它暴露了计划缺陷) | 裁定最小解锁改动 + 记账 + 带进下一个任务的派发;只有"每条前进的路都是猜"时才停 | 静默 park 一个结构性失败,等于让每一个依赖它的任务都建在它上面——把结构性失败推迟到最贵的时刻引爆 |
两条配套纪律,保证"跳闸"不被用成"提前放弃"
只在到上限时裁决——原文有一句很尖锐的话:"提前裁决来结束循环,是换了个名字的预判。"每次裁决都是账本里的一行——静默丢弃是被禁止的。
四种典型借口(都是原文点名过的)
把五件事合起来看:有上限(5 轮);有换人策略(3 轮续聊、2 轮换人升档);重审范围受限(只看修复 diff);次要发现不进循环;与计划冲突的发现走裁定而非循环;到点由持有更多上下文的角色裁决并全部记账。这套组合把"循环会不会停"从一个概率问题变成了一个结构问题——它一定会停,而且停下来时留有记录。
19三条由观测换来的"不许"
评审环节有三条禁令,它们的共同点是:都不是从原则推出来的,而是从真实会话的成本观测里收回来的。
| 规则 | 原文的说法 | 它背后的观测 |
|---|---|---|
| 不写开放式指令 | 没有具体、任务相关的理由,不许写"检查所有用法""如果觉得有用就跑一下竞态测试" | 每一条"观察到的大规模或重复测试运行",都是控制者写的 prompt 明确要求的——评审者不会自己乱跑,是被指示去跑的 |
| 不让评审者重跑实现者刚跑过的测试 | 实现者的报告已经带着测试证据 | 同一份代码跑两遍不产生新信息,但会产生真金白银的账单 |
| 不替评审者预判发现 | 如果正在写的 prompt 里出现"不要标记""别把 X 当缺陷""最多算 Minor""计划就是这么选的"——停,你在预判 | 这通常是为了给自己省一轮评审。这条的补充说明更直白:如果你认为某条发现会是误报,让它提出来,然后在评审循环里裁决 |
⚠️ 第四条禁令:实现者不许自己派子代理,尤其不许派评审者
派发里带着一条"无子代理契约",实现者的模板里写着:这件事的活你自己做完。绝不派子代理去实现任务的一部分,尤其绝不派一个评审者来检查你的工作。它还给了一句我认为很有用的解释——如果你心里冒出"多一个独立评审会让我的报告更强",那个评审已经安排好了,报告即可。
技能把"工人自带的评审者"明确定义为一个应当被标记的缺陷,而不是严谨。理由:每个工人自己生出来的评审者都在重复控制者本来就会派的那个任务评审——等于每个任务白付一个评审座位。
这条对你有直接用处:看到"我自己又派了个代理帮我审了一遍"这种描述时,应该当成流程出错的信号,而不是加分项。
20任务之间不许停下来问:连续性是被写进规则的
SDD 里有一条明确的"不要",语气很重,中文重述是:不要在任务之间停下来跟人类伙伴确认,把计划里的任务全部执行完再停。唯一的停止理由是那四个具名条件,或者所有任务完成。原文把"要继续吗?"这类提示和进度小结("目前 2/5")称为浪费他们的时间——"他们让你执行计划,那就执行"。
为什么这条规则值得单独讲
因为它和多数人对"AI 代理"的期待正相反。多数人觉得"多问我一句更安全",但这个流程算的是另一笔账:把"人"当默认检查点,等于把最贵的收益(无人值守连续推进)主动放弃,而且把"执行"降级成了"轮流批准"。所以判据是:你停下来要问的这件事,属于那四类之一吗?不属于,就该裁定 + 记账 + 继续。
先分清"动工前"和"执行中"
动工前:批准闸门永远要等一个明确的 yes,任务再小也不省——你在"开始做之前"保留了全部控制权。执行中:四类之外全部自己裁定(格式固定:决定了什么 / 为什么 / 错了的代价),记进账本,继续——你在"已经开始做之后"换来了不被阻塞的推进。两个时刻、两套规则,互不侵蚀。授权大胆的前提是"错误可撤销、且记账后可见",这个前提在下一节变成了四条边界。
与连续性配套的还有一条等待纪律:绝不用短超时反复轮询,也别一声不吭地无限等。手上有本地活(更新账本、打包下一份评审、读报告)就继续做;真的闲着时按有限时段等(平台允许的话五到十分钟一段),每段之间发一行状态并核对还活着的子代理。如果你看到它每隔几秒看一次子代理状态,那是回归。
21账本:进度为什么必须写在文件里
这是整套流程里最"不优雅"、也最有证据支撑的一节。SDD 的 Setup 段第一句就是这条痛点的记录:
# 原文(skills/subagent-driven-development/SKILL.md,2026-09-13 抓取)
Conversation memory does not survive compaction. In real sessions,
controllers that lost their place have re-dispatched entire completed
task sequences — the single most expensive failure observed.
中文重述:对话记忆活不过上下文压缩。在真实会话中,丢失了进度的控制者重新派发了整批已经完成的任务序列——这是被观测到的最昂贵的失败。
它到底有多贵,设计文档里记了三组可核对的数字(前两组来自"没有隔离"时期,第三组来自一次压力测试):
那次压力测试推翻了一个假设,也校准了一个说法
测试场景是"上下文压缩后恢复",而且故意把本该失败的条件都摆好:一个陈旧扁平路径的账本(属于另一个计划)、另一个计划自己的已完成目录、而当前计划一份记录都没有。
- 结果:25/25 次控制者都拒绝了把别人的账本当自己的进度用(三个轮次、五个单元格、每格五个全新子代理)。假设中的失败——盲目采信陈旧外部账本——没有复现。
- 但可复现的代价还在:在最接近真实崩溃恢复的那一轮里,每个控制者平均仍要花 9.0 次工具调用(7、13、9、10、6)去先证明这份账本不是自己的,然后才开始干活。
这里要说清一件容易被讲反的事:新的目录结构并没有把这个数字降下来。同一份报告给出的对照是——结构性改造之后,同一场景的原始工具调用数反而变成 9.6 次(9/11/9/7/12),因为新夹具里的陈旧材料更多(多了"自己的空目录""扁平旧账本""另一个计划的已完成目录"三处,而旧夹具只有一处扁平账本)。
旧结构下控制者只能靠跨计划的提交/计划文件取证来判定归属,因为文本没给它别的办法;新结构下它靠结构判定:解析本计划的 workspace、先看账本第一行的身份。报告的原话是 "misattribution is now impossible when every ledger names its plan — is the load-bearing result, not a call-count reduction this scenario does not demonstrate."(承重的是"误认不再可能"这个结构性质,不是这个场景没能展示的调用数下降。)
账本的格式:几行字符串,每一行都有语义
账本就是一个纯文本文件 progress.md,放在这个计划专属的、被 git 忽略的工作区里。格式看起来简陋,但每一行都是为了让下一个接手的人(或代理)能据此行动:
| 行 | 格式 | 它为什么必须长这样 |
|---|---|---|
| 身份(第一行) | # SDD ledger — plan: <计划文件路径> | 没有它,恢复时无法回答"这是不是我的进度"——上面那次取证开销就是这么来的 |
| 延后的次要发现 | Task <N>: minor (deferred): <一句话> | 这些不进修复循环,但末端评审要指着这份清单来分诊哪些必须在合并前修 |
| 修复轮次 | Task <N>: fix round <R>/5 (<X> addressed, <Y> open — <发现摘要>; commits <a7>..<b7>) | 最后一行是这个格式,说明该任务正卡在循环里,恢复时从下一轮续 |
| 裁定 | Ruling: <决定了什么> — <为什么> — <错了的代价> | 见下方"裁定必须活着走出去" |
| 完结 | Task <N>: complete (commits <base7>..<head7>, review clean) | 恢复时,有这行的任务绝不重派 |
| park | Task <N>: parked — <发现> — Ruling: <为什么这段代码可以站着> | 跳闸后的处置,末端评审要看到两边 |
一份真实形状的账本大概长这样(内容不重要,注意行的种类与顺序):
# SDD ledger — plan: docs/superpowers/plans/2026-09-13-export-filtered.md
## Preflight rulings
- Task 1 × Task 2 共享 to-csv.ts → 接口以 Task 1 的签名为准
- Task 3:"始终有表头"与空数组分支矛盾 → Ruling: 空数组也输出表头
## Progress
Task 1: complete (commits 4f2a9c1..8b3d0e7, review clean)
Task 2: minor (deferred): CSV 转义只覆盖逗号,未覆盖换行
Task 2: fix round 1/5 (2 addressed, 0 open — 魔法数字/进度上报; commits 8b3d0e7..c19f4aa)
Task 2: complete (commits 8b3d0e7..c19f4aa, review clean)
Task 3: parked — 导出文件名时区未处理 — Ruling: 不在本计划 spec 范围内,延后
为什么必须记"提交号",而不只是"任务 3 已完成"
因为 账本给的是坐标,真相在 git 里。技能原文说得很关键:账本里记下的提交号在 git 里真实存在,即使你的上下文已经想不起来创建过它们。由此推出一条纪律:被压缩之后,信账本和 git log,不要信你自己的回忆。
还有一条警告:这个工作区是草稿区,会被清掉——技能正文直接点出 git clean -fdx 会摧毁它(它是被 git 忽略的临时区)。撞上时的恢复办法不是找回文件,而是从 git log 恢复;这正是"必须记提交号"的另一半理由。
🚨 收尾时最容易漏的一步:裁定必须活着走出去
SDD 收尾有一条特殊要求:删除工作区之前,把账本里每一条含 Ruling: 的行收集进最终消息,标题叫 "Rulings I made",按做出决定的顺序排列,每条附上"错了的代价"。原文把严重性说透了:
"那份清单是你在人类伙伴不知情的情况下替他做出的决定,唯一能到达他手上的地方……一条随工作区一起消失的裁定,等于一个在暗处做出的决定。"
原因很实在:工作区会被 rm -rf 删掉,记录移交给 git 历史——但裁定不会自动进入 git(它只是工作区里的几行文字)。所以这一步漏了,你就再也看不到代理替你做了哪些判断。技能对这份清单的要求是穷尽:账本里有几条裁定,清单里就有几条。
22压缩或换会话之后,怎么接着做
恢复动作被写成三条判断,顺序固定,都能机械执行。这也是你可以亲手复核代理行为的地方——打开工作区里那个 progress.md,看第一行。
| # | 看什么 | 据此做什么 |
|---|---|---|
| 1 | 第一行写的是不是你的计划文件 | 不是 → 那是别人的进度,原地留着,自己新建一份。旧扁平路径(.superpowers/sdd/progress.md)同样按"别人的"处理 |
| 2 | 有没有 Task <N>: complete | 有这一行的任务不要重派,从第一个没有这行的任务续上 |
| 3 | 最后一行的形状 | 是修复轮次行 → 该任务正卡在循环里,从下一轮续,而不是从头重审 |
这三步能成立,靠的是上一节那条设计:一个计划一个目录 + 第一行写身份。它省下的不是"少犯错",而是每次都少花一次取证开销——这个思路本身值得学:一个机制的价值不一定要体现在"避免灾难"上,也可以体现在"把每次都要付的税砍掉"。
用一张 todo 列表 + 会话记忆跟踪"哪些任务做完了",在短会话里工作得很好——这也是它流行的原因。代价是:上下文一被压缩,todo 与记忆一起消失,而代码已经提交、看起来像做过了;控制者没有办法区分"这个文件是我做的"和"本来就有的",于是最省事的动作就是重做一遍——原文把这条列为观测到的最昂贵失败。
判据很简单:你的进度记录,能不能在一次上下文压缩之后独立地回答"第 3 个任务做完了吗"?
23只有四件事能停下它,其它一律自己裁定
这是理解整套流程"性格"的关键一节。SDD 用两个小标题定义了自己的行为准则,第一个是 "Rulings, not stalls."(裁定,而不是停摆):
# 原文(skills/subagent-driven-development/SKILL.md,2026-09-13 抓取)
A running plan does not wait on a human. Conflicts, ambiguities,
plan defects, a cap you would have asked to exceed — decide them.
The spec is the binding authority, the plan is its argument, and
your judgment settles what neither answers. ... A wrong ruling costs
rework your human partner can see and undo; a session parked on a
question costs their whole day and buys nothing.
中文重述:运行中的计划不等人。冲突、歧义、计划缺陷、一个你本来会申请突破的上限——都由你决定。spec 是有约束力的权威,plan 是它对 spec 的论证,两者都没回答的部分由你的判断来定。每条决定都要记成 Ruling: <决定了什么> — <为什么> — <如果错了代价是什么>,然后继续。
最后那句是整段的灵魂:一个错误的裁定,换来的是人类看得见、也能撤销的返工;一个停在问题上的会话,换来的是他一整天的等待,而且什么都没买到。这是一个明确的经济学取舍:用"可撤销的错误"换"不阻塞"。让这个取舍不至于失控的,是下面四条边界。
四件必须停下来的事
| 停机条件 | 它长什么样 | 为什么它不能交给"裁定" |
|---|---|---|
| 1. 不可逆或破坏性操作 | 删数据、强推、rm -rf 掉不该删的东西、--force 清理 | 错误裁定的前提是"可以撤销"。不可逆操作让这个前提消失,"看得见、能撤销的返工"于是变成看不见的损失 |
| 2. 安全敏感动作 | 改权限、动密钥与凭证、放宽鉴权 | 失败模式不是"返工"而是"泄露"——代价的量级和概率都换了种类 |
| 3. 本工作区之外的副作用 | 合并、推送到共享分支、发布——原文补了一句"按惯例你就该先问的那些" | 影响面超出这个隔离工作区,已经影响到别人的工作 |
| 4. 计划烂到每条前进的路都是猜 | 不是"这一条不清楚",而是所有可走的路都需要猜 | 裁定要有依据(spec 或计划文本);当所有路都无据可依时,任何裁定都只是编造 |
注意第四条的门槛被刻意设得很高:"每条路都是猜",而不是"有点不清楚"。它的作用是防止把"裁定"这个工具用来逃避思考——发现计划有缺陷时,默认动作是裁定最小修正并记账,只有连最小修正都无从谈起时才停。
❌ 错误:把"人"当成默认的检查点
"我做完任务 1 和 2 了,要继续吗?"
"任务 3 有个小歧义,等你回复再动手。"
"给你一个进度小结:目前 2/5……"
代价:原文认为这些是浪费人类时间——他们已经把计划交给你执行了。而且它把"执行"降级成了"轮流批准",等于把 SDD 最贵的那部分收益(无人值守连续推进)主动放弃。
动工前:批准闸门永远要等一个明确的 yes
执行中:四类之外全部自己裁定
格式固定(决定了什么 / 为什么 / 错了的代价)
记进账本,继续
好在哪:你在"开始做之前"保留了全部控制权,在"已经开始做之后"换来了不被阻塞的推进。两个时刻、两套规则,互不侵蚀。
⚠️ 这条授权反过来用,就是整套流程最危险的地方
"我自己裁定"这句话,如果被用在四类停机条件上——比如顺手强推了一个分支、或者用 --force 清了挡路的工作区——那么这套流程用来兜底的那个机制就失效了:裁定之所以可以大胆,是因为错误可撤销、且记账后可见;破坏性与安全敏感动作同时打破了这两条。你读代理输出时最该盯的就是这里:它把哪些动作归类成了"可裁定的"。
反过来的误判:有三类提问是设计如此
不要因为它停下来问你就断定"又卡住了"。有三类提问本来该发生:① 动工前的批准闸门(每条路径、每个任务都要);② brainstorming 的澄清提问(一次问一个,而且偏好多选题);③ 上面那四类停机条件。真正的异常是另一种:在"已经批准、正在执行"的阶段,为了一件四类之外的小事来问你。把这两者分开看,你就不会去"修"正确的行为。
24末端评审与收尾:一次宽评审,一个由你选的菜单
末端评审:一次,很宽,最强模型
所有任务走完之后,流程做一次全分支评审(不是每任务那种窄评审),四个特点都有理由:
| 特点 | 具体做法 | 为什么 |
|---|---|---|
| 范围是整个分支 | diff 包用 MERGE_BASE..HEAD(MERGE_BASE 是这条分支的起点,例如 git merge-base main HEAD),同样写成一个文件交给评审者 | 免得它自己用 git 命令反复推导、把上下文花在拼 diff 上 |
| 模型钉在最强档 | 技能在模型选择那一节专门点名:全分支评审"是一种架构与设计类任务——用可得的最强模型派发它,而不是用你会话的默认模型" | 架构级问题需要最强的判断力,且整条分支只此一次 |
| 模板换成宽模板 | 用 requesting-code-review 的评审模板 | 这也正是 02 节那个"模板归属"问题的答案:窄的归 SDD 自带模板,宽的归这里 |
| 要指着账本分诊 | 把账本里"延后的次要发现"与"park"行指给末端评审,让它判断哪些必须在合并前修 | 这是"Minor 不进循环"之所以安全的前提——如果不给末端评审,那份清单就是白记的 |
有发现时:恰好一次修复波
处置方式是硬性的:派一个修复子代理,带上完整的发现清单——不是每条发现一个修复者;然后恰好一次范围受限的重审(同样只看修复范围),残余发现按跳闸那套处理。没有第二轮修复波,剩下的承重发现会在收尾阶段呈现给你。
为什么这么抠?设计文档给的成本结论很具体:"一次真实会话的末端评审修复波,花的钱比它所有任务加起来还多。"原因是每条发现一个修复者时,每个修复者都要重建上下文并重跑测试套件——纯粹的重复开销。
收尾:动作顺序是固定的五步
最后一个技能 finishing-a-development-branch 把这个顺序写成了一条链:验证测试 → 探测环境 → 呈现选项 → 执行选择 → 清理。顺序本身是规则,其中两处最容易出错:
| 步骤 | 做什么 | 容易错在哪 |
|---|---|---|
| 验证测试 | 跑项目完整测试套件;失败就报告失败并停——"菜单在绿色测试之后" | 用"这个会话早些时候测试过了"当理由。原文的反驳:一次绿色运行只证明了它跑的那棵树,要在你即将整合的那棵树上跑 |
| 探测环境 | 取 GIT_DIR / GIT_COMMON,并趁还在工作区里先记下 WORKTREE_PATH | 清理阶段需要这个值,但那时已经 cd 出工作区了——所以原文特意注明"趁现在捕获" |
| 呈现选项 | 普通仓库与具名分支的工作区:恰好三个——① 本地合回基线分支 ② 推送并创建 PR ③ 保留分支不动。detached HEAD:恰好两个(去掉本地合并)。呈现完等你回答 | 替你做决定("他们显然想合并")——原文:整合是你的决定 |
| 执行选择 | 选合并时:先合并、在合并结果上再跑一次测试,绿了才清理工作区、再删分支 | 合并结果测试失败时自作聪明:"大概是 flaky 吧"——原文:失败的合并结果会停下一切,分支与工作区都原地留着,先查 |
| 清理 | 只清理 .worktrees/ 或 worktrees/ 下的(那是 Superpowers 自己建的);其它位置属于宿主环境,别动 | 顺手把"看起来很久没用"的别的 worktree 也清了——原文:不属于你的就留给宿主 |
"丢弃"是一条隐藏路径
三个选项里没有"丢弃这份工作"。它只在你明确要求扔掉时出现,且出现时必须先把要删的东西摆出来:分支名、全部提交的清单、工作区路径,然后要求你亲手打出 discard 才算确认——随口一句"行,删了吧"不算。
清理时如果 git worktree remove 报"contains modified or untracked files"被拒,它的含义是那个工作区里有文件只存在于那里——没提交的计划、笔记、草稿。技能的处理是:先跑 git status --porcelain -uall 把风险摆给你看,再给三个选项(先提交到分支 / 搬到主仓库 / 删掉(不可恢复)),等你选。
原文把"顺手 --force"单列成一条要警惕的借口,理由是:拒绝就意味着有文件只在那里,--force 会永久销毁它们。
git merge-base main HEAD # 取 MERGE_BASE,给末端评审的 diff 包用
npm test # 全量测试:菜单只在绿色之后出现
git status --porcelain -uall # 工作区删不掉时,先把风险摆出来
git worktree remove .worktrees/feature-export
git branch -d feat/export-filtered
25代价与模型纪律:为什么"用最便宜的模型"经常更贵
这套流程有一批看起来很"抠"的规则(不许贴历史、diff 交给文件、Minor 不进循环、一次修复波)。它们不是洁癖,而是一组被反复测量的成本结论。最有反直觉价值的一条是:
墙钟时间与上下文成本随子代理的回合数增长,而最便宜的模型在多步工作上经常要花 2–3 倍回合——整体反而更贵。因此技能给出的模型下限是:评审者与照散文描述干活的实现者,用中档模型当地板;只有当计划文本里已经含完整待写代码、实现退化成"抄写 + 测试"时,才用最便宜档;单文件机械修复同样用最便宜档。
它还有一条硬要求:每次派发都必须显式写模型。原文解释了原因:省略模型会让子代理继承你会话的模型——那通常是可得的最强也最贵的那个——从而静默地废掉整个模型选择策略。
一次"加固反而变贵"的实测:读数字才看得见的东西
同一份评测场景(一个叫 go-fractals 的图形程序)在不同配置下的公开数字如下。第三列的解读是必要的——只看前两列会得出错误结论:
| 配置 | 时间 / token / 花费 | 怎么读这一行 |
|---|---|---|
| 基线(改动前) | 64.9 min / 21.2M / $16.07 | 对照点 |
| 第一个"任务范围评审"版本 | 42.8 min / 14.5M | 把评审范围收窄到任务,立刻拿到大幅下降 |
| 加了"质量加固"文案之后 | 69.9 min / 32.2M | 比基线还贵,而盲评质量与基线持平(8.5 vs 8.5)。加固不是免费的——这一版把成本推到了最差 |
| 迭代 1(回合数优先的模型指导、证据"引用而非叙述"等) | 68.2 min / 22.9M | token 降了约 29%,墙钟基本没动——说明省的是 token,不是时间 |
| 迭代 2(两个评审合并成一个任务评审;实现者迭代时跑聚焦测试、提交前跑一次全量) | 47.5 min / 15.7M / $13.55 | 每一轴都胜过基线,而且盲评 9/10 vs 基线 7/10——这是"更便宜且更好"的那一版 |
| 最终冻结配置 | 44.4 min / 13.4M / $11.67 | 文档自报 −32% 时间 / −37% token / −27% 花费(这几个百分比我复核过,见下) |
为什么会"加固反而变贵"?文档给出了逐个子代理的回合剖析,结论按影响排序是:便宜模型在多步工作上回合数翻倍(1197 个子代理回合里有 678 个是最便宜的那一档)、每次派发的固定开销(每个任务起 3 个子代理、每个都要自己重新推导 diff;控制者协调本身占了一半的钱)、以及证据叙述的开销。这就是"回合数比单价重要"这句话的来源。
我自己复核过的两件事
上面这些数字是维护者自己的评测记录,我没有条件复现整套实验——但凡是能用文档里给出的绝对数除出来的比例,我都除了一遍,并把方法写在这里,你可以手工验证:
- 三个百分比:44.4 ÷ 64.9 = 0.684 → −31.6%;13.4 ÷ 21.2 = 0.632 → −36.8%;11.67 ÷ 16.07 = 0.726 → −27.4%。文档写的是 −32% / −37% / −27%,三个都在四舍五入范围内成立。
- "最差一抽也胜过基线":文档说同设计的 8 次运行分布在 44.4–57.1 分钟 / 13.4–20.0M / $11.67–14.84;拿最差那端与基线比——57.1 < 64.9、20.0 < 21.2、14.84 < 16.07,三个轴全部成立。
- 顺带算出的极差:57.1 ÷ 44.4 = 1.286,即同样 prompts 下最好与最差相差 28.6%。这解释了文档为什么把结论都改写成区间、并声明了 ±6 分钟的噪声地板,也提醒你:任何单次成本数字都该当成区间里的一抽。
另一条被量化过的"评审越界"
任务级评审最初被做成"分支评审规模",文档记得很具体:一个真实会话里 8 个质量评审者有 7 个跑了全仓库 grep,最贵的跑了 50+ 次 Bash 命令、约 200 秒;同期规格评审者只花 6–16 次工具调用、14–65 秒——质量评审的成本是规格评审的 4–8 倍。修法本身比数字更值得记:不是禁止广度,而是把广度挂在"具名风险"后面——跨模块审计(锁顺序、变更的契约、共享可变状态)有时候正是正确的评审方法,"把广度门禁在一个说出口的具体风险之后,而不是禁止它"。
这一整节的目标从来不是"更便宜"。看迭代 2 那一行:它每一轴都更便宜,同时盲评分数更高(9/10 vs 7/10);而"加固反而变贵"那一版虽然质量与基线持平,也并没有因为贵而被留下。真正被优化的是"同一质量下的成本"——所有规则都服务于这个复合目标。
这一点对你的用法有直接影响:如果你为了省钱去关掉任务评审或跳过重审,你省掉的是这套流程唯一能证明"做完了"的部分——那就不是优化,是把这个产品的核心功能删了。原文对此的判词是:"没有评审的循环,只是未被验证的瞎忙。"
26常见坑:症状、根因、怎么避免
下面每一条都是"你会看到什么"先行——因为症状是你能观察到的,根因不是。
| 坑 | 你会看到的症状 | 根因与怎么避免 |
|---|---|---|
| 把七步当铁轨 | 改一行配置也要陪它看完一份设计文档 | 忽略了第一条决策会把流程劈成三条路径。看到它宣布分类时就用一句话复核——这是最便宜的纠偏时机(05) |
| 让子代理读整个计划文件 | 子代理开始讨论"另一个任务"的事,或擅自改了别的模块 | 它被灌进了与它无关的任务。正确做法是给它任务单文件 + 一句话定位 + 早前任务的接口(14) |
| Minor 发现被"顺手"修掉 | 修复循环莫名多跑好几轮,任务迟迟不结束 | Minor 的处置是记账延后、交给末端评审分诊,它不该进循环。进了循环就等于让"所有问题"都有权拦住任务(18) |
| 为评审者预设结论 | prompt 里出现"这个不算缺陷""最多算 Minor""计划就是这么写的" | 这是预判,通常是为了给自己省一轮评审。正确做法是让发现被提出来,然后在评审循环里裁决——而且裁决要记账(19) |
| 用记忆或文件时间判断进度 | 上下文压缩后,已经完成的任务被重做一遍 | 原文称这是"观测到的最昂贵失败"。恢复时信账本与 git log,不信回忆;账本第一行的身份行就是为了让这件事可判定(22) |
| 把二手摘要当实现真相 | 照着一篇博客去理解它的行为,然后发现对不上 | 本文自己就是二手来源(只是我读了原文并标了口径)。"它到底会不会 X"这类问题,去读对应技能的 SKILL.md——摘要会漂移,实现不会(29) |
| 把"裁定"用在不可逆操作上 | 日志里出现强推、--force 清理、直接动密钥 | 裁定的授权前提是"错误可撤销且可见"。四类停机条件(不可逆 / 安全敏感 / 工作区外副作用 / 每条路都是猜)必须在动手前问你(23) |
三对最容易混的东西,一句话分清
| 容易混的一对 | 差在哪 | 会怎么混错 |
|---|---|---|
| 流程技能 vs 实现技能 | 前者决定"怎么做事"的顺序与闸门,后者提供"用什么做"的领域知识 | 先挑工具再定做法,于是在错的框架里写得很快 |
| 任务评审 vs 末端评审 | 前者窄(一个任务的 diff、两个判定),后者宽(整条分支、一次、最强模型) | 把任务评审做成全分支规模 → 又慢又贵;或者指望任务评审兜住架构问题 → 漏到最后才炸 |
| 裁定 vs 停机 | 裁定用于"有依据、可撤销、必须继续"的情况;停机用于四类"错了就不可挽回"的情况 | 把不可逆操作当裁定处理 → 流程的兜底机制整体失效 |
四类"看起来像坑、其实是设计"的行为
| 行为 | 为什么它是设计 | 什么时候它才是坑 |
|---|---|---|
| 动工前反复确认方案 | 批准闸门不随任务缩水 | 你已经说了明确的 yes,它还在确认 |
| brainstorming 一次只问一个问题 | 提问是流程的规定动作,且偏好多选题 | 问的东西你已经答过,或者它拿问题当拖延 |
| 遇到不可逆 / 安全敏感动作就停 | 四类停机条件之一 | 它把"改个注释"也归进不可逆 |
27术语对照表
这些词在这套流程里都有特指,用日常义去理解会正好理解反。第三列回答"为什么重要、什么时候用、别把它当成什么用"。
| 术语 | 在这套流程里指什么 | 为什么重要 / 何时用 · 别当什么用 |
|---|---|---|
| skill(技能) | 一份带触发条件的操作说明文件(SKILL.md):可能是流程(brainstorming),也可能是实现细节 | 这套体系的最小规则单元。别当成"提示词模板"——它有触发条件、有强制动作,还会被出题评测 |
| 流程技能 vs 实现技能 | 前者决定"怎么做事",后者决定"用什么做" | 冲突时流程技能优先。先定做法再选工具;反过来会在错的框架里写得很快 |
| subagent(子代理) | 为一个任务新起的代理,不继承你会话的上下文或历史 | 上下文隔离的实现手段,也是 SDD 全部收益的来源。别当"便宜的打字员"——它的价值恰恰在于不知道你的历史 |
| brief(任务单) | 从计划里抽出的单个任务的完整原文,写成独立文件发给实现者 | 派发的唯一需求来源,确切值(数字、签名、测试用例)只在这里。别用"让子代理读整个计划"代替它 |
| ledger(账本) | <workspace>/progress.md,一行一条,第一行是身份行;含提交号、修复轮次、裁定、park | 压缩后唯一的恢复地图。别当成给人读的进度报告——它只有坐标没有叙述,也别指望它记全细节,真值在 git 里 |
| workspace(计划工作区) | <repo-root>/.superpowers/sdd/<plan-basename>/,一个计划一个,装账本、任务单、报告、评审包 | 边界是"哪个计划"而不是"哪个项目"——跨计划混用正是那次取证开销的来源。别读写别的计划的目录,也别指望它长期存在(完成即删) |
| 任务评审 | 每完成一个任务后的窄评审,要给出两个判定:规格合规 + 任务质量 | "做完了"的唯一依据(实现者自审不算)。别把它做成全分支评审——那是末端评审的活 |
| 范围受限重审 | 修复后的重审,只看 FIX_BASE..HEAD,对每条发现判 addressed / not addressed | 循环能收敛的结构保证。别理解成"再全审一遍"——那种重审每轮都会翻出新发现 |
| 末端评审 | 全部任务完成后一次全分支宽评审(MERGE_BASE..HEAD),最强模型,并分诊账本里延后的 Minor | 宽度的唯一合法出口。别指望任务评审兜住架构问题,也别在它之后安排第二轮修复波 |
| 断路器(breaker) | 修复循环第 5 轮仍不干净时"停止派发、由控制者逐条裁决"的机制 | 把"会不会停"从概率问题变成结构问题。别当失败信号——跳闸后正确动作是裁决 + 记账 + 继续 |
| 裁定(ruling) | 控制者对计划没写的情况自己做决定,格式固定:决定了什么 / 为什么 / 错了的代价 | "不阻塞"与"可追责"之间的交换条件:因为敢裁定,所以必须记账。它不能用在四类停机条件上 |
| park(挂起发现) | 把一条发现记进账本、带裁定、不进循环、留给末端评审看 | 处理"真实但不阻塞"和"评审错了"两类。别用它处理承重发现——那等于让每个下游任务都建在它的缺陷上 |
| worktree(隔离工作区) | 让改动不影响你当前分支的独立检出目录(或宿主提供的等价机制) | 流程的场地条件,不是一环。第一动作是检测是否已隔离;别绕过宿主自带的工具,也别建在没被忽略的目录里 |
| 闸门(gate) | 必须拿到人类明确同意才能通过的点,例如动工前的批准闸门 | 规则是"仪式随任务缩水,闸门永远不缩"。别把"没反对"当成"同意" |
| 分类(classification) | 把请求判成 spike / bounded / architectural 三条路径之一 | 决定后面所有工件的重量。"流程太重"的抱怨十有八九是分类判重了,不是规则错了 |
28速查表:每一步的起点、产出与硬规则
阶段速查
| 阶段 | 起点条件 | 强制产出 | 最容易漏的硬规则 |
|---|---|---|---|
| 分类 | 任何请求(包括"简单问题") | 说出分类结果 | 拿不准选重的;棘轮单向,只能升级(05) |
| brainstorming | 要做创造性工作之前 | spike:建议;bounded:对话内短设计;architectural:设计文档 | 批准闸门三条路径都不能省;architectural 之后只能接 writing-plans(06) |
| 隔离 | 设计批准后 | 隔离工作区 + 干净的测试基线 | 先检测再创建;创建前必须确认目录已被忽略(07) |
| writing-plans | 有已批准的设计(architectural) | 计划文件(含强制头部五件套) | 零占位符;自审三步;写完把两条执行路径交给用户选(11) |
| SDD Setup | 选择了子代理驱动 | workspace + 账本(带身份行)+ 每任务一条 todo | 派发前先做计划冲突预扫并写表;无人类同意不在 main 上实现(13) |
| 每任务循环 | 预扫完成 | 提交 + 两判定评审 + 账本一行 | 绝不并行派实现者;绝不预判发现;绝不带未决 Critical 进入下一任务(12) |
| 修复循环 | 规格 ❌ / Critical / Important / 已确认的 ⚠️ | 修复提交 + 修复报告(含测试、命令、输出)+ 账本轮次行 | 上限 5 轮;1–3 续聊、4–5 换人升档;重审只看修复 diff(18) |
| 末端评审 | 所有任务完结 | 一次全分支评审 + 至多一次修复波 + 一次重审 | 最强模型;一次派发带全部发现;没有第二轮修复波(24) |
| 收尾 | 末端评审干净 | 全量测试报告 + 三分支(或两分支)菜单 | 菜单在绿色测试之后;只在明确要求时出现 discard,且要打出那个词(24) |
"什么时候该停下来问你"已经在 23 节的对照里讲过了;这里不再重复一张同样的表。
可以直接抄的东西
| 你要做什么 | 抄这个 | 在哪一节 |
|---|---|---|
| 准备隔离工作区并验基线 | git worktree add ../feature-export -b feat/export-filtered → npm install → npm test | 07 |
| 写一个合格的任务单 | Files / Interfaces / 五步(含 Run: 与 Expected:)的完整骨架 | 08 |
| 写计划头部 | Goal / Architecture / Tech Stack / Spec / Global Constraints 五件套 | 09 |
| 派发一个实现者 | 五要素派发模板(定位 + 任务单路径 + 接口 + 裁定 + 报告路径与契约) | 14 |
| 生成评审包并交给评审者 | scripts/review-package PLAN_FILE BASE HEAD;没有 bash 时用三条 git 命令重定向到一个文件 | 14 |
| 记录一次修复轮次与收尾风险 | Task <N>: fix round <R>/5 (…; commits <a7>..<b7>);工作区删不掉时先跑 git status --porcelain -uall | 21 / 24 |
五个反直觉点
- 简单任务也要批准。随简单程度缩水的是工件(两句话的设计),不是批准。沉默不算同意。
- 便宜的模型常常更贵。回合数比 token 单价重要;最便宜档在多步工作上要多花 2–3 倍回合。而且不显式指定模型 = 继承最贵的那档。
- 子代理不知道你的历史,是特性。把历史粘进派发(真实案例 42k 字符里 99% 是历史)既是成本,也是污染。一次派发只装一个任务。
- 循环靠"范围受限"收敛,不靠"更努力"。重审只看修复 diff;上限 5 轮;到点跳闸裁决并记账。没有上限的"再试试",正是被修掉的病。
- 官方摘要会跟实现脱节。七步摘要里"任务评审归谁"已经过时,而且整层账本机制没进摘要。判断行为要去读
SKILL.md。
29参考来源与证据边界
本文所有关于"它要求什么"的陈述,都来自下面这份文件清单。抓取时间:2026-09-13。我按"实际读到什么程度"分层列出,并标明每份文件在本文里承担哪一部分——没有读过的文件,本文不引用其内容。
A. 逐行读完的技能原文(本文主要依据)
skills/subagent-driven-development/SKILL.md(568 行)——第 12–24 节的主要依据:五步循环、四种报告状态、派发五要素、账本与工作区、修复循环与五轮上限、断路器三分类、"裁定不是停摆"与四个停机条件、末端评审、收尾前收集裁定的要求。skills/brainstorming/SKILL.md(250 行)——第 05、06 节:三条路径、批准闸门原文、"太简单不需要批准"反模式。skills/writing-plans/SKILL.md(171 行)——第 08–11 节:写给谁看、任务切分判据、2–5 分钟步骤、强制头部五件套、禁止写法清单、自审三步、执行交接的两条路径。skills/test-driven-development/SKILL.md(320 行)——第 08 节五步骨架与"删除先于测试写下的代码"。skills/using-superpowers/SKILL.md(63 行)——第 04 节全部:1% 规则原文、技能优先级、<SUBAGENT-STOP>、用户指令优先级、plan 模式前的 brainstorming 前置。skills/using-git-worktrees/SKILL.md(167 行)——第 07 节:先检测再创建、忽略检查、基线测试。skills/finishing-a-development-branch/SKILL.md(225 行)——第 24 节:五步链、两种菜单、discard 确认词、清理归属与--force禁令。skills/executing-plans/SKILL.md(64 行)——第 11 节两条执行路径的对照与"立刻停"四条。skills/requesting-code-review/SKILL.md(95 行)——第 02、24 节:宽评审模板的归属与"在何时必须评审"。- SDD 的三份派发模板:
implementer-prompt.md(154 行)、task-reviewer-prompt.md(207 行)、re-review-prompt.md(115 行)——第 14–16 节:无子代理契约、评审者输入清单、重审的三条输出契约。 - SDD 自带的三个脚本名:
scripts/sdd-workspace、scripts/task-brief、scripts/review-package——第 12、14 节的命令用法(我核实了这三个路径存在、读到它们在正文里的用法,没有逐行读脚本本体)。
B. 逐行读完的设计文档与仓库元数据
docs/superpowers/specs/2026-07-15-sdd-fix-loop-redesign-design.md(196 行)——第 17、18 节:修复前的"Repeat until approved"、三条设计决定(resume 原实现者 / 重审范围受限 / 五轮断路器)、"扛过三次 resume"的策略原话。docs/superpowers/specs/2026-06-09-sdd-task-scoped-review-dispatch-design.md(160 行)——第 02、14、25 节:模板归属被修掉的记录、质量评审 4–8 倍的数字、成本迭代表与 678/1197 回合剖析。docs/superpowers/specs/2026-07-06-sdd-plan-scoped-workspace-eval-results.md(543 行)——第 21 节整节的数字来源:25/25、9.0 次(7/13/9/10/6)与改造后 9.6 次(9/11/9/7/12)的对照表,以及"原始调用数没有下降、承重结论是误认不再可能"的原话。docs/superpowers/specs/2026-07-06-sdd-plan-scoped-workspace.md(196 行)——第 21 节:269 次派发 / 约 22 个任务、68 个文件来自三个计划、身份行与"每个计划一个目录"的设计理由。README.md(main 分支)——第 02 节的七步清单、How it works概述、技能清单。.claude-plugin/plugin.json——版本号6.3.0与仓库地址。- GitHub API:仓库元数据(默认分支
main、star 数、最后推送时间)、releases/latest、commits?per_page=10(确认 main 上最后一次提交是 2026-08-12 的发布提交b36e0829)、contents/docs/superpowers/specs。
C. 只下载/列了清单,未读、因此未引用其内容的文件
skills/receiving-code-review/、skills/verification-before-completion/、skills/systematic-debugging/、skills/dispatching-parallel-agents/ 四份 SKILL.md;docs/superpowers/specs/2026-06-10-strict-cost-sdd-design.md;evals/ 目录(夹具需单独初始化,本次未取)。
① 版本口径。本文以发布标签 v6.3.0(2026-08-12 发布)为锚点,实际抓取的是 main 分支 2026-09-13 的内容。抓取当天核对提交历史:main 上最后一次提交就是 2026-08-12 的发布提交,所以这批内容与 v6.3.0 应当一致——但我没有逐条比对标签与 main 的差异,需要精确对齐某版本时请 checkout 该标签。
② 仓库的"最后推送时间"不等于"代码有更新"。抓取时 API 报的推送时间晚于最后一次提交,说明当天有非提交类的引用更新(标签/分支)。我没把它当成"内容又变了"的证据——凡本文与旧版有出入处,都以提交历史里能定位到的文件内容为准。
③ 技能文本是"要求",不是"行为保证"。它规定的是代理应当怎么做;模型是否遵循是另一回事——仓库自己也正是因为这一点才维护了一套评测。所以本文通篇讲的是流程契约,不要读成"每次运行都会这样"。
④ 第 21 节那个数字我按原报告做了修正。旧版把"9.0 次工具调用"写成"新结构下仍要付的取证开销",并说这条设计"省下了这笔税"。原报告的对照表显示:新结构的原始工具调用数反而略升(9.6 vs 9.0),因为新夹具里的陈旧账本材料更多;报告明确写了"raw tool-call count did not drop",并把承重结论改成了"误认不再可能、不再需要内容取证"。本文按原报告的口径写作,并把两边都摆出来,而不是择一掩盖。
⑤ 成本数字不是独立复现。第 25 节的数字来自维护者自己的评测记录(go-fractals 等场景),本文只做到"用文中给出的绝对数复核其自报百分比"(方法写在那一节,可手工验算)。文档自己也承认:同样 prompts 下 8 次运行极差达 28.6%,并设有 ±6 分钟噪声地板——任何单次数字都该当区间看。
⑥ 时效:evolving。规则按月变化(本文引用的设计文档日期集中在 2026-06~07,本身就是持续改动的证据)。读到时若已过去数月,请以你本地版本的 skills/*/SKILL.md 为准,并优先复核第 12–19 节。
99一句话总结
这套工作流程是一串带闸门的接力:先分类(spike / bounded / architectural)再动手,动工前必须拿到一个明确的 yes;architectural 路径产出设计文档 → 计划 → 逐任务派发全新子代理;每个任务都要有独立的规格与质量判定,修复循环到第 5 轮就跳闸;执行期间只有四件事能停下它,其余全部由代理自己裁定、记账、继续——而进度必须写进一个带身份行的文件里,因为对话记忆活不过上下文压缩。你要盯的两个接口是:它把哪些动作用了"我自己裁定"(不该是不可逆的),以及收尾时那些裁定有没有被交到你手上。