dsh-failure-capsule
yiharvest/dsh-failure-capsule
Local-first failure evidence capsules for DeepSeek Harness sessions
安装
dsh plugin --profile web add github:yiharvest/dsh-failure-capsuleREADME
dsh-failure-capsule
DeepSeek Harness 的本地优先故障证据包插件:当工具或 Agent 失败时,自动把失败前发生了什么、项目当时是什么状态、运行环境和插件组合是什么整理成一个经过脱敏的 ZIP。
当前状态: 可作为标准 Profile Bundle 安装;面向
@deepseek-ai/dsh@0.1.0-rc.6的原生session/event与agent/error接口实现。插件不修改 Harness 核心,不上传数据,也不调用模型诊断故障。
快速开始
为使用中的 profile 安装插件。Web 与 headless 是两个独立 profile,需要分别安装:
dsh plugin --profile web add dsh-failure-capsule
dsh plugin --profile headless add dsh-failure-capsule
验证组合层:
dsh --profile web --dump-config
# 输出中应出现 id: failure-capsule / name: dsh-failure-capsule
随后正常使用 DSH。失败发生时,插件默认把证据包写入当前项目:
.dsh/failure-capsules/
└── 2026-08-14T08-20-31-123Z_<session>_tool-error_event-42.zip
它解决什么问题
普通错误日志往往只有“最后哪里炸了”,但 Coding Agent 的失败通常依赖一整段过程:模型请求、工具调用、权限、工作树变化、运行时以及插件组合。当失败携带压缩后的 JS 栈(如 agent/error)时,插件还会用项目里的本地 source map 把它反解回原始源码位置,而不是只保留一行压缩栈。Failure Capsule 把这些信号放在同一个离线证据包里:
flowchart LR
A[Harness session events] --> D[Failure detector]
B[Git evidence] --> E[Evidence builder]
C[Runtime and plugins] --> E
D --> F[Bounded failure window]
F --> E
E --> R[Secret redaction]
R --> Z[failure-capsule.zip]
默认捕获以下故障:
| 信号 | 默认 | 说明 |
|---|---|---|
tool/result 且 isError=true | ✅ | 每个失败工具调用各生成一份 |
turn/end / error | ✅ | 模型、传输或 Agent 回合失败 |
turn/end / blocked | ✅ | 回合被策略或流程阻塞 |
turn/end / interrupted | ✅ | 上个进程未能正常关闭回合 |
agent/error | ✅ | 没有落入持久化失败回合的运行时错误 |
turn/end / aborted | ❌ | 用户取消默认不视为故障,可配置开启 |
ZIP 内容
failure-capsule.zip
├── manifest.json # schema、触发点、证据清单、脱敏计数
├── failure.json # 结构化失败身份
├── timeline.jsonl # 失败点之前的有界 Session Event 窗口
├── diagnosis.md # 确定性、无模型的排查入口
├── runtime.json # Node / OS / 项目包信息
├── plugins.json # Loader 插件、启用状态和 fiber 阶段
├── redaction-report.json # 按规则统计;不包含原始秘密
├── stack-trace.json # 栈帧与 source map 反解结果(存在栈时)
├── stack-trace.md # 反混淆后的可读栈帧与源码上下文
├── session/
│ └── header.json # 会话 cwd、谱系和格式版本
└── git/
├── head.txt
├── branch.txt
├── status.txt
├── recent-commits.txt
├── working-tree.patch
└── index.patch
Timeline 默认最多 80 条事件。每条 Git 命令默认最多采集 512 KiB;达到预算会终止命令并明确标注截断。Git 通过参数数组直接执行,不经过 shell,不读取未跟踪文件内容,也不运行 hook 或 textconv。
安全模型
- Local-first: ZIP 只写本机;插件没有网络请求和遥测后端。
- 导出副本脱敏: 原始 Session Log 和工作树不被改写。
- 默认脱敏: 敏感字段、Bearer/Basic 凭据、常见 provider/GitHub/npm token、AWS access key、环境变量赋值、URL 用户密码、私钥块和本机路径。
- 有界采集: Session Event 数量和每个 Git 输出都有硬上限。
- 错误隔离: 证据生成失败只写 Harness warning,不改变 Agent 的原始失败或后续运行。
- 安全停止: 插件卸载时会等待已启动的证据包写入结束。
自动脱敏不能证明 ZIP 中绝对没有业务秘密。分享前仍应人工检查,尤其是自由文本、源代码 diff 和自定义插件事件。
配置
cordis.patch.yml 提供以下默认值。可以在 profile 的 cordis.patch.yml 中用同一个 row id 覆盖整段配置:
- id: failure-capsule
name: dsh-failure-capsule
config:
outputDir: .dsh/failure-capsules
maxEvents: 80
maxGitBytes: 524288
captureGit: true
capturePlugins: true
triggerOnToolError: true
triggerOnTurnFailure: true
triggerOnAborted: false
triggerOnAgentError: true
resolveSourceMaps: true
maxSourceMapBytes: 4194304
| 字段 | 类型 | 默认值 | 作用 |
|---|---|---|---|
outputDir | string | .dsh/failure-capsules | 相对路径以 Session cwd 为基准;也可用绝对路径 |
maxEvents | integer | 80 | 1..10000,失败点之前最多保留的事件数 |
maxGitBytes | integer | 524288 | 1024..16777216,每条 Git 命令的输出预算 |
captureGit | boolean | true | 是否采集 Git 证据 |
capturePlugins | boolean | true | 是否采集 Loader 插件清单 |
triggerOnToolError | boolean | true | 失败工具结果是否触发 |
triggerOnTurnFailure | boolean | true | error / blocked / interrupted 回合是否触发 |
triggerOnAborted | boolean | false | aborted 回合是否触发 |
triggerOnAgentError | boolean | true | 无持久化失败边界的 live error 是否触发 |
resolveSourceMaps | boolean | true | 是否用本地 source map 反解压缩后的 JS 栈帧 |
maxSourceMapBytes | integer | 4194304 | 1024..67108864,单个 source map 文件的读取预算 |
错误配置在插件加载时直接失败,不静默回退。相同 Session Event 在一个插件生命周期内只生成一次;agent/error 会短暂等待对应的 turn/end,避免同一失败重复打包。
开发与验证
需要 Node ^22.19.0 || >=24.0.0:
npm install
npm run check
npm pack
测试覆盖脱敏、故障分类、配置边界、Git 采集预算、source map 栈帧反解、ZIP 确定性、原子写入和路径安全。发布包的 prepack 会重新执行 typecheck、测试与构建。
从本地 tarball 验证真实 profile 安装:
npm pack
dsh plugin --profile web add ./dsh-failure-capsule-0.2.0.tgz
dsh --profile web --dump-config
生态发现
仓库使用 dsh-plugin topic,并以 package.json 的 dsh.bundle.patch 作为标准安装入口,因此会被 Awesome DSH Plugins Radar 自动发现。收录只代表可发现;兼容性和安全性仍应以可复现测试与源码审查为准。