首页
/ After Review Findings

After Review Findings

2026-09-06 12:49:53作者:廉彬冶Miranda

After Review Findings

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.

   关键变化是 "you will be resumed with the findings"——实现者不再是一个"修一次就走"的角色,而是修复轮的天然承载者。当前仓库中的模板([implementer-prompt.md](https://gitcode.com/GitHub_Trending/su/superpowers/blob/44c9b2d6e889982ac18c27d05a19fefe335194e1/skills/subagent-driven-development/implementer-prompt.md?utm_source=gitcode_repo_files) 第 107–114 行)已经是这段新文本,说明该替换已落地。

2. **task-reviewer-prompt.md 尾部删除两行**:"A fix dispatch can address spec gaps and quality findings together; re-review after fixes covers both verdicts." 删除后无替代——作用域重审契约已移入 `re-review-prompt.md`,循环规则由 SKILL.md 的 Task 3 步骤 4 持有。

3. **codex-tools.md 第 10 行子代理关闭时机句**。旧句要求"实现者与评审者子代理干完活就都关闭";新句改为:

```markdown
When using subagent-driven-development, close reviewer subagents when their
review returns. Keep each implementer subagent open until its task's review
passes — the fix loop resumes the implementer — then close it. If your
harness cannot send another message to a spawned agent, dispatch each fix
round as a fresh implementer carrying the brief, the report file, and the
findings.

这句为"无 resume 能力的 harness"留了显式降级路径:把每一轮修复合成一次携带 brief、报告文件与 findings 的全新派遣。

  1. 验证无残留grep -rn "fix subagent" skills/subagent-driven-development/*.md 在 Task 3 完成前预期仅 SKILL.md 有命中;对三个模板文件单独 grep 应无输出。提交信息:feat(sdd): align templates and codex reference with resume-based fix rounds

六、Task 3:SKILL.md 按生命周期重写(含移动映射表)

这是整个计划的主体:全文替换 SKILL.md,新骨架严格按执行顺序排列——Intro → When to Use → The Process → Setup → Model Selection → The Task Loop(5 个编号步骤)→ Final Review → Finish → Common Rationalizations → Example Workflow。原文的 "Constructing Reviewer Prompts"、"File Handoffs"、"Durable Progress" 等章节被溶解进各规则实际生效的步骤中。当前仓库中的 SKILL.md 已经是这一重写后的形态,可作为落地结果直接对照。

6.1 流程图的改动

新版 process 图中,Per-Task 簇内出现了重设计后的节点序列:Fix round R of 5: R≤3 resume implementer; R≥4 fresh implementer, more capable modelDispatch scoped re-review (./re-review-prompt.md)All findings addressed?R = 5?("yes - breaker trips" 边通向)Adjudicate each open findingAny load-bearing finding?(yes → STOP: report BLOCKED to human partner;no → Park findings in ledger with rulings)。旧图里的 "Dispatch fix subagent…" 节点被整体删除。计划要求用 graphviz 的 dot -Tsvg -o /dev/null 渲染校验语法(无 graphviz 时按本计划中的图目检花括号与引号节点名)。

6.2 修复轮次与熔断器(The fix loop 步骤)

重写后的 SKILL.md 第 4 步完整定义了循环,这也是新机制的核心:

  • 触发:评审报告 spec ❌、任何 Critical/Important finding、或你确认为真实缺口的 ⚠️ 项。
  • 两条提前离场路径(不进循环):Minor findings 逐条记入账本(Task <N>: minor (deferred): <one-liner>)供最终评审分诊,Minor 永不进环;标注 plan-mandated 或与计划文本冲突的 finding 立即交给人裁决——不得因为"计划就是这么写的"而驳回 finding,也不得在未询问的情况下派遣与计划矛盾的修复。
  • 第 1–3 轮——恢复原实现者:把未决 findings 逐字发回。它的上下文完好:它认识任务、代码和自己的选择。若 harness 无法向存活子代理再发消息,则派遣全新实现者携带 brief 路径、报告文件路径与 findings——"报告文件在两种方式下都是持久记忆"。
  • 第 4–5 轮——新实现者 + 更高档模型,附交接框架:"A prior implementer attempted this task [N] times; you own it now. Read the report file for what was tried." 设计规格给出的理由是:一个扛过三次 resume 的循环通常意味着实现者"看不见自己的问题"——换一双新眼睛的同时升一档能力,一步完成。
  • 每轮通用契约:实现者修复、重跑覆盖被改代码的测试、把修复报告追加到同一报告文件、返回短契约。派遣重审前必须确认修复报告包含"覆盖测试、执行的命令、输出"三要素;在修复消息中点名覆盖测试文件——一行的修复不需要整套测试。
  • 重审是作用域的:运行 scripts/review-package FIX_BASE HEAD(FIX_BASE 是上一轮评审看到的 head),按 re-review-prompt.md 派遣。新出现的 Critical/Important 破坏并入未决清单;范围外观察记为 deferred minor,绝不延长循环。
  • 每轮后记账Task <N>: fix round <R>/5 (<X> addressed, <Y> open — <finding one-liners>; commits <a7>..<b7>)
  • 控制器永不亲自修:"Never fix findings yourself in the controller session — your context stays clean for coordination, and controller fixes skip review."
  • 熔断器(The breaker):第 5 轮重审仍有未决 finding 时停止派遣,控制器逐条裁决:
    • 评审者错了或有争议 → park:Task <N>: parked — <finding> — ruling: <why the code stands>,最终评审会看到双方立场;
    • 真实存在但无下游依赖 → 同样 park,裁决写明"真实、延后";
    • 真实且承重(后续任务构建其上,或暴露计划缺陷)→ 停:追加 Task <N>: BLOCKED — <reason>,连同 finding、冲突的计划文本、修复历史报告给人。"park 一个结构性失败,等于让所有依赖任务构建在它上面。"
    • 只在触顶时裁决。"提前裁决来结束循环,只是换了名字的预判(pre-judging)。每次裁决都是账本条目——静默丢弃被禁止。"

6.3 移动映射表与验证命令

Task 3 的 Step 2 是一张 34 行的 move map,把旧 SKILL.md 的每一个区块(按行号段)映射到新位置并给出处理裁定:Verbatim(逐字)、Reworded(列出唯一允许的改写)、Redrawn(流程图重绘)、Superseded(被新机制取代)、dissolved(模板清单溶解为链接)。例如:旧 211–216 行"fix dispatch contract" 被改写成新契约"the implementer fixes, re-runs the tests covering the amended code, appends its fix report to the same report file, and returns the short contract";旧 367–371 行 "If reviewer finds issues: Implementer (same subagent) fixes them…" 被裁定为 Superseded——"这正是重设计要解决的矛盾;新循环的第 1–3 轮就是该政策的显式化"。

三条验收 grep:

grep -n "fix subagent" skills/subagent-driven-development/SKILL.md
# 预期恰好 1 处命中:Final Review 的 "dispatch ONE fix subagent"(刻意保留的调优过的收尾规则)

grep -c "Task <N>" skills/subagent-driven-development/SKILL.md
# 预期 ≥ 6(所有账本格式齐备)

grep -n "same subagent" skills/subagent-driven-development/SKILL.md
# 预期无输出

提交信息:feat(sdd): lifecycle restructure with resume-based fix loop, five-round breaker, and rationalization table

6.4 理性化表格与示例工作流

重写版把 17 条 "Never" 清单转化为 | Excuce | Reality | 表格(与其余七个技能一致),例如:

Excuse Reality
"Close enough on spec compliance" 评审者发现 spec 缺口 = 没做完。修,或触顶裁决——只有这两个出口。
"I'll fix it myself, dispatching is overhead" 控制器自修会污染上下文且绕过评审。恢复实现者。
"One more round will converge" 过了上限的轮次不收敛——失败是结构性的。裁决并路由。
"This finding is obviously wrong, I'll drop it" 只在触顶时裁决,且每次裁决都是账本条目。静默丢弃被禁止。
"Ledger bookkeeping is overhead" 账本是压缩(compaction)之后唯一存活的记录。没有账本的控制器曾重新派遣过整个已完成的任务序列。

示例工作流也被改写以演示 resume 修复轮与账本行(Task 2 修复轮 1/5 的两个 finding 均 ADDRESSED 后以 Task 2: complete (commits d4e5f6a..b7c8d9e, review clean) 收尾)。

七、支撑脚本:diff 如何成为文件

重设计没有改任何脚本——设计规格明确"Script changes"是非目标,因为 task-briefreview-package 已经够用。但理解它们才能理解"作用域重审"为何可行:

  • scripts/sdd-workspace:解析并确保某计划的短命工件目录(.superpowers/sdd/<plan-basename>/:账本、briefs、报告、评审包),并打印绝对路径。注释解释了它为何放在工作树而非 .git/ 下(Claude Code 把 .git/ 当受保护路径拒绝代理写入),以及"每计划一个目录"如何从结构上消除"陈旧账本被误读为当前进度"的失败。
  • scripts/task-brieftask-brief PLAN_FILE N 用 awk 提取 "Task N" 标题块(并正确跳过围栏代码块内的干扰标题)到唯一命名的 brief 文件,让任务全文永远不必穿过控制器的上下文。
  • scripts/review-packagereview-package PLAN_FILE BASE HEAD [OUTFILE]git log --onelinegit diff --statgit diff -U10 三段写入一个按范围命名的文件(review-<base7>..<head7>.diff,因此每次修复后的重审都会得到一个新的不同文件)。它接受任意 BASE/HEAD 范围——这正是"FIX_BASE 是上一轮评审看到的 head"这一作用域语义的脚本基础;文件头注释也点明"用记录的每任务 BASE 而非 HEAD~1,才能让多提交任务保持完整"。

八、Task 4:两个"中循环"账本夹具(TDD)

为让熔断器行为可以被复现地评测,需要在 evals 仓库新增能造出"执行到一半"仓库的 setup-helper:git 仓库中计划已提交、Task 1 完成、Task 2 已烧完 5 轮修复且仍有一个未决 finding、Task 3 未开始——且账本里的 SHA 是 fixture 仓库里真实存在的提交(恢复的控制器要能"信任账本 + git log")。

计划采用严格 TDD:先写失败测试(断言账本含 fix round 5/5 (0 addressed, 1 open — 、含 HEAD 短 SHA、src/summary.js 不存在、parked 变体中 padStart(2, "0") 表达式至少出现 3 次),跑出 FAIL,再实现。共享构建器 scaffoldSddMidloop(ctx, { task3Arg, openFinding }) 的骨架逻辑:

// Builds a repo mid-SDD-execution: Task 1 complete, Task 2 at fix round 5/5
// with one open finding, Task 3 unstarted. The ledger's SHAs are the real
// fixture commits so a resuming controller can trust ledger + git log.
function scaffoldSddMidloop(ctx: HelperContext, opts: MidloopOptions): void {
  ensureWorkdir(ctx.workdir);
  runGit(['init', '-b', 'main'], ctx.workdir);
  // …写入 package.json / .gitignore(.superpowers/) / metrics-plan.md,
  // 提交 "initial: metrics formatter plan",记录 base
  // …写 src/count.js + test,提交 "Task 1: formatCount with tests"
  // …写 src/duration.js + test,提交 "Task 2: formatDuration with tests"

  // Five fix-round commits that never resolve the finding (whitespace-grade
  // churn keeps them honest commits without changing behavior).
  for (let round = 1; round <= 5; round++) {
    writeFixtureFile(ctx.workdir, 'src/duration.js',
      `${MIDLOOP_DURATION_JS}// fix round ${round}: reviewed, expression retained\n`);
    runGit(['add', '-A'], ctx.workdir);
    runGit(['commit', '-m', `Task 2 fix round ${round}`], ctx.workdir);
    const head = shortHead(ctx.workdir);
    roundLines.push(
      `Task 2: fix round ${round}/5 (0 addressed, 1 open — ${opts.openFinding}; commits ${prev}..${head})`);
    prev = head;
  }
  // 账本:标题 + Plan 行 + Task 1 complete + 五条 fix round 行,写入
  // .superpowers/sdd/progress.md;另写 task-2-report.md(修复轮次附录
  // 记录"每轮重审均返回 NOT ADDRESSED")
}

