2.7 KiB
2.7 KiB
会话切换后表单不渲染修复计划
目标
修复频繁切换会话后“表单”角标已有待处理数量、但消息区未渲染表单的问题,确保切回会话后无需 F5 即可看到并操作待处理表单。
验收标准
- 频繁切换包含待处理表单和普通消息的多个会话后,当前会话的表单立即渲染。
- 旧会话异步请求晚到时,不得覆盖当前会话的消息或表单派生状态。
- 表单角标数量与消息区实际可见待处理表单保持一致。
- 页面刷新后的恢复行为与 SPA 内切换行为一致。
- 新增竞态回归测试,并通过相关前端测试与静态检查。
工作步骤
- [DONE] 定位表单计数与消息渲染的会话切换链路
- [DONE] 编写可复现竞态的回归测试
- [DONE] 运行回归测试并确认当前实现失败
- [DONE] 修复会话切换时的表单状态同步与过期请求覆盖
- [DONE] 运行前端相关测试并确认回归通过
- [IN_PROGRESS] 执行静态检查并审查影响面
- [TODO] 使用真实浏览器验证频繁切换无需刷新
关键假设
- 后端数据完整,因为 F5 后同一待处理表单能够显示。
- 缺陷位于前端会话切换、消息加载或表单派生渲染状态的同步路径。
- 修复应优先采用请求归属校验或会话级状态隔离,不依赖强制刷新。
已确认根因与修复边界
beginSessionSwitch()在切换请求刚发起、DOM 尚未替换时提前执行renderEpoch++,会永久取消当前会话尚未完成的历史消息批次;表单若位于该批次,便形成“缓存角标有 1、DOM 卡片为 0”。session_info对msg.sessionId === currentSessionId无条件放行,同一会话旧requestId响应可能覆盖新加载。- 服务端
session_history_chunk未回传requestId,前端历史块也只按sessionId判断;A→B→A时旧 A 尾块可能误完成新 A 加载。 - 修复同时覆盖:渲染代次只在真实 DOM 提交时推进;加载响应按
sessionId + requestId归属;历史分块透传请求 ID。
风险
- 消息加载、流式事件和表单计数可能来自不同异步通道,需要避免只修复其中一条路径。
- 仓库由多个会话共享,不能覆盖现有
.planning/.active_plan、Trellis 当前任务或无关工作树改动。
错误记录
| 错误 | 尝试 | 处理 |
|---|---|---|
| 完整回归的旧静态断言要求保留 requestless idle 分支原字符串 | 1 | 将兼容分支拆为具名布尔量,保留语义和可审查契约后重跑 |
codebase-memory-mcp detect_changes 返回 Transport closed |
1 | 不重复同一失败调用,降级为本地 git diff/rg/语法检查和独立审查代理 |