Skip to content

[Bug] 页面刷新后面板 dock 停止更新——新的 panel:true 围栏被持久化重放屏障静默拒绝 #4

Description

@letff

摘要

页面刷新后,会话面板 dock 冻结在之前渲染的内容上。之后发送的 panel:true dsh-ui 围栏被静默丢弃:dock 不更新,浏览器控制台也没有任何报错或警告。清除插件的持久化状态(localStorage.removeItem('dsh.genui.panel'))后更新恢复,但下次刷新又复发。

环境

项目
dsh-genui 0.8.0(安装自 github:omdsh-dev/dsh-genui#main,client.js 构建于 2026-08-14)
DSH 运行时 @deepseek-ai/dsh 0.1.0-rc.6
浏览器 Google Chrome 151.0.7922.109(正式版本,64 位,Stable)
操作系统 Windows 11 21H2(Build 22000.2538);DSH 服务端运行于 WSL2(Ubuntu 22.04)
安装方式 profile 依赖 "@omdsh-dev/dsh-genui": "github:omdsh-dev/dsh-genui#main"

复现步骤

  1. 在会话中发送一个 panel:truedsh-ui 围栏(任意 spec,如 badge + 按钮)。dock 正常渲染。✅
  2. 再发送一个内容不同的 panel:true 围栏。dock 更新为第二个内容。✅
  3. 刷新页面(F5)。
  4. 刷新后发送第三个内容不同的 panel:true 围栏。dock 仍显示第 2 步的内容。 ❌ 控制台无任何输出。
  5. 验证诊断的工作区:DevTools 执行 localStorage.removeItem('dsh.genui.panel') 后刷新,新围栏又能更新 dock——但下次刷新再次失效,循环往复。

期望行为

页面刷新后发送的新 panel:true 围栏应正常替换 dock 内容(与不刷新时行为一致)。

实际行为

dock 停留在旧快照上。旧按钮仍能触发 [genui-action](旧 spec 仍然存活),而所有新 panel 围栏都被静默拒绝。无任何日志、无错误。

根因分析(已在 v0.8.0 client.js 代码中核实)

面板 store 在跨页面加载时启用了幂等/重放保护:

  • an()localStorage['dsh.genui.panel'] 恢复会话状态,并初始化 replayBarrier = 持久化的 maxSeenSeq
  • on() 拒绝任何满足 t.order[0] <= e.replayBarrier(以及 e.seen.has(sourceId))的操作——返回 null 即静默拒绝。
  • order[0] 是消息序号,由 DOM 通道(Bn()i()zn())从宿主的 [data-chat-anchor-key] 属性推导。
  • 刷新后历史消息重放能通过屏障(幂等,正常),但新消息也无法通过:其 anchor 序号没有超过恢复的屏障(或跨页面会话不满足单调递增比较)。cn() 返回 "idempotent"/"blocked",围栏被丢弃且零诊断。
  • 清除 localStorage 键会将 replayBarrier 重置为 -1,这正是第 5 步能恢复更新的原因——证实持久化屏障就是拦截点。

#1 属于同一类问题(DOM/fence 通道中静默 return、无诊断日志)。

影响

任何刷新过页面的用户都会得到冻结的面板 dock。唯一临时办法是手动清 localStorage,且每次刷新后都会再次失效——对刷新过的会话来说实际上是永久故障。

建议修复(任一)

  1. 屏障语义replayBarrier 不应拒绝「严格新于当前快照」的操作;排序应改用全局单调递增的消息 id(如服务端消息序号),而非 DOM anchor 序号。
  2. 按页面会话隔离:新页面会话开始时重置 replayBarrier(或把屏障存到 sessionStorage 而非 localStorage),避免一次刷新毒化后续所有更新。
  3. 诊断(最小改动):在 on()/DOM 通道的每个静默拒绝路径加 console.warn(与 MacOS 下 Chrome 正常渲染但是 Safari JS报错无法正常使用 #1 的诉求一致),至少让这类失败可观测。

关联

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions