Skip to content

[Desktop/Chat][P2] 低版本快照不得回退主会话控制状态与轮次状态 #83

Description

@jiayuqi7813

触发与范围

桌面聊天同一 thread 的旧 REST 快照在新 SSE snapshot 后返回时,原 mergeConversationView 保留较新消息正文,却直接接纳旧快照的 state、queue、watermark 等控制字段;同一 turn 的旧记录也覆盖最新状态。界面可同时显示完成的正文和回退的 running/待审批状态。

按 P2 主会话状态一致性追踪。2026-09-30 的原 hook/merge 隔离 fixture 已确认逻辑;没有真实 REST/SSE、桌面 profile、审批、工具或权限操作,没有消息/引用丢失或生产事故证据。范围仅为 desktop-owned 主聊天的快照 admission 与合并,共享 Web 文件用于定位,不要求本轮修改 Web 或后端。

原模块验证与保护对照

fixture 原样转译并运行 useConversation、mergeConversationView、stream reducer 与加载辅助逻辑,使用 React test renderer。apiFetch、EventSource、timer 和分页响应全为内存合成对象,无真实网络、存储、账号或 Provider;未使用的 receipt/命令依赖一旦调用就抛错。

  • 同 generation 的新完成快照先进入 hook;挂载时仍 pending 的旧 REST 随后完成。watermark 回退、running_turn_id 与旧 pending/queue 恢复,turn 的 completed 状态变回 running。
  • 同 message ID 的最新正文 stream_seq 较高,原 mergeMessageLists 正确保留完整新正文。这不是消息内容被旧响应覆盖。
  • 原纯 merge 另验证低 generation 的 next:current_generation 回退,但已知 retry/supersession 仍过滤旧分支正文、保留当前分支。
  • 顺序新 snapshot 正常推进;切换到另一 thread 后,旧 REST 和旧 EventSource snapshot 都被原归属 guard 拒绝。

完整输入、合并对象、原请求与源码哈希只保存在本地 ignored artifact;控制状态回退不能写成真实批准、重新执行或删除数据。

根因与影响边界

合并逻辑判断 nextGen > prevGen 时清理旧分支,没有拒绝 nextGen 更低或同 generation 低水位的快照。最终 ...next 覆盖控制字段,mergeTurnLists 对同 turn ID 也直接采用 incoming。消息 seq 保护解决正文新旧,却没有让整体快照状态保持一致。

这会使主聊天呈现过时的运行、待审批和队列信息;UI 用户决定可能基于旧状态。真实命令结果和授权仍需服务独立判断,本轮没有提交任何决定,不能把状态错误升级为权限或执行事故。现有跨 thread/旧流、正文和 supersession 保护均应保留。

桌面优化与验收

  • 主聊天快照用明确 thread、generation 与 watermark/等价版本判定是否可成为当前控制状态;低版本快照不能接管 state/queue/turn 状态。
  • 历史分页可补充正文和引用,控制状态与当前有效分支按独立的已确认版本合并,避免用旧页整体替换。
  • 重跑原 hook 的乱序序列:已完成状态、当前 generation、已解决的待审项与队列不回退,较新正文仍保留。顺序推进、跨 thread、旧流、重复增量和 supersession 对照继续通过。
  • 在可弃置桌面数据环境补真实延迟响应验收,仅用合成内容与 recorder;未完成前不宣称端到端事故或已修复。

去重与源码

#80 是侧栏整列表 refresh;本条是主 view 的控制状态/turn/generation 合并,使用不同模块路径和验收对象。#38 的停止结果解释、#67 的审批决定投递也不替代此快照保护。关联 Epic #31。

固定公开代码供导航,当前源文件哈希为本次证据:useConversation / mergeConversationView、stream reducer。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions