Skip to content

Commit 0ab24de

Browse files
committed
feat(sdd): 同步上游 v6.2.0 —— plan 作用域工作区 + 基于唤回的修复循环(#19 A 块)
对齐上游 v6.1.1 -> v6.2.0 中 subagent-driven-development 的 6 个 commit (6df8ba1 / b8a2d84 / 2dbbaed / 87e4050 / ebdd4ec / 28882fc)。 这是 #19 拆分后的 A 块。注意 v1.7.1 刚对齐过 SDD,本次是那之后的新增量。 ## 为什么必须整块一起改 我们的 SKILL.md 里写的是旧脚本签名(review-package BASE HEAD)。脚本换成 plan 作用域签名后若不同步改文档,agent 会照旧签名调用直接吃 usage 错误 —— 比不同步更糟。所以脚本 + 文档 + 模板同批落地。 ## plan 作用域工作区(结构性修复) 原先所有计划共用 .superpowers/sdd/ 一个目录,一份过期账本被误读成当前进度, 会让控制者跳过整段任务序列 —— 上游称这是观察到的最昂贵失败。现在每个计划 一个 .superpowers/sdd/<计划文件名>/,从结构上消除这种误读。 - scripts/sdd-workspace 改为接收 PLAN_FILE,自忽略 .gitignore 上移到 .superpowers/sdd/;scripts/review-package 前置 PLAN_FILE 参数 - 两个脚本在我们这边与上游 v6.1.1 字节一致(从未汉化),直接取上游版 - scripts/task-brief 只手工应用上游那两处改动,保留我们的 fork 适配 (awk 同时匹配 "Task N" 与 "任务 N",因为本仓库 writing-plans 产出中文标题) - 账本新增身份行 `# SDD ledger — plan: <路径>`,并明确「第一行点名别的计划、 或旧扁平路径下的游离账本」都不是你的进度 实测(临时 git 仓库):两个计划各得独立目录;往 A 计划写 ledger 后 B 计划 目录仍为空(关键回归);.gitignore 落在 .superpowers/sdd/ 且 git status 干净; 中文「任务 2」经新路径抽取成功;review-package 旧签名正确报 usage 错误。 ## SKILL.md 全面重写(14 章 -> 生命周期结构) 上游把平铺的 14 节重组为「任务循环」五步 + 熔断机制,Red Flags / Advantages / Integration / File Handoffs / Durable Progress 等并入使用现场。逐节重译: - 修复循环:一轮 = 一次修复分派 + 一次定向复审,每任务上限五轮 第 1-3 轮唤回原实现者(context 完整),第 4-5 轮换全新实现者 + 高一档模型 - 熔断:第 5 轮仍有未解决发现则停止分派,逐条裁定 —— 搁置(附裁定)或在 承重项上 BLOCKED。只在上限处裁定,提早裁定等于换名字的预先定性 - Minor 发现与「计划要求的」发现两条路在循环外 - 新增「常见的合理化借口」表取代原「红线」清单 新增 re-review-prompt.md(106 行全文翻译):定向复审只核实发现是否解决 + 只看修复 diff 的新破坏,范围外观察进账本不延长循环。 implementer-prompt.md「审查发现之后」改写为基于唤回的修复轮次; task-reviewer-prompt.md 更新脚本签名并删除被 re-review-prompt.md 取代的结尾两句。 ## 顺手修掉一个既有缺陷 三个 SDD 文件末尾都残留着 `</content>` —— v1.7.1 那次重写(PR #108, d7885ca) 留下的生成产物,上游没有。这些文件会整体进 agent 的 prompt,属于污染。已全部清除, 并全仓扫描确认无同类残留。 ## 验证 - 章节结构与上游 14 节一一对应;superpowers: 引用集与上游完全一致 - 26 项关键技术记号(脚本签名、账本行格式、四种状态、ADDRESSED/NOT ADDRESSED、 数值门槛)逐一确认存在,无漏译 - 两个 dot 图节点/边数与上游精确一致(6/6 与 23/28),且无幽灵节点、无孤立节点 (手工翻译 dot 标签最易在边里写错,会静默产生幽灵节点) - audit.sh 150 pass / 0 fail;verify-release.sh 82 pass / 0 fail - SDD 已从 audit 的上游漂移警告里消失(结构层级现已对齐) 注:audit PASS 由 153 降至 150,是上游有意删除 Integration 一节 (原列 executing-plans / test-driven-development / writing-plans 三个引用) 导致 Category 4b 少 3 项引用检查,非静默跳过 —— 已核对我们的引用集与上游一致。
1 parent 78457e5 commit 0ab24de

7 files changed

Lines changed: 356 additions & 221 deletions

File tree

skills/subagent-driven-development/SKILL.md

Lines changed: 209 additions & 192 deletions
Large diffs are not rendered by default.

skills/subagent-driven-development/implementer-prompt.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,11 @@ Subagent (general-purpose):
106106
107107
## 审查发现之后
108108
109-
如果审查者发现了问题、你也修复了,就重跑覆盖被改动代码的测试,
110-
并把结果追加到你的报告文件里。审查者不会替你重跑测试——
111-
你的报告就是测试证据。
109+
如果任务审查发现了问题,你会被带着那些发现重新唤起(resume)。
110+
修复它们,重跑覆盖被改动代码的测试,然后往你的报告文件里追加一份
111+
修复报告:你改了什么、你跑了哪些覆盖用的测试、命令是什么、输出是什么。
112+
审查者不会替你重跑测试——你的报告就是测试证据。然后用与第一份报告
113+
相同的那个简短状态契约回复。
112114
113115
## 报告格式
114116
@@ -136,4 +138,3 @@ Subagent (general-purpose):
136138
如果你无法完成任务,使用 BLOCKED。如果你需要未提供的信息,
137139
使用 NEEDS_CONTEXT。绝不默默产出你不确定的工作。
138140
```
139-
</content>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# 定向复审提示词模板
2+
3+
在一轮修复之后分派复审时使用此模板。复审者核实那些发现是否已被解决,
4+
并检查修复 diff 有没有引入新的破坏。这**不是**一次全新审查——完整审查
5+
早已做过了。
6+
7+
**目的:** 核实上一次审查的每一条发现都已解决,且修复本身没有破坏任何东西。
8+
9+
```
10+
Subagent (general-purpose):
11+
description: "复审任务 N 第 R 轮修复"
12+
model: [模型 —— 必填:按 SKILL.md 的"模型选择"来选;省略模型会默默
13+
继承会话里最贵的那个]
14+
prompt: |
15+
你正在复审一个任务的一轮修复。之前的审查产生了一批发现,
16+
一个实现者已经尝试修复它们。你的工作是给每条发现下结论、
17+
并检查这次修复的 diff——仅此而已。
18+
19+
## 任务
20+
21+
读取任务简报:[BRIEF_FILE]
22+
23+
## 待核实的发现
24+
25+
[FINDINGS]
26+
27+
## 修复
28+
29+
读取实现者的报告(修复报告追加在文件末尾):
30+
[REPORT_FILE]
31+
32+
**修复基线:** [FIX_BASE_SHA](上一次审查所看到的那个 head)
33+
**Head:** [HEAD_SHA]
34+
**diff 文件:** [DIFF_FILE]
35+
36+
把 diff 文件一次读完——它包含修复的提交、stat 摘要,以及带上下文的
37+
修复 diff。不要重新跑 git 命令。如果 diff 文件不存在,自己取 diff:
38+
`git diff --stat [FIX_BASE_SHA]..[HEAD_SHA]` 和
39+
`git diff [FIX_BASE_SHA]..[HEAD_SHA]`。
40+
41+
你的审查对这个 checkout 是只读的。不要以任何方式改动工作树、索引、
42+
HEAD 或分支状态。
43+
44+
## 范围
45+
46+
你的范围就是那份发现清单和这次修复的 diff。**每一条发现都要给结论。**
47+
检查修复 diff 里有没有修复本身引入的新问题。**不要**去复审这次修复
48+
没有碰过的代码:如果你注意到一个完全在修复 diff 之外的问题,
49+
把它写进"范围外的观察"——它不阻塞本任务,也不会延长修复循环。
50+
覆盖整个分支的宽范围审查会在所有任务完成后另行进行。
51+
52+
## 测试
53+
54+
实现者已经重跑了覆盖被改动代码的那些测试,并把结果追加到了报告文件里。
55+
把报告当作**未经核实的声明**来对待:确认修复报告点名了覆盖用的测试
56+
并给出了它们的输出,再拿这些声明去对照 diff 核验。不要为了确认它的报告
57+
而重跑整个测试套件。只有当读代码引出了某个现有运行结果无法回答的
58+
具体疑问时才跑测试——而且只跑一个聚焦的测试,绝不跑整包套件。
59+
60+
## 输出格式
61+
62+
你的最终消息就是报告本身:直接从第一条发现的结论开始。每一行都应该是
63+
一个结论、一条带 file:line 的发现,或者一项你实际做过的检查——
64+
不要开场白,不要过程旁白。
65+
66+
### 各条发现的结论
67+
68+
按"待核实的发现"里的顺序,逐条给出:
69+
- **[发现的一句话概括]** —— ADDRESSED(已解决)| NOT ADDRESSED(未解决),
70+
附 file:line 证据。"尝试过了"不算已解决:那个具体缺陷必须已经不存在。
71+
72+
### 修复 diff 里的新破坏
73+
74+
修复本身破坏或引入的任何东西,附严重度(Critical/Important/Minor)
75+
和 file:line。干净就写"无"。
76+
77+
### 范围外的观察
78+
79+
你注意到的、完全位于修复 diff 之外的问题。不阻塞;控制者会把这些
80+
记进账本留给最终审查。没有就写"无"。
81+
82+
### 结论
83+
84+
**本轮修复:** [所有发现均已解决,无新的 Critical/Important 破坏 |
85+
仍有发现未解决] —— 把未解决的那些列出来。
86+
```
87+
88+
**占位符:**
89+
- `[MODEL]` —— 必填:审查者模型,按 SKILL.md 的"模型选择"来选;小修复 diff
90+
的定向复审用便宜到中档的层级即可
91+
- `[BRIEF_FILE]` —— 任务简报文件(与实现者所依据的是同一个文件)
92+
- `[FINDINGS]` —— 上一次审查里的 Critical/Important 发现和规格差距,
93+
逐字抄下来,每条一个 bullet
94+
- `[REPORT_FILE]` —— 实现者的报告文件(修复报告追加在其末尾)
95+
- `[FIX_BASE_SHA]` —— 上一次审查所看到的那个 head
96+
- `[HEAD_SHA]` —— 当前提交
97+
- `[DIFF_FILE]` —— `scripts/review-package PLAN_FILE FIX_BASE HEAD` 打印出的那个路径
98+
99+
**复审者返回:** 逐条发现的结论(ADDRESSED / NOT ADDRESSED)、
100+
修复 diff 里的新破坏、范围外的观察,以及一个本轮结论。

skills/subagent-driven-development/scripts/review-package

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@
44
# call. Using the recorded per-task BASE (not HEAD~1) keeps multi-commit
55
# tasks intact.
66
#
7-
# Usage: review-package BASE HEAD [OUTFILE]
8-
# Default OUTFILE: <repo-root>/.superpowers/sdd/review-<base7>..<head7>.diff
7+
# Usage: review-package PLAN_FILE BASE HEAD [OUTFILE]
8+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/review-<base7>..<head7>.diff
99
# (named per range, so a re-review after fixes gets a distinct fresh file).
1010
set -euo pipefail
1111

12-
if [ $# -lt 2 ] || [ $# -gt 3 ]; then
13-
echo "usage: review-package BASE HEAD [OUTFILE]" >&2
12+
if [ $# -lt 3 ] || [ $# -gt 4 ]; then
13+
echo "usage: review-package PLAN_FILE BASE HEAD [OUTFILE]" >&2
1414
exit 2
1515
fi
1616

17-
base=$1
18-
head=$2
17+
plan=$1
18+
base=$2
19+
head=$3
20+
[ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
1921

2022
git rev-parse --verify --quiet "$base" >/dev/null || { echo "bad BASE: $base" >&2; exit 2; }
2123
git rev-parse --verify --quiet "$head" >/dev/null || { echo "bad HEAD: $head" >&2; exit 2; }
2224

23-
if [ $# -eq 3 ]; then
24-
out=$3
25+
if [ $# -eq 4 ]; then
26+
out=$4
2527
else
26-
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
28+
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace" "$plan")
2729
out="$dir/review-$(git rev-parse --short "$base")..$(git rev-parse --short "$head").diff"
2830
fi
2931

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
11
#!/usr/bin/env bash
2-
# Resolve and ensure the working-tree directory SDD uses for its short-lived
3-
# artifacts: task briefs, implementer reports, review packages, and the
4-
# progress ledger. Print the directory's absolute path.
2+
# Resolve and ensure the working-tree directory SDD uses for one plan's
3+
# short-lived artifacts: task briefs, implementer reports, review packages,
4+
# and the progress ledger. Print the plan directory's absolute path.
5+
#
6+
# One directory per plan (.superpowers/sdd/<plan-basename>/) so a follow-up
7+
# plan in the same working tree can never read or overwrite another plan's
8+
# artifacts. A stale ledger misread as current progress makes controllers
9+
# skip whole task sequences — plan-scoping removes that failure structurally.
510
#
611
# The workspace lives in the working tree (not under .git/) because Claude Code
712
# treats .git/ as a protected path and denies agent writes there — which blocks
813
# an implementer subagent from writing its report file. A self-ignoring
9-
# .gitignore keeps the workspace out of `git status` and out of accidental
10-
# commits without modifying any tracked file.
14+
# .gitignore at .superpowers/sdd/ keeps every plan's workspace out of
15+
# `git status` and out of accidental commits without modifying any tracked file.
1116
#
1217
# Single source of truth for the workspace location, so task-brief and
1318
# review-package cannot drift to different directories.
1419
#
15-
# Usage: sdd-workspace
20+
# Usage: sdd-workspace PLAN_FILE
1621
set -euo pipefail
1722

23+
if [ $# -ne 1 ]; then
24+
echo "usage: sdd-workspace PLAN_FILE" >&2
25+
exit 2
26+
fi
27+
28+
plan=$1
29+
[ -f "$plan" ] || { echo "no such plan file: $plan" >&2; exit 2; }
30+
31+
slug=$(basename "$plan" .md)
32+
[ -n "$slug" ] && [ "$slug" != "." ] && [ "$slug" != ".." ] \
33+
|| { echo "cannot derive a workspace name from: $plan" >&2; exit 2; }
34+
1835
root=$(git rev-parse --show-toplevel)
19-
dir="$root/.superpowers/sdd"
36+
base="$root/.superpowers/sdd"
37+
dir="$base/$slug"
2038
mkdir -p "$dir"
21-
printf '*\n' > "$dir/.gitignore"
39+
printf '*\n' > "$base/.gitignore"
2240
cd "$dir" && pwd

skills/subagent-driven-development/scripts/task-brief

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
# through the controller's context.
55
#
66
# Usage: task-brief PLAN_FILE TASK_NUMBER [OUTFILE]
7-
# Default OUTFILE: <repo-root>/.superpowers/sdd/task-<N>-brief.md
8-
# (per worktree; concurrent runs in the same working tree share it).
7+
# Default OUTFILE: <repo-root>/.superpowers/sdd/<plan-basename>/task-<N>-brief.md
8+
# (per plan and per worktree; concurrent runs of the SAME plan in the same
9+
# working tree share it).
910
#
1011
# 中文 fork 适配:上游只识别英文任务标题 "## Task N",而 superpowers-zh
1112
# 的 writing-plans 产出的是 "### 任务 N:..."。下方 awk 同时匹配
@@ -24,7 +25,7 @@ n=$2
2425
if [ $# -eq 3 ]; then
2526
out=$3
2627
else
27-
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace")
28+
dir=$("$(cd "$(dirname "$0")" && pwd)/sdd-workspace" "$plan")
2829
out="$dir/task-${n}-brief.md"
2930
fi
3031

skills/subagent-driven-development/task-reviewer-prompt.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,8 @@ Subagent (general-purpose):
158158
- `[BASE_SHA]` —— 本任务之前的提交
159159
- `[HEAD_SHA]` —— 当前提交
160160
- `[DIFF_FILE]` —— 必填:控制者写入审查包的那个路径
161-
`scripts/review-package BASE HEAD` 会打印它写入的唯一路径;
161+
`scripts/review-package PLAN_FILE BASE HEAD` 会打印它写入的唯一路径;
162162
审查包永远不会进入控制者的上下文)
163163

164164
**审查者返回:** 规格合规性结论(✅/❌/⚠️)、优点、问题
165165
(关键/重要/次要)、任务质量结论
166-
167-
一次修复分派可以同时处理规格差距和质量发现;修复后的重新审查
168-
覆盖两个结论。
169-
</content>

0 commit comments

Comments
 (0)