修复: 条数登记校验**只在"绿"的那条路上** —— 文件越红,它的登记数越没人守(假绿方向)
设备在场时跑全套,顺手核了每个文件的『登记条数 vs 实际条数』,发现:
narrow-layout 登记=64 实际=88 exit=0 绿 ⇒ 校验生效(报了)
nav-merge 登记=8 实际=9 exit=0 绿 ⇒ 校验生效(报了)
background 登记=43 实际=44 exit=0 绿 ⇒ 校验生效(报了)
harmony-presets 登记=5 实际=6 exit=0 绿 ⇒ 校验生效(报了)
harmony-admin 登记=22 实际=27 exit=1 ★ 红 ⇒ 校验**走不到**(grep 0 命中)
根因:这条校验原来写在**最后一个 `else`**("退出码 0"那条路)里,而
`r.status !== 0` 会**先在 `else if` 里 reds.push 并跳过它**。
⇒ **文件越红,它的条数登记越没人守** —— 假绿方向:
harmony-admin 那多出来的 5 条判据**不在"被删会红"的保护内**,
而它恰好是红的 ⇒ **只要它一直红,缺口就一直是隐形的**;
等它修绿那天校验才第一次生效,那时多出来的几条可能早被删了。
(同族:`unlisted`/`blind`/`baseline=` 的结论到不了 `verdict`,§16.1。)
★ 而且这个缺口**已经真的吃过一次**:`c523c21`("邮件详情与「我的」页 1:1 对齐")
给 harmony-admin **+5 条判据**(它自己的 commit message 就写着 "+5"),
**却没同步登记数**,而当时该文件是红的 ⇒ 5 条新判据至今裸奔。
修法:把条数校验移进 `else { … }`(红绿都跑;先 push 退出码红,再判条数)。
⚠️ broken(崩了/一条条数都没自报)**不在这里**判 —— `diedWithoutReporting` 已吃掉它,
再叠一条"没找到自报条数"只是噪音:**"判据没答 ≠ 判据答错了"**(§17)。
并做那个"显式、可复核的编辑":登记数 22 → 27(和 c523c21 欠下的那 5 条对齐)。
变异验证:
· 红的 harmony-admin 登记数改 99 ⇒ 报『自报 27 条 < 登记的 99 条』✓
· 改成 27(对齐)⇒ **不报条数**、只剩"退出码 1" ✓
· 修后全套:red=10(harmony-admin 那条从"走不到"变成"报出来"后 +
对齐登记数又收回,净额 0),另 4 个绿文件的条数不符**照旧照报** ✓
`CRITERIA.md` 新增通用规则:**校验写在哪条分支上,决定它保护谁。**
凡"出错时要额外检查 X"的守卫,先问:**这条分支真红的时候,它还跑得到吗?**
This commit is contained in:
@ -487,6 +487,43 @@ console.log('主题:通过'); // 有输出
|
||||
那正是要看见的事(顺手删两条判据、某条被跳过、`check` 实现被改坏)。
|
||||
代价:**故意删判据时要同步改数字**(这是一次显式的、能被复核的编辑,可以接受)。
|
||||
|
||||
### 条数登记校验**曾经只在"绿"的那条路上**(dsh 2026-09-19 设备在场时发现)
|
||||
|
||||
上面那条校验原来写在**最后一个 `else`** 里("退出码 0"那条路)。而 `r.status !== 0`
|
||||
会**先**在 `else if` 里 `reds.push(...)` 并**跳过**它 ⇒ **文件越红,它的条数登记越没人守。**
|
||||
|
||||
**实测**(同刻、设备在场、一次全套):
|
||||
|
||||
```
|
||||
test/narrow-layout.test.mjs: 登记=64 实际=88 exit=0 绿 ⇒ 校验生效(报了)
|
||||
test/nav-merge.test.mjs: 登记=8 实际=9 exit=0 绿 ⇒ 校验生效(报了)
|
||||
test/background.test.mjs: 登记=43 实际=44 exit=0 绿 ⇒ 校验生效(报了)
|
||||
test/harmony-presets.test.mjs: 登记=5 实际=6 exit=0 绿 ⇒ 校验生效(报了)
|
||||
test/harmony-admin.test.mjs: 登记=22 实际=27 exit=1 ★ 红 ⇒ 校验**走不到**(0 命中)
|
||||
```
|
||||
|
||||
⇒ ★ 这是本仓那条母规则的又一例:**"判据在,但走不到"**,
|
||||
而且方向是**假绿**:`harmony-admin` 那多出来的 5 条判据**不在"被删会红"的保护内**,
|
||||
而它恰好是红的 ⇒ **只要它一直红,这个缺口就一直是隐形的**;
|
||||
等它被修绿那天校验才第一次生效,那时多出来的几条**可能早被删了**。
|
||||
(同族:`unlisted`/`blind`/`baseline=` 的结论到不了 `verdict`,§16.1。)
|
||||
|
||||
**修法**:把条数校验移进 `else { … }`(红绿都跑;先 push 退出码红,再判条数)。
|
||||
⚠️ 但 **broken(崩了/一条条数都没自报)不在这里判** —— `diedWithoutReporting`
|
||||
已经把它归入 broken,再叠一条"没找到自报条数"只是噪音:
|
||||
**"判据没答 ≠ 判据答错了"**(§17)。
|
||||
|
||||
**修后实测**:`harmony-admin` 那一段现在报
|
||||
`自报 27 条 > 清单里登记的 22 条 —— 新加的那几条不在"被删会红"的保护内`,`red` 10→11。
|
||||
**变异**:把红的 `harmony-admin` 登记数改成 `99` ⇒ 报 `自报 27 条 < 登记的 99 条` ✓;
|
||||
改成 `27`(对齐)⇒ **不报条数**、只剩"退出码 1" ✓。
|
||||
|
||||
★ **通用规则**:
|
||||
|
||||
> **校验写在哪条分支上,决定它保护谁。**
|
||||
> 凡"出错时要额外检查 X"的守卫,先问:**这条分支真红的时候,它还跑得到吗?**
|
||||
> —— 把校验放在"一切正常"的那条路上,等于**只在没出事时守着**。
|
||||
|
||||
计数必须写在 **`check()` 内部**:写在调用点或靠扫源码,"实现被换空"就看不见了
|
||||
—— 上面那个反例的 `pass` 会是 0,正是靠这一条才有分辨力。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user