# 两个量具矛盾时，先怀疑我自己写的那个

> **落点**：`9d0289cf` / `d1f0a67b` / `b174542b` / `a6debfc2` / `93e6fe2d` / `a8e5ee6a`（落地线第九十三轮）。
> **同族真源**：[`2026-09-02-a-the-one-off-script-is-the-unreliable-part.md`](./2026-09-02-a-the-one-off-script-is-the-unreliable-part.md)
> —— 「一次性脚本才是不可靠的那环」全文在那里，⛔ 本篇不复写。本篇只写它**没覆盖的两件**：
> 假阳的**方向**、以及**发现它的机制**。

---

## 一 · 09-02 那份记的是「否定一个正确的东西」，本轮记的是「跳过一个该做的东西」

09-02 复盘的七次失误，假结论方向全部是**去否定某个其实正确的东西**（全 ❌ / 全 null / HTTP 200 却是别的页面）。
配套纪律因此写成「**全红先证量具活着**」——放一个必然相等的对照行。

本轮撞上的是它的**反面**，而那条纪律接不住：

「归档」plan 的 Task 1 逐字要求「执行时重扫入站引用，**不信本计划的候选清单**」。我照做，写了一个全仓
引用扫描脚本。它用裸子串匹配 `text.includes(name)`，而候选名 `<name>` 恰好是同名 spec
`<name>-design.md` 的**前缀** ⇒ 造出 **8 处假阳**。其中三处长这样：

| 假阳位置 | 读起来像什么 | 实际指向 |
|---|---|---|
| `src/canonical/composables/form/formEngine.ts:5` | 该 plan 被 **`src/` 产物面**引用 | `specs/2026-07-21-form-validation-engine-design.md` |
| `figma-data/page-recipes.json:8` | 该 plan 被**数据文件**引用 | `specs/2026-07-22-table-data-grid-spec-design.md` |
| `scripts/audit-plan-lifecycle.mjs` ×4 | 该 plan 被**闸脚本自己**引用 | `specs/2026-08-05-…-extension-design.md` |

三处**全部精确落在** plan Task 4.2 那条判据上：「任一处执行时发现引用**承重**（不是叙述而是被程序
拿去读文件）→ 该 plan 移出本批，不强改」。

⇒ **照着假阳执行，会少归档 3 份**，而且每一步都合规：我跑了重扫（plan 要求的）、我按判据处置了
（plan 写的）、闸全绿（那 3 份留在 live tree 本来就有引用）。**没有任何一道闸会报警**，
因为漏做不制造违例。

**两条纪律的方向是相反的**，⛔ 别把它们当同一条：

| | 假阳方向 | 症状 | 接得住它的纪律 |
|---|---|---|---|
| 09-02 | 否定一个正确的东西 | 整齐的**全否**（全 ❌ / 全 0 / 全 null） | 全红先证量具活着（放必然相等的对照行）|
| **本轮** | 跳过一个该做的东西 | **零星的肯定** —— 8 处里只有 3 处要紧，其余淹在正常输出里 | 见下方 §二 |

「全红」是显眼的。**「多了三条命中」不显眼** —— 它长得跟真结果一模一样，且正好落在一条会让我
少干活的判据上。

---

## 二 · 发现它的不是纪律，是两个量具当场对不上

我没有靠自查发现这件事。发现路径是：

1. 我的脚本（闸的 `computeInboundRefs`）报 `2026-08-05-infra-f96-…` 排除自身后 **0 入站引用**；
2. 我的另一个脚本（全仓 grep）报同一份文件 **7 处引用**；
3. 两个数**不可能同时对**。

于是逐处读原文 → 全是 `-design.md` → 假阳定位。

**关键在第 3 步的方向判断**：我当时可以往两边怀疑。
- 「闸的扫描面比全仓小，所以闸漏了」——这句**听起来完全合理**，而且**在别的语境下是真的**
  （本仓 `stale-anchors` 的边界 B1、`rule-inventory` 的 S4 注册面，都确实小于全仓）；
- 「我的 grep 有假阳」。

选错方向的代价是：我会认定「闸看不见 `src/` 里的引用」，进而把三份 plan 移出本批，
**并且顺手给 backlog 记一条不存在的闸缺口**。

