README.md 2.6 KB

普通聊天跨端历史一致性排查

基线:主分支 29e60b5(v0.4.17)。修复分支:codex/ordinary-chat-consistency。

已复现的问题

Web 收到 sessions.changed / cache.synced 时只刷新当前打开的会话。后台会话保留 historySynced=true,切回后跳过历史读取,继续展示已过时的中间结果。该判断来自 c17b5f1(2026-09-10),早于本次十路并发改动。

此外,SSE 会替换 Web 的会话状态对象。历史读取若仍持有请求前的对象,就会把结果写到旧对象中,页面内容和加载状态无法正确更新。历史请求或分页进行中收到的新补齐通知也可能被忽略。

修复

  • 按 Profile 和 session ID 标记对应缓存失效;后台会话保留可读内容,在再次选择时读取最新历史。
  • 补齐通知使用本地递增版本;请求期间的新通知合并为一次后续读取,不接受早于新通知的快照。
  • 历史读取和分页在异步返回后重新定位当前状态,合并现有流式尾部及已加载旧消息。
  • 历史请求采用单调递增编号,离开账号或被较新请求替代的结果不能修改新状态。
  • 不修改 Bot 调度、发送幂等规则或服务端数据库。

验证结果

tests/client/chatCrossClientSync.test.ts 的 4 个新增场景在原主线代码上全部失败(另外 12 项原测试通过),修复后通过。对照期间仅临时替换独立 worktree 的 Web store 文件,并在 finally 恢复修复版本。

新增场景:后台会话补齐后重新进入;补齐通知与迟到快照交错;SSE 替换状态期间合并历史并保留流式回复;分页期间补齐且保留旧消息。

相关 10 个测试文件共 125 项全部通过,npm run typecheck 通过。执行:

bash docs/verification/2026-09-14-ordinary-chat-consistency/verify.sh

原主线失败记录见 baseline.txt,修复后结果见 results.txt。

线上对照范围

沿用用户先前提供的服务与账号,只读抽查最近两条普通聊天。分别包含 68 条和 2 条记录;Web 本地历史接口与原始历史接口的角色和正文逐条一致。部分投影消息的 ID 与原始数据库 ID 不同,但此次对照中正文相同。登录会话已退出,原始业务数据仅保存在权限受限的临时目录,没有提交到仓库。

用户尚未指定实际出现差异的会话,因此以上抽查不能证明所有会话均无差异,也未在用户 iPhone 上核对其缓存。本次仅修改已复现的 Web 问题,iOS 代码未修改;未合并或部署此修复。