dsh-session-doctor:不打开会话也能定位坏事件

前言

DSH 把会话日志写成 session.vN.jsonl[.zstd],事件之间靠 turn / step 的嵌套和顺序维持可读性。一旦某个事件的坐标写错了——比如在没有打开 turn 的情况下写 tool/ptc-dispatch-start——整个会话在当前 reader 眼里就变成了 corrupt session,只会报一句「会话损坏」,不会告诉你是哪一条事件、哪一步出了问题。想自己翻文件定位,就得手工解压、逐行 parse。

下面介绍的 dsh-session-doctor 就是为这一类问题做的:它只读、不写,替你把违反 reader 检查规则的事件逐个点出来。它对应 deepseek-harness Discussions #11971、#11981、#11121 这一类生命周期问题的排查场景。

这是什么

dsh-session-doctor 是 aturzone 维护的 DSH 插件,分类为 admin-security,目录页显示星标 0,README 自己标注为「插件早期、使用 pre-release tag」。

它做的事情可以一句话概括:逐条解码 session.vN.jsonl[.zstd] 里的事件,重放当前 reader 生效的 turn/step/scope 规则,然后报出具体是哪个序号、哪种事件类型、哪条规则不再成立。全程只读,不会写入会话文件。

它能查到什么

README 列出的检查项有四类:

  1. turn/step 坐标完整性:turn/start / turn/end / step/start / step/end 的嵌套与顺序。
  2. 在同一个未结束的 turn 内 step 编号重新开始。
  3. turn/step 作用域内的事件被写到了作用域之外:request/header、request/context、tool/ptc-dispatch-start、tool/ptc-dispatch、assistant/message、tool/call、tool/result 的替换记录等。
  4. 行级损坏:非法 JSON、缺失 header、非事件行。

需要留意它的定位:这是一个「与当前 V4 reader 对齐的签名检测器」,不是完整的格式校验器。它不重新实现 message payload 校验、格式迁移,也不处理 zstd 之外的压缩 framing。所以它给出的结论是「这里违反了哪些规则」,而不是「这个文件格式上还对不对」。

安装

从 npm 安装(插件处于早期,用 next 这个预发布 tag):

dsh plugin --profile web add dsh-session-doctor@next

从 Git 仓库安装,命令会触发 package 的 prepare 构建:

dsh plugin --profile web add git+https://github.com/aturzone/dsh-session-doctor.git

package.json 里的 engines 限定 dsh >=0.2.2-rc.1 <0.3.0、node >=24.9.0,前者依赖 @deepseek-ai/cordis ^4.1.0,后者 @deepseek-ai/dsh-tools >=0.2.2-rc.1 <0.3.0。项目使用 zstd 解压,所以 Node 版本要求不低。许可证是 MIT。

作为 bundle 启用

装好之后 bundle 只往配置里插入一行插件声明。插件会注册一个面向模型调用的 session_doctor 工具,扫描 $DSH_HOME/sessions(也可以传 sessionsRoot 参数),返回和 CLI 相同的报告,同样是只读。

如果想在本地 checkout 上用覆盖文件做开发调试,README 给的做法是先写 overlay:

# overlay.yml
- insert:
    - id: session-doctor-dev
      name: /absolute/path/to/dsh-session-doctor/src/index.ts

然后带着 patch 启动:

pnpm dsh web --patch ./overlay.yml

这一步的意义是把源码路径直接挂进正在运行的 dsh,不必先打包发布。

当 CLI 用

不想走模型工具、只想在脚本里巡检一遍时,可以直接调命令行:

session-doctor [--home <DSH_HOME>] [--sessions-root <dir>] [--json] [--all-generations]

参数行为按 README 整理:

  1. 默认先找 $DSH_HOME/sessions,找不到再退回 ~/.dsh/sessions。
  2. 默认只检查每个会话里版本号最高的那个 canonical generation;加 --all-generations 会把保留下来的更早版本一起校验,比如 session.v3.jsonl 与 session.v4.jsonl 并存的情况。
  3. --sessions-root 既可以传会话根目录,也可以只传某一个 workspace bucket,例如 --sessions-root .../sessions/--my-project--。
  4. 退出码:0 干净、1 发现可疑 generation、2 用法或 I/O 出错。--json 打印结构化报告,便于接进别的脚本。

这些退出码可以直接当 CI 里的判定条件用。

输出长什么样

README 给的示例输出大概长这样:

session root: /home/me/.dsh/sessions
sessions: 12 scanned, 1 with reader-incompatible signatures

✗ --home-me-project--/session-8bc9…
  file: …/session.v4.jsonl.zstd
  events: 41, version: 4
  - seq 22 tool/ptc-dispatch-start: turn-scope: tool/ptc-dispatch-start outside an open turn
  - seq 23 tool/ptc-dispatch: turn-scope: tool/ptc-dispatch outside an open turn

报告会落到具体文件、事件总数、版本号和出问题的序号,拿到之后可以直接去对应位置看上下文。

适用场景与注意

适合这几类人:会遇到 corrupt session 报错、想自己定位而不是等上游修的 DSH 使用者;想审计一批历史会话是否适用当前 V4 reader 规则的维护者;想在 CI 里蹲住会话落盘格式变化的项目。

使用前需要注意三点。

  1. 插件以当前 dsh 进程的权限运行,安装前应当自己过一遍源码,确认 cordis.patch.yml 这类 patch 没有超出预期。许可证是 MIT,但「MIT」不等于「可以无脑装」。
  2. 它是检测器,不是修复工具。README 明确说目前没有 repair 或 quarantine 能力,报告给出缺陷之后,要不要把坏掉的 generation 挪走仍是人工决策。
  3. 规则对齐的是发布时的 V4 reader,future 格式版本(session-format-vN-to-vN+1)需要跟着更新这个插件。另外默认只扫最高 generation,历史版本不传 --all-generations 就看不到,这是设计使然,不是漏检。

社区目录(skillhub.cn)是独立站点,与 DeepSeek、幻方没有官方从属关系,插件列表别当成官方应用商店来引用。

结尾

dsh-session-doctor 的价值在于把「会话损坏」这种没法再往下查的报错,拆成「第几行、哪种事件、哪条规则违规」。它只读、不改文件、不承诺修复,代价是要跟 dsh reader 的版本一起维护规则。排查 corrupt session 时,先把这个插件跑一遍,比手工解 zstd 再逐行 parse 省事。

  • 目录页:https://www.skillhub.cn/plugins/aturzone/dsh-session-doctor
  • GitHub:https://github.com/aturzone/dsh-session-doctor
羽毛球分组比赛记分
小程序二维码

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

小夜