DeepSeek Harness 更新后旧会话打不开怎么办?dsh 会话格式迁移、版本兼容与备份说明
DeepSeek Harness 更新后旧会话打不开,根因通常是「会话格式版本」变了,而不是会话数据被删除。会话格式是一个独立于包版本的整数;官方设计是引入新格式时不重写已发布数据,旧会话在读取时按迁移链转换,源文件保持不变(来源)。
本文只讲「保留但读不了」的迁移与兼容问题。如果你担心的是更新会不会丢配置和数据,结论是保留,见《dsh 更新会不会丢数据》;如果是会话日志本身损坏(而非版本不兼容),见《会话日志损坏修复》。
更新后旧会话为什么打不开:会话格式版本不等于包版本
DeepSeek Harness 里「会话格式版本」和「dsh 版本号」是两个独立的概念,升级 dsh 到新版本可能同时把会话格式推进一级,这就是旧会话打不开的直接原因。 官方文档明确要求区分会话格式整数与包发布版本、SQLite schema 版本、投影单元版本、协议包装版本——它们各管各的,互不等价(来源)。
把这几类版本摆在一起,看各自管什么:
| 版本类型 | 管什么 | 什么时候变 |
|---|---|---|
| 包发布版本 | dsh 的发布版本号 | 每次发布 |
| 会话格式版本 | 会话日志的结构 | 表头、事件信封、核心事件语义或面重建的结构性变更 |
| SQLite schema 版本 | 存储表结构 | 存储结构变更 |
| 投影单元版本 | 投影单元结构 | 单元结构变更 |
| 协议包装版本 | 协议包装结构 | 包装结构变更 |
什么时候会推进格式版本?只有对表头、事件信封、核心事件语义或面重建做结构性变更时才递增;向后兼容的改动可以通过新增确认留在当前版本,不必升版本。所以并不是每次更新都会动旧会话,只有破坏性结构变更才需要迁移。
官方怎么保证旧会话兼容:不重写数据 + 读取时迁移
DeepSeek Harness 的兼容策略核心是一句话:引入新格式时「不重写已发布数据」,迁移发生在读取侧而不是就地改写。 具体有六个设计点:
- 历史格式全部留档 — 每一个历史会话格式都有独立的格式文档,变更记录用仓库内的快照逐次确认转换,覆盖到当前写入版本之前的每一个整数。
- 读取时迁移,源头不动 — 历史读取打开可以返回迁移后的内存产物而不写入;写入打开只会发布最终的当前后继再追加。源文件路径、字节与 inode 保持不变(来源)。
- 不做降级回退 — 选中了较新或无效的会话代号时,不能回退到前驱版本,避免读到半成品。
- 严格恢复校验 — 通过
sessionFormatCatalog.createRestore(header, { recovery: 'strict', validation: 'current' })逐行校验,把物理解码、完整迁移链与当前会话校验都跑一遍。 - 迁移链是相邻逐级,不是一步到位 — 从格式 N 到当前写入版本,按 N→N+1→… 逐级转换,而不是跨级直接跳。
- 迁移失败不会污染源文件 — 因为转换发生在读取侧,读取失败时源文件仍保持原样,重试或用旧版本再读都不会把文件写坏。
更新前怎么判断,更新后旧会话怎么处理
判断分两步:更新前先看目标版本有没有破坏性变更并备份,更新后先用只读方式打开旧会话确认可迁移。 按下面 6 步操作:
- 更新前确认版本线 — 用
dsh --version记录当前版本,对照目标版本说明里是否提到会话 / 存储格式的破坏性变更。 - 备份会话目录 — 0.1.0-rc.8 重构 SQLite 后端后存储结构不兼容,官方提示升级前先备份
~/.dsh数据(来源):bashcp -r ~/.dsh/sessions ~/.dsh-sessions-backup - 更新后只读打开旧会话 — 迁移在读取侧完成,先确认能正常打开、内容完整,再继续追加新消息;这样即便迁移有问题,源文件仍是干净的。
- 打开失败时保留原文件 — 不要覆盖、重命名或删除打不开的会话文件,用对应旧版本读取,或等迁移链修复后重试;原始数据是最后的兜底。
- 用会话相关插件前先核对版本 — 参与会话事件声明的插件需要与目标格式兼容,先去 DSH Plugin Hub 的已安装列表核对是否有可更新版本,确认兼容后再启用。
- 最后只读核对源文件是否被改写 — 打开过旧会话后,执行
ls -l ~/.dsh/sessions(Windows 用dir)。预期:旧会话文件仍在原路径、时间戳与更新前一致,印证迁移没有就地改写源文件。
更新后处理旧会话的注意事项
- 备份先于更新 — 跨破坏性变更时,备份是唯一能保证可回退的手段,别等打不开才想起备份。
- 迁移是「读」的行为 — 旧会话文件不会被就地改写,看到打不开时先怀疑读取链路与版本兼容,而不是文件损坏。
- 别混淆两类版本 — DeepSeek插件 版本、dsh 包版本、会话格式版本各有各的语义,升级前分开核对。
- 善用官方留档 — 官方为每个历史格式保留文档与快照,遇到兼容疑问时以格式文档和变更记录为准,不要凭猜测手改会话文件。
- 备份放到仓库外 — 备份目录别放在会被更新或清理覆盖的位置。预期:真出问题时,备份仍是干净可用的那一份。
- 手边留一份能读旧格式的版本 — 跨破坏性变更时保留一个旧版本。预期:旧会话多一条读取路径兜底,不必现场找工具。
插件是另一条独立链路:更新会话相关 DSH plugin 时,用 DSH Plugin Hub 的已安装列表先看版本与「可更新」徽标,确认兼容目标版本后再更新,避免旧会话因插件事件声明变化而读不了。

