# Fresh Eyes Review

> 用「干净上下文的第二个 agent」审查代码改动、方案或数据结论：委派一个 spawn 子 agent（不带本会话上下文），强制每条发现带「位置 + 复现命令 + 实测输出」，并用反向验证（把 bug 装回去必须变红）收口。当用户说「审一下 / review 一下 / 找找 bug / 复核这个改动 / 让别的 agent 看看 / 这段代码有没有问题」，或你刚完成会碰数据、凭据、权限、定时任务的改动想验证时使用。

- Skill: `dely0/fresh-eyes-review` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add dely0/fresh-eyes-review`
- Raw SKILL.md: https://api.skillmd.com/api/skills/dely0/fresh-eyes-review/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: Dely0 (https://skillmd.com/u/dely0)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/dely0/fresh-eyes-review

---


# Fresh Eyes Review（换个脑子审一遍）

## 这个 skill 解决什么

刚写完的东西，自己再读一遍基本没用 —— 因为**自审用的还是同一个脑子里的同一套想当然**，第一遍没看出来的地方，第二遍照样看不出来。实测数据支持这一点：把同一处错误分别以"外部注入"和"模型自己产生"两种身份给模型，14 个模型呈现 **64.5% 的自我纠错盲区**（能力在，但"自己错的时候"不被激活）。

所以本 skill 做三件事：

1. 用 DSH 原生的 `subagent`（**spawn**）起一个**空对话**的审查者 —— 它没有你的上下文，被迫从产物本身重新理解；
2. **强制它交出可复现的证据**，而不是"建议考虑"这类判断；
3. 修完用**反向验证**收口：把 bug 装回去，测试必须变红。

**边界（很重要，别对外夸大）**：这不是"多一个 AI 更安全"。对照实验（29 名专家、50+ 小时）显示，多一个 LLM 审查者**并不会提高高危缺陷的捕获率**，还会带来锚定效应。价值全在三处：**审查者能真的跑命令** + **强制它交证据** + **收口动作能变红**。市面上没有任何 AI 审查产品要求"复现命令 + 实测输出"，这三条才是差别。

## 什么时候用 / 不用

**用**：
- 改动会碰数据、凭据、权限，或者不可逆（删库、发版、迁移、改配置）
- 跑在无人值守的地方（定时任务、看门狗、同步脚本、自动清理）
- 你已经答不出"**我怎么知道它真的在跑**"
- 用户明确要求审查、复核、找 bug

**不用**：
- 一次性的小脚本、临时排查（跑一次就扔，错了当场就看见）
- UI 微调、文案、肉眼一看就知道对错的改动
- 需求还没定清楚 —— 先对齐再互查，否则两边一起跑偏

## 流程

### 第一步：收集材料

子 agent 是空对话，你脑子里的事情它一概不知道。所以先把这几样列出来（缺的写"未提供"）：

- 工作目录的**绝对路径**
- **改动范围**：`git diff --stat` / 文件清单 / commit 范围
- **想达成什么**：一句话验收标准
- **能跑什么**：测试、构建、复现入口
- **证据文件写到哪**：指定一个目录（如 `<仓库>/.review-evidence/`），让它把每条复现命令的**原始输出落盘**、首行写 `[exit code: N]`，报告里只写路径
- **临时产物写到哪**：指定一个仓库外或明确被忽略的目录（如 `<仓库>/.tmp-review/` 或系统临时目录），并要求它设 `PYTHONDONTWRITEBYTECODE=1`、不要在 skill 目录或仓库里留下 `__pycache__`、样例文件、临时脚本

**不要**写进"我为什么这么写"。那会把你的假设一起传染给它，等于把独立性抵消掉。

**但要写「哪些已经定死了」。** 这两件事容易被混为一谈，区别很重要：

| 该藏起来的 | 该给它的 |
|---|---|
| 你的**推理过程**（"我认为这样是对的，因为…"） | 范围、验收标准、环境约束 |
| 具体某处代码的**自我辩护** | 有出处的决策记录（谁定的、在哪儿定的） |

想把后者写清楚、又不越界变成「封口」，用 `references/handoff-template.md` 落成 `<工作目录>/.review-handoff.md`。它在**首轮其实就有用**（避免审查者在已知取舍上白费力气），在第四步的模式 C 里则是**必需**——第二轮必须知道第一轮说了什么才能去怼它。

### 第二步：委派一个空对话的审查者

用 `subagent`，它默认 provider 就是 `spawn`：

```
subagent(
  description = "独立审查 <模块名>",
  prompt      = "<references/reviewer-prompt.md 填满后的全文>",
  run_in_background = false
)
```

五条硬性注意：

1. **必须是空上下文的子 agent**：DSH 里就是 `subagent`（spawn）；**不要用 `subagent_fork`** —— 它以父级已完成轮次作初始内容，你的对话历史会被送过去，独立性当场归零。
   ⚠️ **术语陷阱**：Claude Code 的 `context: fork` 意思是"派生一个**隔离**上下文"，与 DSH 的 `subagent_fork`（**继承**父级对话）**含义正好相反**。移植到别的平台时，先确认那里的 "fork" 是隔离还是继承。
2. **父级只收到它的最终输出。** 它跑命令的中间过程不会回传，所以证据必须**落盘成文件**并在报告里写明路径 —— 这正是模板里那四个字段存在的原因。
3. **审查者只读，不改文件。** 修是编排者（你）的事；审查者一旦动手改，它就从"独立审查"变成了"又一个人"。
4. **提示词必须自足。** 用 `references/reviewer-prompt.md`，把 `<...>` 全部填掉再发。
5. **想进一步拉开独立性**：调用时带 `provider` / `model` / `reasoning_effort` 换一个模型。同一模型的另一个上下文已经能拿到大部分收益（盲区来自"身份"而非权重），换模型是加分项，不是必需，也不是不装的借口。

它会继承你的工作目录和工具，所以它能自己去读文件、自己跑测试 —— 让它跑，别替它跑。

**关于"退回补证据"怎么落地**：前台（`run_in_background = false`）起的 subagent 结束后不会留下可寻址的 agent id，`send_message` 无处可发 —— **不要设计成"叫同一个审查者补证据"**。两种可行做法：

- **推荐：重开一个空上下文的审查者**，把原报告一起给它，明确"只许补证据、不许重报、不许改结论"。这样既拿得到补充材料，又不破坏独立性（把原报告给它带来的锚定，比你直接把结论喂回去小得多）。
- 或者后台起（保留 id 以便追问），但要接受它已经看过你的上下文之外的东西、且会话还在，独立性略降。

不论哪种，都要在最终记录里注明**哪几条是原证据、哪几条是后补的** —— 补出来的证据强度不如当场跑出来的。

### 第三步：过滤 + 收口

**1. 先过格式门禁。** 把它的报告存成文件，然后：

```bash
python "<skill-dir>/scripts/check_review_report.py" <report.md>              # 默认：查格式与证据文件可用性
python "<skill-dir>/scripts/check_review_report.py" --pre-fix <report.md>    # 改之前跑：重跑「反向前置」，必须仍然失败
python "<skill-dir>/scripts/check_review_report.py" --replay <report.md>     # 改之后跑：重跑复现命令并与证据文件 diff
# 模式 C（对抗性复审）——第二轮：
python "<skill-dir>/scripts/check_review_report.py" --falsify --handoff .review-handoff.md <round2.md>
```

退出码：**0** 每条都带齐证据 / **1** 有条目不合格 / **2** 报告读不了（缺文件、未知参数、编码解不开；`--pre-fix` 与 `--replay` 同时出现也退 2）。

**三档的区别是关键**：默认档只查"写了没有"（含证据文件在不在、首行是不是 `[exit code: N]`、位置真不真）；**`--pre-fix` 档在动手修之前跑，重跑每条的「反向前置」命令并要求它仍然失败**；**`--replay` 档在修完之后跑，重跑复现命令并与落盘证据逐行比对**。

- 默认档 0 分**不代表内容为真** —— 你可以编一段输出，它照样放行。
- `--pre-fix` 0 分才叫"缺陷真的被观察到失败"：修之前先跑一次，跑不红就别修。
- `--replay` 0 分才叫"这条证据是真的跑出来的"，而且现在还能跑出同样的结果。

**两条命令、两个时刻，别搞混**：`--pre-fix` 是**改之前**（要求失败），`--replay` 是**改之后**（要求一致）。同一个报告先过前者、修完再过后者，这条发现才算走完——**先红后绿**。

可选参数：`--workdir DIR`（默认报告所在目录）、`--timeout SEC`（默认 120）、`--strict`（缺严重度、位置没行号、**位置指向不存在的文件**、**缺少反向前置**这类提醒也计为不合格）。

**门禁还会顺手核实「位置」是不是真的。** 它从位置里解析出 `路径:行号`，检查文件在 `--workdir` 下存在、且行号不超过文件总行数（只对代码类后缀做这件事，文档类审查不会被误伤）。默认档只提醒，`--strict` 才算不合格——因为报告可以合法地引用 `--workdir` 之外的路径。

为什么值得加这一条：**重放只能证明「命令能跑、输出和证据文件一致」，完全无法证明「被指控的文件和行号真的存在」。** 实测过一种攻击：位置写成 `src/does_not_exist.py:9999`，命令和证据全部合规，重放档照样给绿——而幻觉路径恰恰是 LLM 的典型失败模式。这类机械可查的东西不该推给人。

**「反向前置」是治「命令没有证明力」的那味药。** 门禁验不了"这条命令是否真的触及被指控的代码"，但它能验一件更硬的事：**你声称有缺陷，那就得给出一个在有缺陷的代码上会失败的命令，而且退出码必须非零。**

**它堵住了哪一半、没堵住哪一半（都是实测过的）**：

- ✅ **证据文件记成 `[exit code: 0]` 的恒真证据，四个档位全部拦下。** 记成 0 等于自认「命令在缺陷代码上通过了」＝缺陷不成立，这是硬失败。
- ✅ **`--replay` 会重跑反向前置命令并要求它已经通过**（先红后绿的绿半边）。所以「修完之后前置命令仍然失败」会被抓住——修复没完成，或那条命令与缺陷无关。
- ❌ **把前置证据的退出码伪造成 `[exit code: 1]`、命令本身却是恒真的，只有 `--pre-fix` 抓得住**（因为只有它会在改之前真的重跑）。默认档、`--strict`、`--replay` 都会放行。

> **这条决定了工作流**：`--pre-fix` **不是可选项**。任何一条发现，都要在动手改之前先跑一次 `--pre-fix`；只跑 `--replay` 就相当于放弃了红半边，上面那个伪造缺口就一直开着。

四种攻击姿态 × 四个档位的实测防线（✅ 拦下 / ⚠️ 放行）：

| 攻击姿态 | 默认 | `--strict` | `--replay` | `--pre-fix` |
|---|---|---|---|---|
| 位置指向不存在的文件/行号 | ⚠️ | ✅ | ✅ | ⚠️ |
| 跑一条与发现无关的命令（前置也是无关的失败） | ⚠️ | ⚠️ | ✅ | ⚠️ |
| 证据只留输出的一行（选择性摘录） | ⚠️ | ⚠️ | ✅ | ⚠️ |
| 恒真命令 + 证据记成 exit 0 | ✅ | ✅ | ✅ | ✅ |
| 恒真命令 + 把前置证据伪造成 exit 1 | ⚠️ | ⚠️ | ⚠️ | ✅ |

注意 `--replay` 之所以能拦下「位置不存在」和「无关命令」，靠的是它的两个附加校验（位置可核实性 + 前置命令必须已转绿），不是靠重放本身。

**别误读这张表**：`--pre-fix` 不是万能的，它只回答"你给的前置命令现在失败吗"。**「碰巧失败的无关命令」仍然能骗过它** —— 那条命令在改前改后都失败，四个档位里只有 `--replay` 会因为「前置没转绿」而拦下它，而当作者真的把缺陷修好、只是命令选得无关时，就只剩人判断了。要问的还是那句：这条命令跑在「有问题」和「没问题」两种代码上，输出会不一样吗？

门禁接受模板里的所有自然写法：`- 位置：…`、`- **位置**：…`、`location: …`，值可以写在标签同一行，也可以写在下面几行（多行命令、围栏里的真实输出都算）。

**报告读不了（exit 2）时先修编码**：GBK / UTF-16 会被自动识别并提示转存 UTF-8；真正解不开的文件会明确报错，不会静默给一个错判。

> ⚠️ **`--replay` 不是沙箱。** 它会在你指定的目录里执行报告里写的命令，只有一层"防手滑"拒绝表和超时。**只在你自己读过、且愿意让那些命令碰过的报告上开。**

**2. 分流与退回话术**见 `references/anti-patterns.md`。三要素不齐的条目，**退回**（按第二步说的重开一个审查者）或**直接丢弃**，**绝不凭它改代码**。**重放不一致的条目升级给人判断** —— 可能是环境差异，不要直接当造假。

**3. 由你来修，每修一条补一个断言。** 断言写进**项目既有的测试文件**（照该项目已有的约定与命令）；项目没有测试约定时，先建一个最小测试文件，并在交付说明里写清它的路径和运行命令 —— 不要往 skill 目录或 `node_modules` 里塞测试。

**4. 然后反向验证。这一步不是可选项，是收口动作本身。** 把 bug 故意装回去，测试必须变红。

- 红不了 → 说明断言没咬住，**继续改断言，不是继续改代码**；没演示过变红，就不算修完。
- 这一步是整套流程里**最值得优先做的那一条**：它把"有人看过"变成"机器以后一直看着"。
- **它专门补掉门禁的一个洞**：门禁能验「证据真的跑出来了」，但**验不了「这条命令对结论有没有证明力」**——跑一条恒真命令（`assert True`）配上合规的证据文件，门禁会放行。断言能不能变红，是唯一能拦住这种情况的东西。
- 收尾核对一遍工作目录：**没有留下临时脚本、样例文件或 `__pycache__`**。

**5. 最后你自己只看两件事**：证据能不能重现、这条要不要接受。这就是人类仲裁，本来就该你做。

### 第四步（可选，价值最高的一轮）：对抗性复审

> ### ⚠️ 这一轮**默认不跑**，而且要人点头
>
> **默认只跑首轮。** 对抗性复审要多花一个子代理的时间（实测量级：3–6 分钟），该不该花是人的决定，不是你的。
>
> **你（执行者）不得自行升级到多轮。** 只有人在对话里明确说过（「开第二轮」「再复审一下」「我不放心这个改动」），你才能进这一步。
>
> **门禁会拦这件事**：交接文档必须声明审查模式（`审查模式：首轮` / `审查模式：首轮 + 对抗性复审（用户已确认）`）。声明为「首轮」却跑 `--falsify`，**直接退 2**。所以「偷偷升级到多轮」在机械上是做不到的。

**前提**：第一轮走了、而且你有理由认为它可能报错。**代价**：再一轮的时间与 token。**什么时候值得**：改动碰数据/凭据/权限/不可逆操作，或者夜里无人值守跑。

这一轮问的问题和首轮**完全不同**：不是「这段代码有什么问题」，而是「**上一轮那份报告，哪一条是错的**」。理由：一次自信的**错误**发现，下游代价最大 —— 它会让人去改本来没错的代码。而首轮的审查者自己不会知道自己报错了，只有第二个审查者能把它按下去。

流程：

1. **先写交接文档** `<工作目录>/.review-handoff.md`，用 `references/handoff-template.md`。它是写给审查者的简报：范围、环境约束、**已定取舍（每条必须带出处）**、以及**上一轮已驳回的发现及其理由**。
   - 为什么必须有它：审查者是空上下文的，它不知道哪些是**已经定死的取舍**，会把它们当缺陷报上来、还认真复现一遍 —— 那是真金白银。
   - 为什么它危险：**写它的人正是被审的人**。所以每条取舍必须带出处（`HumanDecision` / `RecordedDecision` / `OrchestratorClaim`），且必须写成「影响边界 + 请只报哪类」而不是「别管」。门禁会逐条检查出处。
2. **委派第二个空上下文审查者**，用 `references/adversarial-reviewer-prompt.md`。给它：上一轮报告、交接文档、工作目录，并要求它**动手重跑**上一轮的命令。换一个模型更好（同族模型共享盲区）。
3. **过门禁**：`--falsify --handoff .review-handoff.md`。它会检查第二轮报告是否分齐三段（确认成立 / 驳倒 / 未决）、每条是否带判定标注，以及交接文档的取舍是否都有出处。

第二轮报告**不走**发现块那套格式 —— 它判的是**报告**，不是代码，所以不该被逼着为每条都造一个新证据。但它必须说清：每条旧发现是**确认**、**驳倒**还是**未决**。

## 铁律

1. 没有复现命令和证据的条目 = 意见，不是发现 → 丢弃。
2. 跑不了就说跑不了。**编造输出比不报更糟** —— 而且现在会被 `--replay` 抓住。
3. 只报问题，不报夸奖。
4. 收口永远是"装回去必须变红"，而且要当场演示。**没演示过变红，就不算修完。**
5. 用空上下文（spawn），不用继承上下文（DSH 的 `subagent_fork`）。注意别的平台 "fork" 可能含义相反。
6. 审查者只读，不改文件；修和补断言都是编排者的事。
7. 收尾不留临时产物。
8. 重放一致只证明"证据是真的"，**不证明结论正确**；重放不一致要升级给人，不是自动定罪。
9. **位置必须真实存在。** 门禁会核实（`--strict` 下算不合格）——被指控的文件都找不到，后面的证据再漂亮也是空的。
10. **每条发现都要有「反向前置」：一个在有缺陷的代码上会失败的命令，退出码非零。** 门禁会查这条证据的退出码（记成 0 直接判不合格，等于自认命令通过了）。**先跑 `--pre-fix` 看它红不红，再动手修** —— 跑不红就别修，先怀疑这条发现。
11. **「这条命令凭什么能证明这个结论」永远要人判断。** 门禁能验「命令失败了、而且失败得可复现」，验不了「它的失败指向那条结论」。跑一条碰巧失败的无关命令，仍然能骗过它。

## 更省的一档（连审查者都不开）

只保留第三步里的两件事：**每处改动配一个能变红的断言**，外加问自己一句"**我怎么知道它真的在跑？**"

有实证支持这一档：抬高上限的是可执行的判据，第二个模型主要是帮你找到"该加哪条判据"。所以在预算紧张或者任务很小的时候，退到这一档是完全合理的，不用有负担。

## Resources

### scripts/check_review_report.py

审查报告的门禁，四档：

- **默认档**：查格式。每条发现是否带齐「位置 / 复现 / 证据（内联实测或证据文件）」与「反向前置」，证据文件在不在、首行是不是 `[exit code: N]`，**反向前置证据的退出码是否非零**，以及**「位置」指向的文件是否真的存在、行号是否在文件范围内**（后两项之外，位置与缺失反向前置只提醒，`--strict` 下才算不合格；**反向前置证据记成 0 是硬失败**）。
- **`--pre-fix` 档**（**改之前**跑）：**重跑**每条「反向前置」命令，**要求它现在仍然失败**。跑绿了就说明缺陷复现不了 —— 先别修，回去看这条发现是不是真的。
- **`--replay` 档**（**改之后**跑）：**重跑**每条复现命令，把真实输出与落盘证据**归一化后逐行比对**（时间戳、耗时、uuid、临时路径、pid、地址会被折叠）；**同时重跑反向前置命令并要求它已经通过**，补上「先红后绿」的绿半边。退出码一致、输出一致且前置已转绿才算过。
- **`--falsify` 档**（**模式 C**，必须配 `--handoff`）：校验**对抗性复审报告**——三段（我确认成立的 / 我驳倒的 / 未决）是否齐、**每段是否至少点名了一条上一轮发现**、判定条目是否带标注；同时校验**交接文档**——`## 范围` 与 `## 已定取舍` 两个小节是否**各自都在**、取舍条目是否每条都带出处（出处必须紧跟在 `依据：` 之后）。第二轮判的是**报告**不是代码，所以它不走发现块那套格式。**`--falsify` 与 `--pre-fix` / `--replay` 同给会退 2** —— 它不走证据重放，静默忽略等于报了一个「验过了」的假信号。