⇒ **通则：一个我刚写的量具与一个已上闸的量具矛盾时，默认错的是我写的那个。**
不是因为闸更聪明，而是因为闸**被跑过很多次、有单测、有故障注入记录**，而我的脚本这是第一次跑。
这跟 [`AGENTS.md` §硬规则 #10](../../../AGENTS.md)「读活源」是两件事：两个量具读的都是活源，
差别在**谁的读法被验证过**。

配套动作（已落地）：
- 按名字找引用一律带**扩展名边界**（`${name}.md`，不是 `${name}`）；
- 修完重跑，与闸的输出**逐项对齐**才继续 —— 修后三处假阳全消失、9 份定案与闸逐项一致。

---

## 三 · 这条与 `name-search-absent-fallacy` 是镜像的一对

memory [[feedback_name-search-absent-fallacy]] 治的是「**grep 没命中 ≠ 不存在**」
（要先排查拼写变体 / 字段错位 / 层归属错）。

本条治的是它的镜像：「**grep 命中了 ≠ 是它**」。

两条的危险方向也是镜像的：

- 「没命中就以为不存在」→ 倾向**错删 / 错判缺失**（去动一个其实在那儿的东西）；
- 「命中就以为是它」→ 倾向**漏做 / 错判在飞**（不去动一个其实该动的东西）。

⇒ 两条要一起记。只记前一条，会在「命中太多」时毫无警觉 —— 因为多命中读起来像「证据更充分」。

---

## 四 · 顺带两条，各自独立

### (a) 让闸说话，优先于按我推测的判据预先改文本

执行「判定表」plan 时，我先按推测改掉了 plan 原文三处（示例路径 `SettingsPage.vue` /
`dist/icons/svg/<ns>/…` + 一句 4-id 先例枚举），理由是「它们可能撞 `stale-anchors` 的
code-span-path / 撞 S7」。

随即我恢复了逐字原文，让闸说话。实测 `code-span-path` 读数 **99 逐字不变**
（无目录分量的裸文件名不成为候选），S4 也没红（那行提到的不是 4 份 target 文件）
⇒ **三处偏离全部不必要**。

代价虽小，但形态值得记：**「预先躲一个还没证明存在的红」与「闸红时改判据」是同一个病的两头**——
都是拿我对判据的推测替代判据本身。前者的症状更隐蔽，因为它不产生任何红。

### (b) 收尾时闸抓到的那个缺陷，正是顶条 ② 那条纪律的正面用例

wrap-up 写 tracker 时，我把「判定表」plan 的链接写成了 `_archive/` 路径 —— 而那份 plan
**并未**归档（自归档是「归档」plan 自己 Task 6.4 的动作，判定表 plan 无此步；我把两份 plan
的收尾动作混了）。`stale-anchors` 精确点名 `tracker:184 目标文件不存在`。

正解在判据之外（改我写错的链接），⛔ 不是让闸别报。这条本轮**没有**踩坑，如实记为
「纪律按预期生效」的一次 —— 按 [[feedback_recommendation-self-audit]] 的同族要求，
验证过管用的做法与教训同等重视。

---

## 五 · 本轮 plan 预判过期的四处（与第九十二轮同族，⛔ 不在此复写形态）

形态定义（「plan 写完之后仓库长出了新的闸面」）真源 =
[`2026-09-03-a-plan-s-least-reliable-part-is-what-it-predicts-about-the-gates.md`](./2026-09-03-a-plan-s-least-reliable-part-is-what-it-predicts-about-the-gates.md)。
本轮四处实例逐条记在 [STATUS-CHANGELOG](../STATUS-CHANGELOG.md) 第九十三轮条目 ⑥ 那张表，
此处只留一句最值得带走的：

**「归档」plan 记的「session pickups 已归档 9 份」现取是 4 份 —— 方向是反的。**
查明 `483e3feb`（08-25「归档桶三」）把 `_archive/` 里 18 份**纯删除**了。
⇒ 「归档」这个动作事实上有**第二段**（`live tree` → `_archive/` → 删除），
而两份 08-12 的 plan 全文都没有这个概念，它们的终点都停在 `_archive/`。
读数**方向反了**和读数**不变**一样，都是「先证量具活着」的触发信号 —— 这次量具是对的，
过期的是 plan 对世界形状的假设。