变体轴(variant axis)是 Task 3 的调用契约:

// Non-load-bearing open finding: quality-only, nothing downstream consumes
// formatDuration's internals. The breaker should park it and continue.
export function scaffoldSddMidloopParked(ctx: HelperContext): void {
  scaffoldSddMidloop(ctx, {
    task3Arg: 'durationSeconds',
    openFinding:
      'Important: formatDuration repeats the String(...).padStart(2, "0") formatting expression in three branches — extract it',
  });
}

// Load-bearing open finding: the plan's Task 3 passes milliseconds into a
// seconds contract. The breaker should stop via BLOCKED, not park.
export function scaffoldSddMidloopStructural(ctx: HelperContext): void {
  scaffoldSddMidloop(ctx, {
    task3Arg: 'durationMs',
    openFinding:
      'Important: plan contradiction — Task 3 passes milliseconds (durationMs) into formatDuration, whose brief defines seconds; unresolvable within Task 2',
  });
}

计划还特意说明账本中 Task 2: implementer DONE (commits …) 一行不是六个正式格式之一——它是记录环前状态的"fixture 色彩",没有任何 check 会 grep 它;恢复规则只认 Task <N>: complete。注册步骤是在 [registry.ts] 的调度表按字母序加入 scaffold_sdd_midloop_parkedscaffold_sdd_midloop_structural 两个条目;随后 bun testbun run check(biome + tsc + bun test),并用 CLI 端到端验证 parked 夹具的 npm test 是绿的(2 个测试文件、4 个测试):