退出码：0 全合格 / 1 有不合格 / 2 报告或交接文档读不了、用法错误。可以直接当 CI 门禁用 —— 它自带回归套件（见下），所以"退出码语义"是被断言钉住的，不是口头约定。报告格式由 `references/reviewer-prompt.md` 规定，两者是配套的，改格式要同时改这几处（SKILL.md、模板、门禁），并跑一遍回归。

**改门禁的规则，必须配定向变异**：把新规则删掉，确认套件真的变红。因为「校验器会打印提醒」和「校验器会让它不合格」是两件事 —— 这个项目里已经栽过两次（`--strict` 漏计数、`--falsify` 整套规则没被任何断言覆盖，前者靠人读代码发现，后者靠独立审查者做定向变异发现）。

> `--pre-fix` 与 `--replay` **都不是沙箱**：它们执行报告里写的命令，只有拒绝表与超时。只在你读过、且愿意让那些命令碰过的报告上开。重放一致 ≠ 结论正确；重放不一致 ≠ 造假（可能是环境差异）——升级给人判断。

```bash
python "<skill-dir>/scripts/check_review_report.py" <report.md>
python "<skill-dir>/scripts/check_review_report.py" --pre-fix [--workdir DIR] [--timeout SEC] <report.md>
python "<skill-dir>/scripts/check_review_report.py" --replay [--workdir DIR] [--timeout SEC] <report.md>
python "<skill-dir>/scripts/check_review_report.py" --falsify --handoff FILE <round2.md>
python "<skill-dir>/scripts/check_review_report.py" --strict <report.md>   # 提醒也算不合格
```

### scripts/test_check_review_report.py

门禁的回归套件：**70 条断言**，覆盖这条流水线上真实踩过的坑（末条发现被尾部小节补齐、散文报告靠"无问题"子串蒙混、GBK/UTF-16 误杀、加粗标签被误判、多行证据被判为空、填充词当证据、`未能执行` 的原因阈值、悬空证据文件、证据文件缺退出码首行、**位置指向不存在的文件、位置行号超出范围、含空格路径、非代码后缀写在前面导致的整体绕过、URL 不被当成文件、无目录的代码文件名**、**反向前置证据记成 0、缺反向前置证据、缺反向前置字段、反向前置写「未能执行」、`--pre-fix` 下缺陷复现不了、`--pre-fix` 与 `--replay` 互斥、反向前置命令同样受拒绝表约束、`--replay` 下前置命令必须已转绿**、**交接文档缺出处 / 缺取舍条目 / 文件不存在、`--falsify` 缺三段 / 缺判定标注 / 必须配 `--handoff`**、重放不一致/退出码不一致/命中拒绝表/超时、易变内容归一化……）。夹具现造，不依赖任何外部文件。

**改完门禁必须跑它，且必须全绿**；全绿代表"门禁行为与文档一致"，不代表某份具体报告合格。要加新规则，先在这里加一条会红的断言。

