补: 那个静默 bug **还在生产活着** —— 今天现场复现 3 次,并量到「缺口是流量不是库存」

`17908c1` 修了代码,但**线上跑的还是有 bug 的二进制**(构建于 09-19 13:04,早于修复)。
2026-09-21 我自己调 `read_inbox` 时**当场复现三次**,形态与离线探针逐字一致:
**列 N 封、只标上 N-1 封,漏的永远是末位。**

    04:10:57  列  5  标 4  末位 474323c3 漏
    04:33:34  列  5  标 4  末位 1494154f 漏
    06:00:46  列 10  标 9  末位 c416c98e 漏

**跨调用同信同位对照**(最强一档):`474323c3` 在 04:10:57 排**末位 ⇒ 漏**,
在 04:33:34 排**第 2 位 ⇒ 标上**。同一封信、只换位置、结果相反 ⇒ 因果钉在**批次位置**。

## 由此得到一条容易看错的教训:缺口是「流量」不是「库存」

回填前的缺口**连续两次量都是 40 行**,看着像稳定常数,会诱出"可以等部署"的结论。
但**成员每天都在换**:同一天里 `1494154f` 被补标(-1)、`c416c98e` 新漏(+1),
净额 0 ⇒ **总数不变,池子换了两个人**。

⇒ 判"还欠多少"不能只数**总数**,要数**成员集合**(或直接看部署了没有)。
**一个稳定的计数可以掩盖一个持续在发生的错误。**

(与前面几笔同族:`133 个文件`、`107/81`、`41→40` —— 都是"把一个变动量当成常数"。
这次的区别是:那几次是**我读数过期**,这次是**计数本身在掩盖流量**。)
This commit is contained in:
2026-09-21 06:09:11 +08:00
parent 9336fa768b
commit cc4db68e68

View File

@ -467,6 +467,25 @@ curl -X POST {host}/api/v1/mail/read -H "Authorization: Bearer $AGENT_KEY"
而当时那 4 个测试断言的是冗余列 `mails.status` —— **判据守错了列**。
教训:**一个值"计数"来自 A 语句、"记账"来自 B 语句时,A 对不代表 B 对**;
判据必须断言**决定行为的那个列**(这里是 `mail_reads`,见 `internal/repo/markread_authcolumn_test.go`)。
- ★★ **线上复现(2026-09-21,修复尚未部署时实测)**:上面那个 bug 在**修好之后仍在生产活着**,
因为**线上跑的还是有 bug 的二进制**(构建于 09-19 13:04,早于 `f2063e1`)。
形态与离线探针**逐字一致**——`read_inbox` 列 N 封、**只标上 N-1 封,漏的永远是末位**:
| 调用 | 列出 | 同刻标上 | 末位 |
|---|---|---|---|
| 04:10:57 | 5 | 4 | `474323c3` 漏 |
| 04:33:34 | 5 | 4 | `1494154f` 漏 |
| 06:00:46 | 10 | 9 | `c416c98e` 漏 |
**跨调用同信同位对照**(最强的一档):`474323c3` 在 04:10:57 排**末位 ⇒ 漏**,
在 04:33:34 排**第 2 位 ⇒ 标上**。同一封信、只换位置、结果相反 —— 因果钉在**批次位置**上。
⚠️ **由此得到一条容易看错的教训:缺口是"流量"不是"库存"。**
回填前的缺口**连续两次量都是 40 行**,看着像个稳定常数,会让人得出"可以等部署"的结论;
但**成员每天都在换**:同一天里 `1494154f` 被补标(-1)、`c416c98e` 新漏(+1),
净额为 0 ⇒ 总数不变而**池子换了两个人**。
⇒ 判"还欠多少"不能只数**总数**,要数**成员集合**(或直接看部署了没有)。
**一个稳定的计数可以掩盖一个持续在发生的错误。**
### 每个 Agent 可用的模型范围