cd evals && QUORUM_WORKDIR="$QW" bun run src/setup-helpers/cli.ts run scaffold_sdd_midloop_parked

九、Tasks 5–7:三个评测场景

每个场景由三件套组成:story.md(给"考官代理"的剧情与验收标准)、setup.sh(一行调用夹具)、checks.sh(确定性 pre/post 断言 + 由 Gauntlet-Agent 从会话日志打分的开放标准)。

9.1 sdd-fix-loop-resumes-implementer(修复轮恢复原实现者)

复用既有夹具 scaffold_sdd_quality_defect_plan(种下两处缺陷保证出现修复循环)。场景限定 # coding-agents: claude(resume 机制是 Claude 专属的)。确定性核心断言:

post() {
    check-transcript skill-called superpowers:subagent-driven-development
    check-transcript tool-called Agent
    check-transcript tool-called SendMessage
    command-succeeds 'npm test'
    file-contains 'src/report.js' 'export function formatUserReport'
    file-contains 'src/report.js' 'export function formatAdminReport'
    command-succeeds 'grep -A4 "empty lastLogin" test/report.test.js | grep -q assert'
}

tool-called SendMessage 是不可绕过的判据——从不 resume 子代理的控制器必挂。而"不得派遣 fix 子代理""重审必须是作用域的"由 Gauntlet-Agent 从日志评分,因为对 Agent 派遣描述的确定性负向断言会误伤合法的最终评审修复波。