```bash
python "<skill-dir>/scripts/test_check_review_report.py"
python "<skill-dir>/scripts/test_check_review_report.py" --only <用例名> --skip-harness  # 秒级
```

`--only <名字>` 可重复，配合 `mutation_check.py --quick` 用来把「跑一次」从 11 秒压到 1 秒以内。

### references/reviewer-prompt.md

**首轮**要给子 agent 的完整提示词模板，含强制输出格式（六个字段，含**反向前置**及其证据 + 证据文件的 `[exit code: N]` 约定）与八条规矩。每次委派前读它、填掉 `<...>`。

### references/handoff-template.md

**交接文档模板**（模式 C 的前提）。它是执行者写给审查者的简报：范围、环境约束、**已定取舍（每条带出处）**、上一轮已驳回的发现及其理由。三条硬规矩写在里面 —— 尤其「取舍必须写成可证伪 + 有边界，不能写成别管」，因为写这份文档的人正是被审的人。

### references/adversarial-reviewer-prompt.md

**模式 C（对抗性复审）**的提示词。它问的问题和首轮完全不同：不是「这段代码有什么问题」，而是「**上一轮那份报告哪一条是错的**」。配套的三段式输出格式（确认成立 / 驳倒 / 未决）与规矩都在里面。

### scripts/mutation_check.py

