dsh-session-recovery:从裸磁盘恢复 DSH 会话与 memory

前言

DeepSeek Harness(DSH)会保存会话日志和 memory 数据。如果 session.jsonl.zstd 被误删、被覆盖或文件本身损坏,普通的文件恢复往往只能拿到零散内容,难以直接用于恢复会话。dsh-session-recovery 的思路是从裸磁盘开始读取,定位可识别的 zstd 帧和 SQLite 数据,再把可恢复内容整理成 DSH 可校验、可继续使用的会话文件。

这是什么

dsh-session-recovery 是一个 DSH 恢复工具,仓库地址为 https://github.com/Coprexist/dsh-session-recovery,许可证为 MIT。

它主要做两件事:

  1. 从裸磁盘恢复 DSH 会话文件 session.jsonl.zstd
  2. 从裸磁盘恢复 memory 数据库 memory.db

仓库本身是一套恢复脚本和手动恢复说明,也可以作为 dsh plugin 安装到 web UI,提供 /session-repair 命令。

核心功能

恢复 memory.db

脚本会按 SQLite 的 SQLite format 3 头部在裸磁盘上定位 memory.db,导出相应数据窗口,并使用 SQLite 的 .recover 机制抢救可读行。遇到损坏页时会跳过,尽量保留仍可读取的数据。

恢复会话日志

脚本会在裸磁盘上扫描 zstd frame magic 0xFD2FB528,按磁盘偏移对帧做聚类,在 turn 重置处拆分不同会话,最后重建官方格式的 session.jsonl.zstd

修复重建后的会话

重建出来的日志可能无法直接通过 DSH 校验。工具会自动修复以下问题:

  • 重新整理 seq,使其连续。
  • 深度修复 sourceEventSeqsmessageSeqs
  • 规范化 surfaceOp

如果会话仍无法 resume,repair-session.js 或 web UI 的 /session-repair 命令会重放 DSH 的 inbox、surface、wire 规则,对文件做进一步修复。

只读读取裸磁盘

脚本只读块设备,并把恢复结果写入指定目录。原始磁盘内容不会被修改。

安装与启用

如果作为 dsh plugin 安装,可以从本地仓库路径添加:

dsh plugin --profile web add file:/path/to/dsh-session-recovery
systemctl restart dsh-web

其中 file:/path/to/dsh-session-recovery 是本地路径占位符,需要替换为实际路径。

安装或恢复替换后,需要重启 dsh-web

典型用法

下面是按顺序执行的恢复流程。

1、先停止会写磁盘的服务

先停掉可能继续写入 DSH 数据的服务,避免恢复过程中数据状态变化:

systemctl stop dsh-web

2、恢复 SQLite memory

从块设备恢复 memory.db

node scripts/recover-memory.js /dev/<dev> /tmp/recovered/

这一步会把可读的 SQLite 数据恢复到 /tmp/recovered/ 目录。

3、扫描裸磁盘中的 zstd 会话帧

扫描裸磁盘,把找到的 zstd 会话帧写入事件流:

node scripts/scan-zstd.js /dev/<dev> > /tmp/session-events.jsonl

4、拆分到不同会话

扫描结果通常是多个会话混合在一起。脚本会按会话拆分:

node scripts/split-sessions.js /tmp/session-events.jsonl 2026-08-16T07:05:06Z

5、重建官方格式会话文件

使用 scripts/rebuild-session.js 重建官方格式的 session.jsonl.zstd。需要提供输入、会话 ID、创建时间、工作目录和输出目录等信息:

node scripts/rebuild-session.js \
  --input <input-jsonl> \
  --id <session-id> \
  --created-at <created-at> \
  --cwd <workspace-dir> \
  --out-dir <out-dir>

6、校验或修复重建后的会话

先做一次 dry-run,检查修复内容:

node scripts/repair-session.js <session.jsonl.zstd> --dry-run

确认没有问题后执行修复:

node scripts/repair-session.js <session.jsonl.zstd>

修复后会产生 session.jsonl.zstd.repaired 文件和备份文件。检查 .repaired 内容和备份后,再决定是否替换原文件:

cp <session.jsonl.zstd>.repaired <session.jsonl.zstd>

7、在 web UI 中使用 /session-repair

安装插件后,可以在任意会话中执行:

/session-repair --dry-run

分析当前会话,不写文件。

/session-repair <session-id-or-path>

执行修复,默认写入 .repaired 文件和备份。

/session-repair --apply <id>

在修复后替换原始文件。注意:--apply 对正在运行该命令的 live session 会被拒绝,需要从另一个会话执行。

适用场景与注意

适合以下场景:

  1. session.jsonl.zstd 被删除或损坏,需要尽量恢复可读内容。
  2. memory.db 损坏,需要抢救其中的 SQLite 数据。
  3. 重建后的会话无法 resume,需要按 DSH 规则做修复。

使用前注意:

  1. 需要 Node 24+,并依赖 node:sqlitenode:zlib
  2. 脚本只读块设备,恢复文件写入用户指定目录,不修改原始磁盘。
  3. 插件以当前 dsh 进程权限运行,安装前应检查源码和许可证。
  4. 使用 --apply 会覆盖原始会话文件,执行前应先检查 .repaired 文件和备份。
  5. 插件变更或恢复文件替换后,应重启 dsh-web

结尾

dsh-session-recovery 提供了一条从裸磁盘读取、重建、修复 DSH 会话与 memory 的路径。适合在常规文件恢复不可用、但仍能从块设备上找到 zstd 帧或 SQLite 数据时使用。

仓库地址:

https://github.com/Coprexist/dsh-session-recovery

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