fix(chat): make the server the only writer of session messages
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled

List GET no longer ships transcripts; consult appends questions after reserve and ignores client history so dual-tab last-write-wins cannot erase messages.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-01 19:51:13 +08:00
parent b98777aa5c
commit b6989c3eea
23 changed files with 871 additions and 150 deletions
+16
View File
@@ -7118,3 +7118,19 @@
- 相关记录:BUG-456、BUG-460、BUG-462
- 复发自:无(授权策略变更,不是同一实现回归)
- 修复版本:待发布
## BUG-464 | 客户端全量覆盖 chat_sessions.messages 导致列表膨胀、写满失败与双标签页丢消息
- 状态:resolved
- 首次发现:2026-09-01
- 最近更新:2026-09-01
- 影响面:`GET /api/sessions``GET/PATCH /api/sessions/[id]``POST /api/consult``append_consultation_question`、首页会话列表与对话区
- 用户现象:会话一多首页变慢;对话变长后发问提示“问题保存失败”;两个标签页各问一句,刷新后只剩后写的那一轮;中止或失败的半截回答会留下可刷新的记录。
- 触发条件:打开带多段对话的账户首页;长会话继续发问;同一会话在两个标签页交替发送;停止生成或 run.failed 后刷新。
- 根因:`chat_sessions.messages` 由浏览器整包 PATCH 覆盖,列表 GET 又把全部消息一次性带回。服务端结算已经 append assistant,客户端再 last-write-wins 覆盖。列表无分页、无上限。
- 修复:列表 GET 去掉 `messages`;详情 GET 按会话加载。咨询在 reserve 成功后由 `append_consultation_question` 写入用户提问,满 200 条或 200,000 字符返回 `session_full` 并退回预扣。consult 忽略请求体 `history`,改读库内最近 12 条。客户端 `persistSession` 只写元数据;旧 bundle 的 `messages` PATCH 接受并忽略。中止与失败的部分回答只留在当前页。
- 验证:合同测试锁列表/详情拆分、伪造 history 不进模型上下文、PATCH 忽略 messages、SQL 幂等与 `session_full`、双 request_id 可叠加。`./node_modules/.bin/tsc --noEmit``npm test``npm run test:db` 必须通过。
- 防复发:不得把 `messages` 加回列表 GET 或校正 agent select。不得恢复客户端 transcript PATCH。consult 不得再读取 `parsed.data.history``append_consultation_question` 必须保持 advisory lock、request_id 幂等与满员拒绝。
- 相关记录:无
- 复发自:无
- 修复版本:待发布