# 测量口径自己会骗人的三种方向（2026-08-12）

> 一个 session 里连撞三次「数字是真的、结论是错的」，而三次的**骗法方向各不相同**。
> 触发登记：WRAP-UP §Retrospection 触发判断「学到通用工程经验 / 发现新 pattern」。
> 现场证据与逐条数字在 [STATUS-CHANGELOG](../STATUS-CHANGELOG.md) 2026-08-12 条，本文只留可迁移的部分。

---

## 三次

| # | 现象 | 数字本身 | 结论错在哪 |
|---|---|---|---|
| 1 | 闸自印「容器宽 22 处」，我据此把 STATUS 里的「19」改成「22」并 commit | **真的**（闸确实数出 22） | 闸把**注释里**提到的 `max-width` 数成了真声明。真值一直是 19 |
| 2 | 单测 12 条全绿，其中「同档保持导航原始顺序」 | **真的**（确实 pass） | 样本让被断言的集合**是空的**，`[].sort()` 恒等 —— 判据根本没在守 |
| 3 | 窄屏面板 `documentElement` 横向溢出「改动前后逐字相同」 | **真的**（确实没变） | 面板左缘在 **-113px**，被切在屏外。负方向溢出**不产生滚动条**，所以不进这个指标 |

三种方向：**① 被污染**（把不该算的算进来）· **② 空过**（该算的集合是空的）· **③ 有盲区**（越界发生在指标看不见的方向）。

---

## 可迁移的三条

### 1. 数字变了，先证明这次改动里存在能解释它的**真**变更

第 1 次的识破点不是怀疑闸，是**算术对不上**：我这次改动一条 `max-width` 声明都没新增，而 S5 的处数从 22 跳到 25。
往回查才发现 +3 恰好等于我新写的三处提到旧断点的注释。

> **判据**：闸/`grep` 报出「变了」时，先在自己的 diff 里找出能解释这个增量的真实声明。找不到 → 先怀疑解析面，别顺着数字改结论。

这与 2026-08-11 记下的「grep 出全 0 时先证明该模式能命中一个已知存在的样本」是**同一条规则的两个方向**：
一个管「没命中」，一个管「多命中」。合起来是：**任何计数在被当成事实之前，先验它的分子分母各由什么构成。**

### 2. 断言写了 ≠ 判据在守 —— **样本的区分力要单独验**

第 2 次是这轮最值钱的。我按纪律做了故障注入（这一步没省），四组注入里有三组正常转红，**唯独「改成字母序」那组全绿**。
如果只看「我做了故障注入」这个动作，会以为覆盖到位了。

根因：样本选了查询 `form` —— 它的命中**全是前缀命中**，于是「非前缀命中的尾段」是**空数组**，
而 `[...[]].sort()` 永远等于 `[]`。断言在，集合是空的。

换成 `n`（前缀只有 `notification`，而 `button`/`icon`/`input`… 是仅包含命中，且导航序与字母序**相反**）后，四组注入逐条打红。

> **判据**：故障注入要**逐条**对上「哪个注入应该打红哪条断言」，而不是只看「有没有变红的」。
> 一条注入没打红任何东西 = 该注入对应的判据缺失或空过，**不是**「实现恰好没问题」。
> 配套写法：在断言前先 `expect(集合.length).toBeGreaterThan(N)`，把「样本非空」本身变成受检事实。

这条是对既有 memory `regression-pass-needs-fault-proof` 的**另一半**补充：那条讲「故障要造在防御层之外」，
这条讲「故障即使造对了，样本没区分力照样测不出来」。

### 3. 聚合指标有方向盲区 —— 越界不一定进得了它

第 3 次：`scrollWidth - clientWidth` 是本仓库窄屏工作反复用的溢出判据（抽屉那轮靠它把溢出清到 0）。
但它**只看正方向**：元素跑到视口**左侧外面**时，这个差值一动不动。

> **判据**：用聚合指标（溢出量、总数、耗时）判「有没有越界」时，先问一句**它的定义域覆盖哪几个方向**。
> 位置类问题要配一条**矩形断言**（元素的 `left ≥ 0 && right ≤ viewport`），聚合值只能当辅助。

---

## 与既有规则的关系

- 不新增任何硬规则。三条都是**已有纪律的锐化**：#1 锐化「先验模式再下结论」、#2 锐化「故障注入」、#3 锐化「窄屏溢出判据」。
- 落地位置各自就近：#1 与 #3 已写进 `scripts/audit-layout-tokens.mjs` 与 `playground/docs/docs.css` 的注释（连同会让它复发的具体写法）；
  #2 写进 `tests/docs-search.test.ts` 那条测试自己的注释里。**规则贴着会复发的地方放，不另开清单。**
