Imported from Room-C/ai-dev-workflow (
skills/diff-review/SKILL.md). Install upstream withnpx skills add Room-C/ai-dev-workflow --skill diff-review. Copyright stays with the author.
Diff Review — 分支对比审查 + 自动化闭环修复
对比当前分支与目标分支,以 Host Review/Inline Review → Validation → Auto-fix → 重审 的闭环运行,直到无 P1/P2 或达到 5 轮上限。
三个 Agent 协作:
diff-reviewer(SubAgent):优先调用宿主 review 引擎产出结构化 findings JSON;不可用时降级 Agent 审查或 native-inlinevalidation-reviewer(SubAgent):对每条 finding 判定to_fix / dismissed / deferred,附 evidence 和 confidencefix-runner(SubAgent):串行执行每条to_fix的修复 + 验证 + 回滚/提交,隔离文件内容与测试日志不污染主上下文
本 Skill 负责编排:参数解析、diff 收集、baseline 准备、循环控制、用户交互(needs_confirm 审批)、报告生成、知识沉淀、清理。
Portable Runtime
本 Skill 必须能通过 npx skills add --copy 单独安装后运行。运行时资源优先从当前 Skill 目录读取:
scripts/preprocess-diff.shscripts/baseline-verify.shreferences/agents/diff-reviewer.mdreferences/agents/validation-reviewer.mdreferences/agents/fix-runner.mdreferences/shared/known-issues.mdreferences/shared/compound-schema.md
宿主支持子代理时,按 bundled agent prompt 委派;没有子代理能力时,主上下文按 reference inline 执行同一 JSON 契约。项目规则读取顺序为 AGENTS.md -> CLAUDE.md -> README/Makefile/package 配置。
参数
| 参数 | 默认 | 说明 |
|---|---|---|
| 目标分支 | main |
对比基准 |
--depth |
standard |
quick / standard / deep,控制审查深度 |
--focus |
全部 | security / performance / logic / style / agent-native,可组合 |
--since |
无 | 增量审查起点 commit |
--path |
全部 | 路径过滤,如 backend/ |
--compound |
on |
知识沉淀。--no-compound 关闭 |
--commit |
on |
每条修复独立 commit。--no-commit 仅改文件 |
--keep-intermediates |
off |
默认清理中间轮次产物,仅保留最终报告 |
工作流程
Step 1: 收集 diff + 上下文
- 预处理脚本(优先):定位当前 Skill 目录下的
scripts/preprocess-diff.sh,传入target_branch/--since/--path,获取 diff 范围、改动文件、模块列表 - 错误处理:脚本若因
target_branch/--since非法而 exit non-zero,直接向用户报告"比较基线无效",不要当作"无改动" - 降级手动:仅当脚本缺失或不可执行时,才回退到
git diff <base>...HEAD --stat和--name-only - 无改动 → 结束:"当前分支与目标分支无差异"
- 模块覆盖检测:Monorepo 仅改部分模块时,在报告开头注明
- 噪音过滤:预处理脚本已内置(
*.lock、*.generated.*、*/migrations/*、*.min.*、*.pbxproj) - 上下文理解:读项目规则文件、
docs/solutions/相关条目、references/shared/known-issues.md、commit 历史
Step 2: 准备输出目录
REVIEW_DIR="docs/develop/reviews/$(date +%Y-%m-%d)"
ROUNDS_DIR="$REVIEW_DIR/.rounds"
if ! mkdir -p "$ROUNDS_DIR"; then
echo "ERROR: cannot create $ROUNDS_DIR (cwd=$PWD, exit=$?). Aborting review." >&2
exit 1
fi
[ -w "$REVIEW_DIR" ] || { echo "ERROR: $REVIEW_DIR is not writable."; exit 1; }
报告文件名:<current-branch>-vs-<target-branch>.md(/ 替换为 -)。
中间产物(round/baseline JSON、每轮 review/validation 文件)全部落在 $ROUNDS_DIR。
Step 3: Baseline 准备(惰性)
不立即执行。记录命令即可,待 Step 4.3 首次验证失败时才执行:
- 探测项目验证命令(项目规则文件 Verification/test/quality 章节 /
package.jsonscripts /Makefiletargets / CI 配置) - 写入
$ROUNDS_DIR/baseline-cmds.json:{lint, typecheck, test}可用命令数组 - 若项目无任何可用验证命令 → 标记
baseline.missing = true,Step 4.3 任何新增失败一律归为"本轮引入"
Step 4: 循环审查(ROUND=1..5)
ROUND=1 起,每轮执行 4.1 → 4.5。
4.1 Review(SubAgent: diff-reviewer)
读取 references/agents/diff-reviewer.md。若宿主支持子代理,按该 reference 调用 diff-reviewer;否则主上下文按 reference inline 执行,传入:
| 参数 | 说明 |
|---|---|
diff_range |
<base>...HEAD(base 为 --since 或目标分支) |
output_dir |
$ROUNDS_DIR |
round |
当前轮次 |
path_filter / focus / depth |
按参数透传 |
dismissed_context |
之前所有轮次被 Validation 判为 dismissed 的清单 + 理由,要求 review 引擎不重复标注(除非发现新证据) |
fixes_context |
之前所有轮次已修复的 commit hash / diff 摘要,让 review 引擎对最新代码状态复审 |
Agent 输出契约(严格 JSON)写入 $ROUNDS_DIR/review-round-$ROUND.json:
{
"engine": "codex|codex-bash|agent-fallback|native-inline|failed",
"raw_output_path": "$ROUNDS_DIR/review-round-$ROUND.md",
"round": 1,
"issues": [
{
"id": "ISSUE-001",
"severity": "P1|P2|P3",
"location": "path:line",
"description": "...",
"suggestion": "..."
}
]
}
四层弹性(diff-reviewer 内部自动降级,仓库可读就不会失败):
- Host-native review Skill → 2. Codex CLI/Bash 直调 → 3. 通用代码审查子代理 → 4. 原生内联审查(仅用 Read/Grep/git)
每层失败自动尝试下一层。engine 字段标明最终走到了哪层。仅当 engine = "failed" 时上层 Skill 终止循环(此时通常意味着 git 仓库不可读)。
4.2 Validation(SubAgent: validation-reviewer / inline fallback)
读取 references/agents/validation-reviewer.md。若宿主支持子代理,按该 reference 调用 validation-reviewer;否则主上下文按 reference inline 执行,传入:
| 参数 | 说明 |
|---|---|
findings_json_path |
$ROUNDS_DIR/review-round-$ROUND.json(4.1 产物) |
diff_range |
与 4.1 相同 |
output_dir |
$ROUNDS_DIR |
round |
当前轮次 |
fixes_context |
之前所有轮次已修复的 commit hash / diff 摘要,避免 Validation 对旧问题重复裁决 |
输出契约写入 $ROUNDS_DIR/validation-round-$ROUND.json:
{
"round": 1,
"items": [
{
"id": "ISSUE-001",
"class": "to_fix|dismissed|deferred",
"confidence": 0.85,
"evidence": "引用代码并说明判断依据(2-3 句)",
"reason": "为什么此分类",
"autofix_strategy": "direct|needs_confirm|manual_only"
}
]
}
硬约束(由本 Skill 再校验一次,防止 agent 遗漏):
confidence < 0.60→ 强制降为dismissed,reason追加[confidence-gate]- 缺
evidence或evidence少于 20 字符 → 强制降为deferred,reason追加[missing-evidence] autofix_strategy = manual_only→ 仅允许deferred或dismissed(不能to_fix)
4.3 Auto-fix(SubAgent: fix-runner / inline fallback,串行)
遍历 Validation 结果中所有 class = to_fix 的项(含 P1/P2/P3)。主 Skill 不亲自改代码、不读测试日志——全部委托 fix-runner,自己仅做编排。
1. 预处理 needs_confirm(本步留在主 Skill,因为涉及用户交互):
对每条 autofix_strategy = needs_confirm 的项,用 AskUserQuestion 展示 {id, severity, location, description, suggestion}。
- 用户选 "approve" → 转交 fix-runner(按 direct 执行)
- 用户选 "reject" → 本条降为
deferred,reason=user-rejected,不再调 fix-runner - 为节省轮次,可将同一轮的多条
needs_confirm合并为一次AskUserQuestion(multiSelect)
2. 串行调用 fix-runner:
读取 references/agents/fix-runner.md。按 severity P1 → P2 → P3 顺序,逐条调用 fix-runner;没有子代理能力时,主上下文按该 reference inline 执行,但仍必须隔离单条 finding 的文件边界。传入:
| 参数 | 说明 |
|---|---|
to_fix_item |
单条 validation item + 对应 finding 的 description/suggestion |
verification_cmds_json |
$ROUNDS_DIR/baseline-cmds.json |
baseline_json |
$ROUNDS_DIR/baseline.json(可能尚不存在,由 fix-runner 首次失败时自行调用 baseline-verify.sh 建立) |
baseline_verify_script |
当前 Skill 目录下 scripts/baseline-verify.sh 的绝对路径 |
output_dir |
$ROUNDS_DIR |
round |
当前轮次 |
commit_enabled |
--commit 参数的值(true/false) |
base_ref |
目标分支或 --since commit |
硬约束:
- 串行不并行:git 工作树 + baseline 建立都是共享资源,并行会竞态
- 主 Skill 只看 JSON 返回:每次 fix-runner 返回
{status, commit_hash, patch_summary, verification, rollback_reason, pre_existing_failures_observed}结构化摘要;不读 patch 内容、不读验证日志 - 文件边界隔离:fix-runner 只允许提交/回滚本条 finding 显式触达的文件,禁止用 repo 级
git diff --name-only推断边界 - 异常处理:fix-runner 抛错或 JSON 不合法 → 视为本条
status=rolled_back,rollback_reason=agent-error,继续下一条
3. 汇总本轮修复:
收集所有 fix-runner 返回的 JSON,合成 $ROUNDS_DIR/fixes-round-$ROUND.json:
{
"round": 1,
"applied": [ { "id": "...", "commit_hash": "...", "patch_summary": "..." } ],
"rolled_back": [ { "id": "...", "rollback_reason": "..." } ],
"skipped": [ { "id": "...", "reason": "..." } ],
"pre_existing_failures_observed": ["..."]
}
rolled_back 项在 Validation 状态上也要降级:本轮 validation JSON 中对应 item class 改为 deferred,reason 追加 [rolled-back:<rollback_reason>],便于 Step 4.4 轮次报告和 Step 5 最终报告追溯。
4. 预存在问题合并:
聚合所有 fix-runner 的 pre_existing_failures_observed 去重后写入 $ROUNDS_DIR/pre-existing.json,Step 5 最终报告直接引用。
4.4 轮次报告
写 $ROUNDS_DIR/round-$ROUND.md:
- 本轮 review findings 原始清单
- Validation 分类结果(to_fix / dismissed / deferred)
- 本轮实际修复的条目(含 commit hash)
- 回滚的条目(含失败原因)
- 本轮 dismissed 清单 + 理由(下一轮 review 必须看到)
4.5 终止判定
顺序检查:
- 成功终止:本轮 review findings 中无 P1 且无 P2 → 终止(P3 无论是否修复都结束)
- 达到上限:
ROUND >= 5→ 终止,剩余 P1/P2 列入最终报告"未解决"段 - 引擎完全失败:
diff-reviewer返回engine = "failed"(四层降级全部不可用,通常是 git 仓库损坏)→ 终止,记录错误 - 本轮零修复且新一轮 findings 与上一轮指纹完全重合(
location + description hash相同)→ 终止,避免死锁
否则 ROUND++,回到 4.1。
Step 5: 生成最终报告
写 $REVIEW_DIR/<current-branch>-vs-<target-branch>.md:
- 元数据:分支、时间、改动范围、技术栈、审查模式、总轮次、结束原因、各轮引擎(host-review / agent-fallback / native-inline)
- 总评:1-3 句概括
- 轮次概览表:每轮
P1/P2/P3 总数 · to_fix · dismissed · deferred · 已修复 · 回滚 - 最终状态:
- 已修复(含 commit hash)
- Dismissed(附 Validation 理由和 confidence)
- 未解决 P1/P2(附原因:deferred / 达上限 / 死锁终止)
- P3 总结(修了哪些、留了哪些)
- 预存在问题:从
baseline.json读取、在本次修复过程中被观察到但非本 PR 引入的问题(仅告知不修) - 亮点(可选):做得好的地方,没有就省略
- 维度评分表:逻辑/实践/简洁/安全/性能/复用/一致/Agent 友好度,各 /5
Step 6: 任务清单(未解决 P1/P2 存在时追加)
报告末尾追加:
## 任务清单
- [ ] P1 **<简明标题>** — `<文件:行号>` — <做什么>(原因:<deferred/round-limit/deadlock>)
- [ ] P2 **<简明标题>** — `<文件:行号>` — <做什么>(原因:...)
若 ≥ 5 条,额外写入 <report-name>-tasks.md。
Step 7: 知识沉淀(--compound on)
--depth quick 跳过。
扫描所有轮次的 review findings + Validation 结果,识别模式级问题(同类错误 ≥ 2 次,或违反潜规则,或新反模式)。
对每个模式:
- 按
references/shared/compound-schema.md的双轨 Schema 和 category 映射生成 solution doc - 写入
docs/solutions/<category>/<date>-<slug>.md - 在最终报告末尾追加"知识沉淀"摘要;如确实需要同步宿主规则,只在报告里给出建议补丁,不自动改
AGENTS.md/CLAUDE.md
沉淀原则详见共享 Schema 文档。没有模式就不沉淀——宁缺毋滥。
Step 8: 清理中间产物
默认行为(--keep-intermediates off):
rm -rf "$ROUNDS_DIR"
仅在 --keep-intermediates on 时保留 .rounds/ 目录。
永远保留(不受清理影响):
- 最终报告
<current-branch>-vs-<target-branch>.md - 任务清单文件(如有)
docs/solutions/下的 solution docs- 已修复的 commits
核心约束
- JSON 契约强制 —
diff-reviewer和validation-reviewer必须产出合法 JSON,格式错误一律视为引擎失败 - Dismissed 必须回喂 — 下一轮 review 调用必须携带
dismissed_context,review 引擎不得重复标注已 dismissed 项(除非给出新证据) - Confidence < 0.60 强制 dismissed — 对齐本 Skill 的 Confidence Gating 规范
- Baseline 惰性 — 不主动跑;仅在首次验证失败时加载,避免无失败情况下的性能损耗
- 本轮引入才回滚 — 预存在失败保留修复、记入报告,不污染 PR 作者
- 循环上限 5 — 达到即终止,不再审查
- 清理默认 on —
.rounds/仅作临时存储,流程结束即删;需审计轨迹则加--keep-intermediates - 宿主规则文件默认只读 —
AGENTS.md/CLAUDE.md不属于rc:diff-review的默认写入面;只在报告中给建议,不自动落盘