You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
英文摘要:After a hot reload of the desktop profile (cordis.patch.yml edit), the session sidebar
silently drops every stored session whose log was not written after the reload — across all
workspaces. Live sessions keep showing. A full app restart restores the list, and the session
logs are intact, so this is runtime state, not persistence.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Bug: 侧边栏在 profile 热重载后丢掉所有"冷"会话(重启才恢复)
dsh --version)1. 现象
修改
cordis.patch.yml触发 profile 热重载的瞬间,侧边栏的整个工作区列表与会话列表一起消失,界面上只剩当时正在看的那一个会话;重载完成后,只有「日志在该时刻之后被写过」的会话重新出现(本例最终 3 条),两个工作区的历史会话全部缺失。没有报错、没有占位行、没有「加载中」。截图时(12:26)的实际渲染:
默认工作区中国企业终止与姆巴佩合作(刚刚)、DeepSeek 底层 GPU 指令集…(5 分钟)、排查并恢复消失的会话(10 分钟)iForce409机台卡顿原因分析即:所有 12:14:48 之前写入过日志的会话都不见了,两个工作区同时中招。
12:15 之后新建/继续的会话(上面 3 条)正常显示。
关闭 DSH 重新打开后,全部会话恢复显示(用户已确认)。这就是关键判据:数据没丢,是运行期状态不对。
2. 触发条件(高度相关的时间线)
sanitizeProfile规则把 profile patch 改名备份~/.dsh/profiles/desktop/cordis.patch.yml.bak-20261027-115410、…bak-privacy-20261027-120930、…bak-global-20261027-121442;~/.dsh/AGENTS.md.bak-20261027-121442cordis.patch.yml被修改(新增一条id: system-prompt的personaSuffix补丁),触发 profile 热重载~/.dsh/sessions/**/session.v4.jsonl.zstd、~/.dsh/storages/session_projcache/sessions/*.json的 mtime 均为 12:14:48规律:只有"日志在 12:14:48 之后被写过"的会话留在列表里。 12:14:48 之后没有任何写入的会话,全部从 UI 消失。
3. 数据完整性核查(排除"数据损坏/丢失")
在故障当下(12:24 前后)只读检查:
~/.dsh/sessions/下 10 个session.v4.jsonl.zstd全部存在、可解压、header 完整(id/cwd/createdAt一致),最大 1.4 MB、事件数 18–1286,无截断;~/.dsh/storages/session_projcache/sessions/有对应 10 份投影缓存,version: 7、formatVersion: 4,与日志seq对齐;~/.dsh/storages/workspace.json当时记账正常:默认工作区8 条 +iForce41 条;归档集合 1 条(session-b8e428f2…,属正常归档);结论:持久层完全健康,问题在宿主/客户端的会话列表装配。
4. 代码层面的定位线索
前端对缺失的会话是静默丢弃,所以宿主侧只要少给一份 summary,整行就凭空消失,用户看不到任何异常:
@deepseek-ai/dsh-client-ui-workspace(lib/client.js)deriveFlat()(约 1146 行):sessionIds.flatMap(id => { const session = list.byId[id]; return session !== undefined && sessionVisible(...) ? [session] : []; })visibleSessionIds()(约 1129 行):list.ids.filter(id => { const s = list.byId[id]; return s !== undefined && ... })list.byId[id]没有 summary 的 id,永远不会渲染(没有占位/骨架行,也没有"hydrating"状态)。宿主侧会话列表依赖"冷会话 summary 的 hydration"(
@deepseek-ai/dsh-session-query的SessionCorpus:listSessions()/projectMany(),以及@deepseek-ai/dsh-session-projection-cache)。热重载会重挂插件树;从现象看,重挂后只有 live 会话进了列表,已落盘的冷会话没有被重新枚举/水合,直到进程重启才恢复。@deepseek-ai/dsh-workspace的WorkspaceRegistry有replaceHeaderIndex(await listStoredHeaders())(Service.init里在table.size > 0时执行)与reportFilteredCandidates()。可疑点:热重载路径是否走了同样的重枚举;若 header 索引为空,candidateMatches()会让成员从sessionIds里被过滤,并在下一次mutate()时永久 prune(有丢索引的风险,比显示问题更严重)。5. 建议的修复/加固方向
replaceHeaderIndex(await listStoredHeaders())+ 重建所有冷会话的 summary,再对外发workspace/sessions基线;workspace.sessionIds数量时给出可见提示;mutate()的 prune 加保护:当 header 索引为空/未就绪时禁止 prune(现有candidateMatches对"索引未就绪"和"确实不属于"返回同一个false,语义应区分);reportFilteredCandidates()的告警同时接到"列表结果比记账少"这条路径上,便于用户与支持人员定位;workspace.json的sessionIds未被 prune。6. 供开发核对的现场数据(机器:本机
~/.dsh)C:\Users\john\Documents\deepseek-harness\default-workspace、D:\prj\iForce4workspace.json:默认工作区8 条(含 1 条归档)、iForce41 条;其中ac99dbfd-b2b3-4c37-8969-55f9947da68d从未被挂进工作区(另一独立小问题:该会话只能在"未分组"里出现)sessionIds被 prune7. 临时规避
cordis.patch.yml/ 插件配置后,主动重启一次 DSH,不要只依赖热重载;~/.dsh/storages/workspace.json与会话目录再操作。All reactions