dsh-contract-check:装完插件后的 DSH 契约体检(零 token、只告警)

前言

DeepSeek Harness(DSH)的写路径相对宽松,读路径却很严:一旦某条工具输出或会话事件不符合内核契约,失败往往落在整条会话上——历史加载报错、日志无法解释,而不是「只坏这一条记录」。社区里已有面向插件仓库的发布前审计(例如 omdsh-dev/dsh-plugin-check,覆盖清单、patch、打包等 33 项),但插件安装进 profile 之后,注册表里的 output.render() 和运行时写入的会话事件类型,仍可能悄悄埋雷。

下面介绍维护者 imtokenxinluo 在工作流分类下的插件 dsh-contract-check:它不查恶意、不拦截执行,专门回答「当前装着的插件有没有违反 DSH 内核契约」;对外只通过日志 warn,并可选在会话头部显示零 token 的「体检」状态。

这是什么

dsh-contract-check 是 DSH 的契约合规检查插件(GitHub:imtokenxinluo/dsh-contract-check)。定位可以概括为:

  • 扫描对象:运行中的工具注册表(安装后),而不是仅扫源码树。
  • 检查范围:两条硬契约——output.render() 应返回 ContentBlock[](而非字符串等);会话事件类型是否落在内核 KNOWN_SESSION_EVENT_TYPES 词汇表内。
  • 行为:只告警(warn-only),不阻止任何操作;不注册模型工具,对每轮对话的 token 消耗为零。

它与 dsh-plugin-check 互补:后者更适合发布前查打包与生态合规;本工具侧重装进来之后、盯「会让会话打不开」的那两类问题,并对压缩或无源码插件仍可读注册表定义。

核心功能

1. render 契约

内核要求 output.render() 返回 ContentBlock[]。若返回裸字符串等,加载器可能抛出 SessionPersistenceCorruptionError,整条会话历史无法加载(README 引述 2026-09 前后 dsh-ssh-ops 相关事故为例)。

检查手段包括:

手段 做法 局限
静态 读 render 源码,看 return 是否为数组 对 defineTool 包装后的壳函数往往看不透
实测(默认开启) 按 output.schema 造合法假数据,真调一次 render 假数据不合形状时抛异常 → 归 unknown,不误报为 violation

静态对多数正经插件只能报 unknown;README 强调实测是必需品,可通过配置关闭(probeRender: false)。

2. 会话事件类型词汇表

加载器对未知事件类型且未标记可忽略的类型会拒绝解释整条日志。README 说明:插件通过 Session.append 无法设置 ignorable;自定义类型若未注册进宿主侧的 KNOWN_SESSION_EVENT_TYPES,使用者的会话可能打不开。插件在运行期订阅 session/event,发现表外类型即告警;措辞为「看起来不在词汇表内,请确认是否已注册」,因为运行时看不出作者是否已通过改 Set 等方式注册过。

3. 三态判定与 GUI

判定 含义
ok 返回值形态正确
violation 证实返回字符串 / 非数组 / undefined 等
unknown 判不准——宁 unknown,不 violation

装进 profile 并重启后,会话头部会出现「体检」按钮(颜色圆点 + 文字)。绿:验过且 0 违规;黄:有违规;灰:尚未体检、无法枚举或全部判不准。状态通过同源 HTTP GET /contract-check/status 与 POST /contract-check/audit 提供;客户端产物需本地 npm run build 生成 lib/client.js,否则 DSH 可能报 client bundles not found。

4. 离线 CLI(无需跑 DSH)

dsh-contract-check scan <文件或目录>
dsh-contract-check package <包目录>
dsh-contract-check vocab
  • scan:递归扫源码里的 render 定义。
  • package:轻量检查 npm 打包是否漏发 package.json 声明要用的文件(完整 33 项请用 dsh-plugin-check)。
  • vocab:打印内嵌词汇表版本与条目数。

发现 violation 时 CLI 退出码为 1,便于 CI。

明确不做什么

  • 不检测蓄意投毒、窃取或后门;进程内检查器与恶意插件权限相同。
  • 不注册模型工具、不注入提示词;唯一常见对外输出是 ctx.logger.warn(...)。

安装与启用

官方 README 给出的方式是写入 profile 的 package.json 依赖与 bundle 列表(非 dsh plugin add 一类命令):

// profiles/<profile>/package.json
{
  "dependencies": { "dsh-contract-check": "^0.1.0" },
  "dsh": { "profile": { "bundles": ["...", "dsh-contract-check"] } }
}

本地开发可将依赖写成 link: 指向仓库路径;修改客户端源码后需重新执行 npm run build 再重启 DSH。package 元数据要求 Node >= 22。

启用后插件会:加载时枚举 ctx.tools.view() 做检查;监听 tools/change 与 session/event;注册 Web 状态路由供头部按钮使用。服务依赖通过 ctx.inject 延迟注入,避免 tools / webServer 未就绪时静默失败。

典型用法

进程内体检:按上一节加入 profile,重启 DSH,观察会话头部「体检」状态;需要即时复检时点击按钮(进行中重复请求会返回 409,避免堆叠扫描)。

发布或改插件前离线扫 render:

dsh-contract-check scan ./src

检查自己的 npm 包会不会漏发 patch / exports 目标:

dsh-contract-check package .

核对内嵌事件词汇表:

dsh-contract-check vocab

适用场景与注意

适合谁

  • 已在 profile 里装多个 DSH 插件,想低成本确认有没有「写坏会话历史」的契约风险。
  • 需要零 token 角标、又不想为检查器本身注册 plugin_check 一类模型工具的场景。
  • 维护插件仓库时,用 CLI 做 render 静态扫或轻量 package 检查(深度发布审计仍应用 dsh-plugin-check)。

务必知晓

  • 插件以当前 DSH 进程权限运行;安装前应自行阅读源码与 MIT 许可证(见仓库 package.json)。
  • 告警不等于恶意;无告警也不等于安全审计通过。同组织 README 还提到 dsh-session-health、dsh-security-audit 等分工不同的工具。
  • 社区插件目录为独立站点 SkillHub 条目,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-contract-check 把「装进来之后」的两条内核契约——render 返回形态与会话事件词汇表——做成零 token、只告警的体检:进程内盯注册表与实时事件,CLI 可离线扫源码与打包遗漏。发布前全量生态检查请继续用成熟工具;装完插件后防「整条会话打不开」,可以用它做日常补位。

  • 目录页:https://www.skillhub.cn/plugins/imtokenxinluo/dsh-contract-check
  • 源码与说明:https://github.com/imtokenxinluo/dsh-contract-check
羽毛球分组比赛记分
小程序二维码

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

小夜