Files
MailUI4Agents/docs
JianFeeeee fffe6bf63a docs(欠账): 登记 read_inbox 吞掉在途邮件(压测后实测复现 3/3)
## 现象(实测,不是推演)

给 pi 发一封邮件 ⇒ 库里 `status` 变 `read`(投递后 **10~13ms**),
而**桥的日志里那封 mail_id 一次都没出现** ⇒ 没起会话、没人回信。

  读数:`mail_reads.read_at - mails.created_at = 0.013s`
        桥日志提及次数 = 0/3(连发三封,三封全中)
  发件人视角 = 「信发出去了,然后没声了」

## 机制:两件事各自都对,合起来丢信

① `4175c0b` 把「投递即标已读」做成一个动作(`markDelivered`),
   治的是「桥重启 → 重投 → 回声」;`catchUp` 按 `status=unread` 捞。
② `read_inbox` **读完自动标已读**(README 明写),而它按 inbox 取信,
   **不区分「这封是不是正在等派发」**。

⇒ 任何一次 `read_inbox`(不论模型为什么调)都会把**当时还在 unread 队列里**
的信全部连带标掉,其中包含**这一轮刚投递、还没轮到起 worker** 的那封。
它随后既不在 unread 里(捞不到)、也不在 `deliveredMails` 里(还没投递)
⇒ **静默消失**。

## ★ 与 4175c0b 修的不是同一件事

  那条治的是「**投过之后**没标已读 ⇒ 重投回声」
  这条是「**投递之前**就被别的路径标已读 ⇒ 投不出去」
两条方向相反,却落到同一条 SQL 上。

## 放大条件

worker 池越小越容易撞(`AGENTMAIL_MAX_WORKERS` 默认 3,
实测同一时刻 4 个 worker 在跑)。池满时信在队列里等,
**等待窗口正是被 read_inbox 扫掉的窗口**。

## 修法方向(未实施,等人定)

`GetInbox` 侧只标「本会话已投递」的信;或桥侧投递时先落 `deliveredMails`
再让模型读得到 —— **后者与 4175c0b 的「投递即标已读」直接冲突,不能两边都要**。
2026-09-28 10:28:21 +08:00
..