Files
MailUI4Agents/client
JianFeeeee b1eb0ab0c9 feat(criteria): ⑤b 负向清单的**两处副本**都要有守 —— 关掉我在 4598095 里明确留下的那条尾巴
`4598095` 结尾我写了「§7 那条同类无守…不在这条提交里改」—— 这条把它关掉。

## 形状(pi `7ec0044a` 指出,我逐条验证)

「已装二进制 = 当前 HEAD —— 不覆盖: ①脏树构建 ②部署后手工替换」这句话有**两份副本**:
```
deploy/check-deploy-drift.mjs   `negative` 常量 + 自检格      ← **有守**
deploy/redeploy-gateway.sh:480  注释 + `ok` 文案(§7)        ← **无守**
```
实测:
```
grep '已装二进制 = 当前 HEAD' 全仓 ⇒ **只命中 redeploy-gateway.sh 那一行**
redeploy-gateway.sh 的 `--self-check` 出现次数 = **0**(参数只有 --skip-tests/--skip-web/--dry-run/--help)
⇒ 同一个动作、同一句"不覆盖"的声明,**一处有守、一处没有**
```
★ 而**无守的那份恰是部署时打印到屏幕上的那份** —— 读者看到的就是它。

## 判据

`criteria-hygiene` 新增:两份副本都必须同时点名同一对失败类(`脏树` / `手工替换`)。
**变异验证**(两侧都验):
```
shell 那份删掉"手工替换"(注释与 ok 文案都删)⇒ 该判据 **红**,点名
  `redeploy-gateway.sh 未点名「手工替换」` ✓
恢复 ⇒ 绿 ✓
```

固定 8 → **9**,已同步 `run-all.mjs`。

## 归族

与上一条(发现路径)**同族**: 都防「**声明的副本**没有守卫」。
区别: 上一条防"没人知道工具存在",这一条防"**声明漂了没人知道**"。
★ pi 的 ⑬″ 判法在这里的用法:先问"这句声明**在 R 内还是 R 外**"——
  「不覆盖②」属于 R 内(该判据确实回答不了内容替换)⇒ 它不是"划出宣称"就能了事,
  而是**必须说出来**,所以两处副本都要保住这句话。

验证: `criteria-hygiene` 9/9;`bash -n deploy/redeploy-gateway.sh` 未受影响(本提交没动它)。
2026-09-25 07:16:26 +08:00
..