JianFeeeee
ed024cd0b2
改: 我一直量的是**代理量** —— 真实重投面是 unreadFor(只读 mail_reads),不是 mails.status='unread'
发现路径:向 pi 解释 `4→8→2` 时去核 `?status=unread` 到底挂在哪一列,读到:
repo.go:611 if status == "unread" { q += ` AND ` + unreadFor("$1") } // :612
repo.go:488 func unreadFor(arg) = (m.status <> 'archived' AND NOT EXISTS(
SELECT 1 FROM mail_reads r WHERE r.mail_id=m.mail_id AND r.reader_name=arg))
⇒ **真实判据只看 `mail_reads`,`mails.status` 完全没参与。**
⇒ "`m.status='read'` 但 `mail_reads` 无行"**同样在重投面内**(那正是 40 行 gap 的成因)
⇒ 而我上面所有"会 `catchUp` 重投"的数都拿 `m.status='unread'` 筛的 ⇒ **系统性少算**。
一次计算内实测(join 非 archived ∧ 有真孩子):
真实(unreadFor 口径) = 92
我的代理(status='unread') = 77
代理漏掉(status='read' 无行) = 15
加法自洽 77 + 15 = 92 = 直接算 ✓
★ 这又是本仓那条 **"判据必须读决定行为的那个列"**,方向相反而已:
上次是**测试**读错列(守冗余列 ⇒ 守不住 bug),
这次是**我自己**读错列(拿冗余列当筛选 ⇒ 量小重投面)。
**两处错的是同一个东西:把 `mails.status` 当权威。**
2026-09-21 07:31:13 +08:00
..
2026-09-19 14:01:21 +08:00
2026-09-21 07:31:13 +08:00
2026-09-20 22:35:35 +08:00
2026-09-15 06:33:54 +08:00
2026-09-19 12:47:32 +08:00
2026-09-14 16:11:00 +08:00
2026-09-15 11:17:23 +08:00
2026-09-19 14:01:21 +08:00
2026-09-15 11:21:00 +08:00
2026-09-13 06:16:59 +08:00
2026-09-08 19:16:35 +08:00
2026-09-08 19:16:35 +08:00
2026-09-14 23:50:35 +08:00
2026-09-21 07:04:04 +08:00