来源:DeepSeek Harness Cookbook - adding a Session log format version(官方仓库)、Session Persistence Event Catalog、v0.1.0-rc.8 Release
常见问题
DeepSeek Harness 更新后旧会话打不开通常不是数据丢失,而是会话格式版本变化。官方设计是引入新格式时不重写已发布数据,旧会话文件保留在原处,读取时按迁移链完成转换,所以原文件仍在,只是需要经过迁移才能被新版打开。
dsh 会话格式版本和 dsh 包版本不是一回事。会话格式是一个独立整数,区别于包发布版本、SQLite schema 版本、投影单元版本与协议包装版本;只有对表头、事件信封、核心事件语义或面重建做结构性变更时才递增,因此升级 dsh 可能同时带来新的会话格式。
更新 DeepSeek Harness 前建议备份会话数据,尤其跨破坏性变更时。0.1.0-rc.8 重构 SQLite 后端后存储数据结构不兼容,官方提示升级前先备份 ~/.dsh 数据;会话目录通常在 ~/.dsh/sessions,复制一份到仓库外即可。
更新后打不开的旧会话一般可以恢复,因为会话迁移是读取侧行为。旧会话文件的路径、字节与 inode 保持不变,可用对应历史格式读取或等待迁移完成;读取失败时保留原文件,不要覆盖、重命名或删除,以免丢掉唯一的原始数据。
在更新 DeepSeek Harness 前,先到 DSH Plugin Hub 核对会话相关插件是否已适配目标版本。参与会话事件声明的插件需要与目标格式兼容,确认兼容后再更新能减少旧会话读取异常;插件版本与会话格式版本要分开看。
相关术语
- Session format version(会话格式版本)
- Session format version 是 DeepSeek Harness 用来标识会话日志结构版本的整数,独立于包发布版本、SQLite schema 版本、投影单元版本与协议包装版本;只有对表头、事件信封、核心事件语义或面重建做结构性变更时才递增。— DeepSeek Harness Cookbook - adding a Session log format version
- Migration chain(迁移链)
- Migration chain 是 DeepSeek Harness 从历史会话格式逐级转换到当前格式的相邻转换链,每一步是 N→N+1 的显式迁移;读取旧会话时按这条链在内存中完成转换,源文件不被改写。— DeepSeek Harness Cookbook - adding a Session log format version
- SESSION_FORMAT_VERSION
- SESSION_FORMAT_VERSION 是 DeepSeek Harness 核心会话类型里声明当前写入格式的常量,它决定更新后新会话写入哪个格式版本,也决定历史会话需要迁移到哪一级。— DeepSeek Harness Cookbook - adding a Session log format version
- Session persistence catalog(会话持久化目录)
- Session persistence catalog 是 DeepSeek Harness 汇总全部持久化会话事件的目录,覆盖逻辑与物理表头、事件信封以及每一个插件声明合并,用于校验会话结构是否完整可读。— DeepSeek Harness Session Persistence Event Catalog