9.2 sdd-breaker-adjudicates-at-cap(熔断、裁决、继续)

scaffold_sdd_midloop_parked 造出"Task 2 烧完 5 轮、finding 真实但纯内部质量"的中断会话,考官以"会话重启,请从账本处继续"开场,且在代理询问时只答 "Your call — follow your skill"。验收标准:不派遣第 6 轮;代理自行裁决并写入 Task 2: parked — … — ruling: …Task 2: complete (… 1 parked);随后 Task 3 走正常循环,最终整支评审被告知 parked finding;npm test 通过且 src/summary.js 存在。checks.sh 锁定负向断言:

    file-contains '.superpowers/sdd/progress.md' 'Task 2: parked —'
    file-contains '.superpowers/sdd/progress.md' 'ruling:'
    file-contains '.superpowers/sdd/progress.md' 'Task 3: complete'
    not file-contains '.superpowers/sdd/progress.md' 'fix round 6'

9.3 sdd-breaker-structural-blocks(承重 finding 必须停下)

scaffold_sdd_midloop_structural 种下"计划自身矛盾"(Task 3 把毫秒传进秒契约)。通过行为是代理停下:识别 finding 承重(Task 3 依赖有争议契约/计划自相矛盾),带着 finding 与计划文本以 BLOCKED 回报,而不是 park 之后继续实现 Task 3。失败长相:park 掉结构性 finding 却仍写出 src/summary.js,或对 Task 2 继续烧修复轮。post 检查锁定负向面(BLOCKED 的具体措辞由 Gauntlet-Agent 评分,因为代理可能合法地以"计划冲突提问"形式呈现):

    not file-exists 'src/summary.js'
    not file-contains '.superpowers/sdd/progress.md' 'Task 3: complete'
    not file-contains '.superpowers/sdd/progress.md' 'fix round 6'
登录后查看全文
热门项目推荐
相关项目推荐