Superpowers SDD 修复循环重构设计:让子代理驱动的评审-修复循环收敛且自主
本文基于 superpowers 仓库的设计规范 2026-07-15-sdd-fix-loop-redesign-design.md,系统讲解 subagent-driven-development(SDD)技能"评审-修复循环"的完整重构设计:如何用"resume 原实现者 + 范围限定的再评审 + 五轮断路器 + 控制器仲裁"四个机制,把原本无上限、可能无限打转的修复循环改造为结构性收敛且可自主执行的流程,并同步重构 SKILL.md 文档结构。读完后,你可以理解这套修复循环每一轮的精确规则(触发条件、轮次预算、再评审范围、仲裁路由),也能对照仓库中已落地的 SKILL.md、re-review-prompt.md 与配套脚本,在自己的 Agent 工作流中复刻同类的"收敛式评审-修复闭环"。
背景:SDD 评审-修复循环的四个真实问题
SDD 技能的工作方式是:每任务派发一个全新的实现者子代理,任务完成后派发一次任务评审(规格符合度 + 代码质量),全部任务完成后再做一次全分支终审。设计规范指出,旧版修复循环的循环体在字面上就是 "Repeat until approved"——没有轮次上限,且每轮再评审都是对完整 diff 的全量评审。设计文档记录了在真实会话中观察到的四个问题,它们是整个重构的出发点:
- 病理性评审循环。由于每次再评审都是一次全新的全量评审,非确定性的前沿评审模型每一轮都会提出新发现,而不是验证既有问题是否已修复。结果形成 implement → review → fix → review → review → fix → review → fix 的无限打转,没有任何断路器。此前 strict-cost 设计规范 独立测量过:评审循环次数是运行间成本方差的最大来源。
- 相互矛盾的修复政策。同一个技能里对"谁来修?"给出了三个答案:流程图与 "Constructing Reviewer Prompts" 小节要求派发专门的 fix 子代理;Red Flags 小节写 "Implementer (same subagent) fixes them";而 implementer-prompt.md 的 "After Review Findings" 一节又假定实现者会被重新唤起。
- 累赘的文档结构。旧 SKILL.md 有十三个顶层小节,同一活动的指导散落在其中四个;"Constructing Reviewer Prompts" 成了一个杂物筐,同时装着评审者指导、修复政策、终审政策和计划冲突仲裁。
- Red Flags 格式不一致。其余七个同级技能使用
| Excuse | Reality |理性化对照表,唯独 SDD 使用 17 条 "Never" 清单加三个 "If X" 小段落。
六项设计决策
设计文档以表格形式给出了六项核心决策及其理由,这六条是整个方案的骨架:
| # | 决策 | 理由 |
|---|---|---|
| 1 | 由原实现者修复自己的评审发现——就地 resume 它 | 它已经持有任务上下文;所有权胜过"路过的修理工"。全新的 "fix 子代理"要为每个发现重建上下文,且缺乏任务框架 |
| 2 | 再评审范围限定到具体发现(scoped re-review) | 每轮全新的全量评审正是循环打转的发动机。范围限定的再评审让循环结构性收敛;最终的全分支评审仍是宽幅安全网 |
| 3 | 五轮修复断路器:先 resume 三次,再在更强模型上新派发两次 | 一次能扛过三次 resume 的循环,通常意味着实现者看不到自己的问题——全新派发同时完成"去锚定"与"能力升档" |
| 4 | 断路器触发后由控制器仲裁并路由,不新增人工检查点;结构性失败走既有的 BLOCKED 停止条件 | SDD 的卖点是自主执行。控制器持有计划与跨任务上下文,这些正是评审者所缺的;既有文本早已授权控制器 "adjudicate it in the review loop",只是从未规定机制 |
| 5 | 按生命周期重组 SKILL.md,保留 eval 调优过的句子 | 从根上解决"难以遵循"。内容移动到其使用点,与仓库近期提交的方向一致(把 recap 小节折叠进使用点) |
| 6 | Red Flags 转换为 ` | Excuse |
其中第 1 条是全文最重要的机制转变:修复不再是一个独立角色,而是把原实现者"叫醒"继续干。第 2 条把"验证修复"与"重新评审"拆成了两个不同契约——这是循环能够收敛的关键。第 3、4 条则回答了"修不好怎么办":不再依赖人工介入,而是让持有完整上下文的控制器做有据可查的仲裁。
修复循环:每一轮的精确规则
触发条件与轮次划分
循环的触发条件:任务评审返回 spec ❌,或出现任何 Critical/Important 级别发现。
第 1–3 轮:resume 原实现者。 将发现逐字(原文)发送给它——Critical/Important 发现加上规格缺口。实现者修复、重跑覆盖性测试,把修复报告追加到已有的报告文件中,并返回简短状态契约。对于不支持 agent resume 的 harness,"resume" 等价于一次携带 brief、报告文件路径和发现清单的全新派发——无论哪种实现,报告文件都是持久记忆。仓库中 implementer-prompt.md 的 "After Review Findings" 一节正是按 resume 语义重写的:
If the task review finds issues, you will be resumed with the findings.
Fix them, re-run the tests that cover the amended code, and append a fix
report to your report file: what you changed, the covering tests you
ran, the command, and the output. Reviewers will not re-run tests for
you — your report is the test evidence. Then reply with the same short
status contract as your first report.
第 4–5 轮:全新实现者 + 更强模型。 携带完整任务上下文:brief、报告文件、未关闭发现,以及一句接管框架——"a prior implementer attempted this N times; you own the task now"。设计文档的理由很直白:扛过三次 resume 的循环,通常意味着原实现者看不到自己的问题,全新派发一举完成"去锚定 + 能力升档"。
每一轮的再评审都是范围限定的。 再评审者收到四样东西:brief、更新后的报告、原始发现清单,以及一个修复范围的 diff 包——即 review-package FIX_BASE HEAD,其中 FIX_BASE 是上一位评审者最后看到的 head。仓库中的 scripts/review-package 本身就接受任意 commit 区间(生成 commit 列表、git diff --stat 和带 -U10 上下文的完整 diff,写出到按区间命名的文件),因此修复轮次的增量 diff 无需任何脚本改动即可支持。再评审者对每个发现给出 addressed / not addressed 判定,只检查修复 diff 中引入的新破坏;落在修复未触及代码上的新发现以非阻塞方式上报,由控制器记入台账留待终审。
完整性门禁与"不早退"
修复报告完整性门禁(既有规则,保留): 派发再评审之前,必须确认修复报告中写明了覆盖性测试、执行的命令、输出三要素,齐备才能派再评审。这一条堵住了"嘴上说修好了"的空洞修复报告。
不早退(no early exit): 控制器绝不能在到达轮次上限之前进行仲裁——提前仲裁会重新打开"预判决发现、省掉一轮评审"的口子,而这正是旧版内容刻意封堵的行为。唯一例外(与现状一致):与计划文本相冲突的发现立即上交给人类——这是计划权威问题,不是循环打转问题。
Minor 发现绝不进入循环: 按既有规则,随到随记入台账(Task <N>: minor (deferred): <one-liner>),指向终审去分诊。
断路器触发时的仲裁
第五轮失败后,控制器停止派发,对每个未关闭发现基于 brief、计划与跨任务上下文做判定,分三种路由:
- 有争议或评审者错了 → 记入台账并附一行仲裁结论("controller: reviewer wrong because X"),继续执行。终审会同时看到双方立场。
- 真实但不承重 → 记为 known-open,继续执行。后续触及该区域的派发会携带指向该台账条目的指针。
- 真实且承重——后续任务建立在它之上,或它暴露了计划缺陷 → 触发既有的 BLOCKED 停止条件。"停放并继续(park-and-continue)"会把结构性失败推迟到成本最高的时点,还让依赖任务建立在它上面——因此结构性失败必须停下,走的是已经存在的停止条件,而不是新增检查点。
每一条仲裁都必须成为台账条目,静默丢弃被禁止。
文档重构:按生命周期重组,句子只搬不改
设计文档给出的新骨架严格按执行顺序排列,共 10 节:
- Intro——为什么用子代理、核心原则、旁白、连续执行
- When to Use——保持不变,含决策图
- The Process——流程图按新循环重绘
- Setup——worktree、台账检查/恢复、派发前计划审查、todos
- Model Selection——保持单一横切小节;每次派发都要参考它,折叠进各使用点会重复五遍
- The Task Loop——五个编号步骤:派发实现者(task-brief 脚本、五要素派发组合、模型行必填)→ 处理报告(DONE / DONE_WITH_CONCERNS / NEEDS_CONTEXT / BLOCKED)→ 评审任务(review-package 脚本、评审者派发组合、约束透镜、禁止预判、⚠️ 处理)→ 修复循环(上述机制)→ 完成任务(追加台账、更新 todo)
- Final Review——包、模型锁定、一次修复波、一次范围限定再评审、仲裁
- Finish——finishing-a-development-branch
- Common Rationalizations——理性化对照表
- Example Workflow——更新为展示基于 resume 的修复轮次与断路器不触发的路径
"Constructing Reviewer Prompts""File Handoffs""Durable Progress" 三个杂物筐小节被溶解到各自规则实际生效的步骤中。硬性约束是:每一句 eval 调优过的句子恰好落在一个新位置;实现计划中附一张 source → destination 的 move map,让评审可以逐行核验没有任何句子被丢弃或改写。这个"只搬不改"的纪律来自 SDD 技能本身被 eval 场景反复校验的事实——实现计划 的 Task 3 甚至逐行列出了旧文件每段文字的去向(Verbatim / Reworded / Superseded),并给出 grep 验证命令(如 "fix subagent" 全文只允许剩下一处命中,即终审刻意保留的 "ONE fixer" 规则)。
仓库当前落地的 SKILL.md 已完整呈现这一骨架,其中修复循环一节位于 SKILL.md 第 302–375 行,断路器仲裁位于 第 358–375 行,与流程图中的 "Fix round R of 5: R≤3 resume implementer; R≥4 fresh implementer, more capable model" 节点一一对应。
理性化对照表:借口配反驳
设计文档将 "Never" 清单中"借口形态"的条目转换为对照表行,并新增覆盖循环病理的行。设计稿(最终措辞在实现阶段定稿)包含六行:
| Excuse | Reality |
|---|---|
| "Close enough on spec compliance" | Reviewer found gaps = not done. |
| "I'll fix it myself, dispatching is overhead" | Controller fixes pollute your context and skip review. Resume the implementer. |
| "One more round will converge" | Past the cap, rounds don't converge. Adjudicate. |
| "The reviewer will just find something new anyway" | Scoped re-reviews check fixes, not taste. New findings on untouched code go to the ledger, not the loop. |
| "This finding is obviously wrong, I'll drop it" | You adjudicate only at the cap, and every adjudication is a ledger entry. Silent discards are forbidden. |
| "The fix was small, skip the re-review" | Unreviewed fixes are how regressions land. |
不属于借口的硬性规则(绝不并行派发多个实现者、绝不无 diff 文件派发评审者、模型行必填、绝不重新派发已完成台账的任务)则移到各自的使用点执行。落地后的 SKILL.md "Common Rationalizations" 小节 扩展为八行,新增了 "Reviews slow the loop down" 与 "Ledger bookkeeping is overhead" 两行,并与其余技能(test-driven-development、systematic-debugging、verification-before-completion 等)的表格格式完全对齐。
提示模板:四个契约,各管一段
修复循环的每个角色对应独立的提示模板,这是消除旧版歧义的另一半:
- implementer-prompt.md——"After Review Findings" 按 resume 语义重写:你会被带着发现唤起;修复、重跑覆盖测试、追加报告文件、返回简短契约(见上文引用)。
- task-reviewer-prompt.md——只负责首次评审;原先尾部的再评审句被移出,不再混装两个契约。
- re-review-prompt.md(新增)——范围限定的再评审契约。其输入为 brief、更新后的报告、原始发现、修复范围 diff 包;输出为逐发现判定(addressed / not addressed)、修复 diff 中的新破坏、以及范围外观察。占位符沿用既有方括号约定,并新增
[FINDINGS]与[FIX_BASE_SHA](见 模板占位符定义)。设计文档明确说明单独立模的原因:它是不同契约——把再评审塞进全量评审模板正是旧版歧义的产生原因。 - 接管派发(第 4–5 轮)——由 implementer-prompt.md 加 SKILL.md 指导现场组合(brief、报告路径、未关闭发现、接管框架),不新增模板文件。
终审循环与台账恢复语义
终审(Final Review)主体不变: merge-base 包、最强模型、ONE fixer(携带完整发现清单——按发现逐个派发修理工会各自重建上下文、重跑测试套件,真实会话中终审修复波的花费超过了所有任务之和)。新增的是:修复波之后恰好一次范围限定的再评审,随后控制器仲裁;残余承重发现会在 finishing-a-development-branch 环节浮现到人类面前。分支的末端也因此获得了有界的循环。
与修复循环紧密耦合的还有台账(progress ledger)的恢复语义——设计文档要求"任务是 DONE 当且仅当存在 Task <N>: complete 行",且"最后一条是修复轮次的任务处于循环中段:从下一轮恢复"。台账行格式是精确到可被 grep 的(实现计划的 Global Constraints 列出了全部六种行格式,如 Task <N>: fix round <R>/5 (<X> addressed, <Y> open — …; commits <a7>..<b7>)),因为 eval 场景直接按这些格式断言。工作区则由 scripts/sdd-workspace 统一解析:每个计划拥有 .superpowers/sdd/<plan-basename>/ 独立目录(台账、brief、报告、评审包),脚本自注释说明了为何放在工作树而非 .git/ 下(见 脚本头部注释)。
Evals:三个新演练场景 + 前后对照
设计文档要求新机制必须携带演练证据(drill evidence),在独立的 evals/ 仓库中新增三个场景,并加跑既有 SDD 场景的前后对照以捕捉重组带来的回归:
- Resume, don't re-dispatch——任务评审返回发现后,控制器必须 resume 同一实现者,而不是派发 fix 子代理。
- Breaker trips——预置一个"永不满足"的评审者;控制器必须在第五轮失败后停止派发,执行仲裁、记入台账并继续——而不是继续打转。
- Structural finding stops——预置一个承重发现(后续任务依赖它);控制器必须走 BLOCKED 停下,而不是停放继续。
实现计划 进一步给出了这三个场景的目录名(sdd-fix-loop-resumes-implementer、sdd-breaker-adjudicates-at-cap、sdd-breaker-structural-blocks)与两个中循环台账 fixture 助手的设计:parked 变体预置一个"仅质量问题"的未关闭发现(三重复制的 pad-and-join 表达式,测试全绿),structural 变体预置一个计划矛盾(Task 2 定义 seconds 契约、Task 3 传 milliseconds),并在线程中精确到台账行格式——因为场景的 checks.sh 就是按这些行 grep 的。
非目标与适用前提
设计文档显式划定了三条非目标,值得在移植借鉴时注意:
- 台账会话隔离——由 PR #1943 负责。本工作触及相同小节,实现计划中标注了碰撞风险(若 #1943 中途落地,需用 move map 重新放置其文字)。
- 脚本改动——task-brief 与 review-package 已经满足新循环的需要(本仓库 review-package 接受任意区间的现状印证了这一点),不需要改。
- executing-plans 与 requesting-code-review 的改动——仅保持终审指针继续可解析。
适用前提:该机制面向"控制器 + 子代理"的分层执行模型,且 harness 需支持(或可模拟)agent resume——设计文档为不支持 resume 的 harness 明确了降级路径(携带 brief、报告文件与发现的全新派发);报告文件在两种情况下都是持久记忆。断路器上限(5 轮)、仲裁路由与台账行格式均可视为该设计的可配置参数,但设计强调:轮次上限与"只在上限处仲裁"是一对——拆掉任何一边都会让循环退回非收敛状态。
小结:这套设计能迁移的方法论
把 SDD Fix-Loop 重构设计 抽象出来,它对任何"Agent 自动评审-修复"工作流可迁移的经验是五条:
- 验证与评审是不同契约——修复后应做"逐发现判定 + 只查修复 diff"的范围限定再评审,而不是再来一轮全量评审;这是循环收敛的结构性条件。
- 上下文所有权优先于新角色——修复者优先 resume 原实现者;确实要换新角色时(第 4–5 轮),同时完成"去锚定"与"能力升档"。
- 有界 + 有仲裁——任何自动修复循环都需要显式轮次上限,以及上限处一条把"修不好"分流为"仲裁/记台账/停下"的路由;停下的通道复用既有 BLOCKED 机制,不新增人工检查点。
- 一切裁决留痕——每次仲裁、每个停放发现都是台账条目,"静默丢弃禁止"是审计底线;台账同时是上下文压缩后的恢复地图(仓库中 sdd-workspace 脚本注释 记录的教训:误读旧台账会让控制器跳过整个任务序列)。
- 文档结构服从执行顺序——把散落的杂物筐小节溶解到规则生效的步骤里,而 eval 调优过的文字"只搬不改",用 move map 让重组本身可验证。
当前仓库中该设计已落地:SKILL.md 的 "The Task Loop" 第 4 步完整实现了五轮修复循环与断路器,re-review-prompt.md 提供了范围限定再评审的完整模板,示例工作流(SKILL.md 第 438 行起)演示了一次 resume 修复轮次从触发到台账收口的完整路径。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00