**定向变异测试**：把门禁的每条规则逐条删掉/改坏，确认回归套件真的变红。

为什么它是必需品：**「校验器会打印提醒」和「校验器会让它不合格」是两件事。** 这个项目栽过两次 —— `--strict` 漏计数（规则形同虚设），以及 `--falsify` 整簇规则**没有任何断言覆盖**（删掉照样全绿）。两次都是变异测试发现的。

```bash
python "<skill-dir>/scripts/mutation_check.py" --quick   # 约 4 秒：只跑受影响的用例
python "<skill-dir>/scripts/mutation_check.py"           # 全量套件，提交前跑
```

**改了门禁规则就在这里补一条变异。** 加进来的变异如果存活，说明那条规则没被钉住。

### references/anti-patterns.md

收到无效发现时的分流表、六种最常见的噪声、可直接照抄的退回话术、退出码与 `--replay` 边界怎么读，以及"别指望多一个 AI 提高高危捕获率"的实证依据。

## 这套东西的来历（被问到时的说法）

**它不发明零件。** 独立审查者、强制证据、变异收口、程序化门禁这四件事，单独都有人做过，而且有些做得更深：

- `momomuchu/make-no-mistakes` —— `context: fork` + 禁写工具做结构性独立；`scripts/mutate.py` 真做单点变异写回源文件重跑，存活率过高直接 FAIL；10 级门禁阶梯。
- `QwenLM/qwen-code` 的 autofix —— reproduce-before-fix、修复前测试必须本来就是红的（`REJECTS the round if none of them fails there`）、提交前 mutation probe。
- `andrewstellman/quality-playbook` —— 强制 `BUG-NNN.red.log`/`.green.log` 落盘，且有"重跑同一条命令与落盘文件 diff"的防伪造机制；那层机制是因为真发生过**模型把自己编造的期望输出写进证据文件**的事故才加的。
- `Kappaemme-git/codex-bug-reproducer` —— `Never claim a bug from code inspection alone`，复现输出落盘 JSON 并比对修复前后。
- DSH 生态的 `PerryLink/dsh-doublecheck`（四阶段交付门禁、退出码 0/1/2、red/green 证据门）与 `joekytc/dsh-swarm`（`validateReviewEvidence`；它自己在 Known limitations 里写了 *"Review evidence is existence-checked, not replay-proven"*）。
- 官方 `anthropics/claude-code` 的 `code-review` —— 独立 agent 结构正规，但靠 0–100 置信度阈值过滤误报，并明文写着不要跑 linter 去验证。

**本 skill 只 claim 那个窄口子**：对**一份审查报告本体**跑校验器，并按条目**重放**它的证据。我没有找到同时做到这一点的实现；如果你知道有，请开 issue 告诉我。

机制上的祖先是 **N-version programming / design diversity**（Avizienis 1985）与 **IV&V**（IEEE 1012）；LLM 时代的工程结论来自 Anthropic 的多智能体工程博客（多智能体约 15× 聊天 token）与 Cognition 的《Multi-Agents: What's Actually Working》（审查者**事先不共享上下文**时效果最好；有效形状是"写入单线程、其他 agent 只贡献判断力"）。

**两条必须一起说的反证：**

1. **Knight & Leveson 1986**（DOI `10.1109/TSE.1986.6312924`）证明"独立开发"的软件版本**仍会共同失效** —— 隔离不等于错误不相关。要真正的独立性得换**来源**（模型族、上下文、提示词框架），不能只换数量。
2. **多一个 LLM 审查者不会自动提高高危缺陷的捕获率**（29 名专家 / 50+ 小时对照实验，arXiv `2411.11401`，还带锚定效应）。真正抬高上限的是"能跑命令 + 强制可重放证据 + 反向验证收口"。

