docs(归档): 把三轮结论与待人决策项落进仓库 —— 邮件会被压缩,这些不能只存在于往来里
归档回信可达性缺陷已修(e78888b / 2b77b17 / a3ca64b,均未 push),
但收尾全部需要人拍板。与其让结论烂在邮件线程里,不如落一份可交接的记录:
改了什么、判据是什么、哪些刻意没做、哪些仍未定位、以及四处待决。
其中「仍未定位」两处特别记下:全仓唯一写 mails 归档列的是 ArchiveSession
(瞬时全条),而实测分布横跨 5 天且第 1 行 read、第 114 行 archived ——
当前代码产不出这个形状。与其猜,不如把读数和「我查过什么」留下。
This commit is contained in:
60
docs/reviews/archive-status-fix-2026-09-28.md
Normal file
60
docs/reviews/archive-status-fix-2026-09-28.md
Normal file
@ -0,0 +1,60 @@
|
||||
# [探针] 归档会话回信可达性 —— 缺陷已修,等待人决策
|
||||
|
||||
**状态**:代码已改完并自验通过;**未 push、未部署、未动任何生产数据**。
|
||||
下一步全部需要人拍板,故停在这里等一句话。
|
||||
|
||||
## 一句话结论
|
||||
|
||||
「归档后不可见」这条契约被 `reply_to` / `permission/request` / 平台会话 adopt 三条路绕过;
|
||||
成因是 `TouchSession` 顺手把 `sessions.status` 写回 `active`,而「不可见」的两条判据
|
||||
分居 `sessions.status` 与 `mails.status` 两张表。已按**不变量**收口,不是逐个堵入口。
|
||||
|
||||
## 三个 commit(都在本地,未 push)
|
||||
|
||||
| commit | 内容 |
|
||||
|---|---|
|
||||
| `e78888b` | `TouchSession` 只写 `updated_at`;`EnsureSessionOpen` 成为三个建邮件函数的共同前置;`reply_to` 恢复 404;`permission/request` 补参与方判据;**adopt 路径第四个入口**;不变量判据 |
|
||||
| `2b77b17` | `MarkMailRead` 补 `AND status <> 'archived'`(反向洞,pi 复核时发现) |
|
||||
| `a3ca64b` | `DecidePermission` 补同一处守卫(pi §五);修正我在 `e78888b` 漏落的参与方误用(会把管理员挡在决策门外) |
|
||||
|
||||
改动面:5 个文件、+505/-4,全部在 `/home/program/agentmail` 内。
|
||||
|
||||
## 判据:8 条,且都验过「去掉修复就转红」
|
||||
|
||||
`server/internal/repo/session_status_invariant_test.go`,核心是不变量:
|
||||
|
||||
> 对任意 `session_id`:`sessions.status='archived'` ⟹ 该会话全部邮件 archived
|
||||
|
||||
不写成「某条路径返回 404」是因为入口会变(今天三个、明天可能第四个),
|
||||
而**两个能写那两张表的入口一个都不能分叉**,是由构造保证的。
|
||||
|
||||
每条都实测过回退修复即转红,不是「改完就绿」的装饰。
|
||||
|
||||
## 已确认的边界(都经生产库读数复核)
|
||||
|
||||
- **修好的**:不再新增分叉。四条复活路径(reply_to / permission / adopt / 反向改写两处)全堵。
|
||||
- **刻意没做的**:存量数据一条没动。`reply_to` 那 9 条的成因确证,清理动作可从成因推出;
|
||||
但要等**先部署**,否则旧代码会继续造新的。
|
||||
- **明确不要做的**:不要按「反向破坏」去清那 424 封 `read` —— pi 的更正确认,
|
||||
且我补的读数显示**主体是回填前的真实已读事实**,清了会破坏 `mail_reads`。
|
||||
- **仍未定位、不猜的**:两处
|
||||
① 那两条大线索(268/463 封)上零星 `archived` 邮件的**写入方** —— 全仓唯一写该列的
|
||||
是 `ArchiveSession`(瞬时全条),而实测分布横跨 5 天、第 1 行是 `read` 而第 114 行
|
||||
`archived`,**当前代码产不出这个形状**;
|
||||
② 38 封无 `mail_reads` 的行级 `read`,同样无机制可解释。
|
||||
|
||||
## 需要人决定的四件事
|
||||
|
||||
1. **推不推**这三个 commit(我没 push)。
|
||||
2. **部不部署**,以及谁执行。
|
||||
3. **存量 9 条**清不清(压测垃圾整条归档;真实对话那两条只动 `sessions` 行、
|
||||
碰都不碰 `mails` 行)。按 pi 与我一致的顺序:部署 → 重数签名 → 才清。
|
||||
4. `docs/DEBTS.json` 里 `archive-session-filter-partial`(`FindSessionByAddress`
|
||||
缺归档过滤,补上会把重复归档从 200 变 404,属行为变更)**仍未提交** ——
|
||||
那文件与另一并行会话的改动混在一起,我不愿夹带。
|
||||
|
||||
## 顺带发现
|
||||
|
||||
工作区**无跨会话互斥**:本轮 `server/` 有另一并行会话同时在改 `ratelimit*.go`
|
||||
及其两个新测试文件。那几处我全程未碰、未纳入我的 commit。
|
||||
(DEBTS 里 `shared-workspace-unserialized-deploy` 已登记此风险。)
|
||||
Reference in New Issue
Block a user