deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
DSH git 版本管理 + 崩溃自动救援插件
把 .dsh 用户目录(sessions 会话、settings、profiles 配置)与 workspace 纳入 git 版本管理,
用 commit 历史做精细回退;harness 崩溃时自动回退到上一个好版本。远端备份仅支持 GitHub token 方案。
🥇 最好的 dsh 恢复插件,永远是 dsh 本体!
2026-08-19 崩溃主机救援实战铁律:插件(包括本插件)只能做 git 回退/拉起这类本机兜底; 真正把一台起不来的 DSH 救回来、把 8 插件 + 上百会话完整恢复的,往往是另一台还在跑的 DSH (跨机部署救援实例 + SSH 拉起纯净环境 + 可覆盖式恢复包)。本机插件救不了的场景,永远记得: 再开一个 DSH 来救这个 DSH——训练有素的 AI + 另一份 .dsh + 一份权威 skill 文档,比任何单个插件都可靠。
功能总览(组件 C 当前 v1.12.0):
| 功能 | 版本 | 一句话 |
|---|---|---|
| git 版本管理 | v1.1.0 | .dsh/workspace 双仓库、自动 commit、心跳、崩溃检测、token 推送 |
| guardian 自动救援 | v1.2.0 | 独立进程探活 + git 回退 + 拉起 + 自检(坏点标记防死循环) |
| 自动更新 | v1.3.0 | 强制跟随 GitHub 最新稳定版:每次启动 30s 首查 + 每天定时,原子替换 + 失败回滚(隐藏开关 env 可关) |
| 接管式重启 | v1.4.0 | 独立脚本接管 DSH 重启:TERM→轮询恢复→验证→留痕,会话中断也能安全完成(配套 skill docs/skill-dsh-restart-takeover.md) |
| 会话恢复联动 | v1.5.0 | 与 dsh-session-manager 协同:崩溃后调用其 scan 自动续跑中断会话;装了才调用、没装跳过、不内置 |
| 异常感知增强 | v1.6.0 | flapping 检测(无限重启识别+冷却)/ 业务就绪探活(假活识别)/ 现场捕获(stderr 落盘+TERM 来源追踪)/ sessions 基线+增量(控制仓库体积) |
| 救援积分 | v1.7.0 | 成功救援次数(guardian/回退/崩溃检出),事件流权威防刷分,设备 ID 标识,未来排行榜 |
| 可选 sudo-key | v1.8.0 | 🔓 完全可选不强求:仅愿提供 root 密码的设备自动修复只读卷(密码绝不明文);不填完全不影响核心功能,敏感用户可跳过 |
| 救援前插件自更新 | v1.12.0 | guardian 救援前先自更新插件本体(checkForUpdate → applyUpdate 换新磁盘代码再救援),救援逻辑保持最新,避免旧版带病救人;测试环境同样允许;GUARDIAN_SELF_UPDATE=0 可关;失败不阻断救援 |
| 测试环境不自动救援 | v1.11.0 | 测试环境崩溃由开发者自行解决:guardian 探测到 dsh-test-* DSH_HOME 即禁用自动 git 回退/拉起,只留现场;活跃对话保护:救援前检测进行中对话,存在则落盘 restart-request.json 提交重启申请不打断;手动救援前记录近期变动文件(防回退丢刚写的代码) |
DeepSeek Harness 改配置、装插件、跑长任务都是家常便饭,风险也随之而来:
cordis.patch.yml 写错、插件冲突,DSH 启动失败白屏dsh-git-rescue 的思路:一切历史都是 git 历史。 版本管理交给 git,救援恢复就是回退, 远端备份交给 GitHub(token)。与现有的 zip 快照方案(dsh-snapshot-guardian)互补:
| 方案 | 手段 | 特点 | 适用 |
|---|---|---|---|
| dsh-snapshot-guardian | zip 全量快照 + 解压恢复 | 零依赖、快照间无关联、恢复 = 解压 | 启动失败/网页崩了的手动兜底 |
| dsh-git-rescue(本插件) | git 增量历史 + commit 回退 | 可 diff、可溯源、自动触发、可远端备份 | 日常版本管理 + 崩溃自动恢复 |
| 管理对象 | 路径 | 说明 |
|---|---|---|
| 用户目录 | .dsh/(settings.yaml、profiles/、sessions/、skills/) |
DSH 全部可编辑状态 |
| 工作区 | workspace/(白名单) |
项目源码、留档、脚本;按 .gitignore 规则入库 |
触发时机(任一命中即 commit):
commit 规范:chore(guard): <触发原因> | <自检摘要>,例如
chore(guard): crash-detected | pre-rollback snapshot of broken state —— 每个 commit 都能回溯"当时发生了什么"。
入库边界(安全第一):
.credentials.yaml、.env、token 文件.fpk、.zip、.tgz、node_modules/jsonl.zstd(二进制、整体差异大)→ 采用 定期全量基线 + 短周期增量 策略,避免仓库无限膨胀.gitignore 规则由插件首次初始化时自动生成并提交崩溃检测 → ① 强制 commit 当前坏状态(可事后分析)
→ ② 从坏点向前找最后一个"好" commit
→ ③ 回退前做一次全量副本备份(双保险)
→ ④ git reset/checkout 回退
→ ⑤ 重启 DSH 自检(端口监听 + 健康检查)
→ ⑥ 失败则继续回退上一步,最多 N 步(默认 3,可配置)
bad 标记,防止"回退后又回到同一个坏点"的死循环600,绝不写入任何 commit;仅用于 push 认证git-remote-https 助手,HTTPS git 操作直接失败 —— 插件检测到该情况时自动降级为 GitHub REST API 直连(curl/Node fetch + token),保证 token 方案在异常环境下依然可用<账号>/dsh-git-rescue-backup-<设备ID前12位>,每台设备一个备份仓/etc/machine-id(Linux 系统级唯一 ID,兜底为持久化 UUID),
同一 GitHub 账号下多台设备互不冲突;hostname 仅进仓库描述供人识别,githubRepo 配置仍可手动覆盖| 检测手段 | 判定 | 说明 |
|---|---|---|
| 进程探活 | dsh web 进程消失 | guardian 独立进程周期探活(每 10s) |
| 心跳文件 | 心跳超时(默认 60s) | DSH 内插件定期写心跳,guardian 读 |
| 启动自检 | 端口未监听 / 白屏 | 重启后健康检查不通过 = 判定为坏状态 |
检测到崩溃 → 走原理二的自动回退流程 → 回退后自动拉起 DSH → 自检通过则通知恢复完成。
┌─────────────┐ ┌──────────────────────────┐ ┌─────────────────┐
│ DSH 启动 │──▶│ ① 检测运行机器有无 git │──▶│ ② 检查插件配置 │
└─────────────┘ │ (git --version) │ │ (token 等) │
└──────────────────────────┘ └────────┬────────┘
▼
┌─────────────────────────────────────────────┐
│ ③ 初始化 git 仓库 + .gitignore + 首次 commit │
└─────────────────────────────────────────────┘
│
┌───────────────┐ 每 30min / 事件触发 ▼
│ ④ 自动 commit ◀───────────────────── 版本快照
└───────┬───────┘
│
┌───────▼───────┐ push (token) ┌──────────────────┐
│ ⑤ 远端备份 │────────────────▶│ GitHub 备份仓库 │
└───────┬───────┘ └──────────────────┘
│
┌───────▼───────┐
│ ⑥ 崩溃监控 │──崩溃?──▶ ⑦ commit 坏状态 → ⑧ 自动回退 → ⑨ 重启自检
└───────────────┘
git_rescue_backup / git_rescue_status / git_rescue_rollback / git_rescue_restart / git_rescue_pushDSH_GIT_RESCUE_AUTO_UPDATE=0 可关git-rescue/restart-latest.log,会话恢复后读日志确认guardian.log,动作全程留痕cd ~/.dsh && git log --oneline、git reset --hard <commit>| 条目 | 约定 |
|---|---|
| token 存储 | 本地文件,权限 600,仅 push 用,绝不提交 |
| 远端仓库 | 只含版本历史与快照,不含任何凭据明文 |
| 回退安全 | 回退前全量副本 + 坏点标记 + 最大回退步数 |
| 大文件 | 一律 gitignore,仓库只保留文本/配置/小体积留档 |
原独立仓库
dsh-snapshot-archive/dsh-guardian/dsh-snapshot-guardian已合并入本仓库并从 GitHub 删除。 以下是从中提取、迁移到 git 方案的原理要点——原仓库已不在,这份记录就是永久提醒,后续开发照此执行。
git reset --hard;网页全崩,命令行也能救| 原 zip 方案 | git 方案(本仓库) |
|---|---|
| zip 全量快照(.dsh 原始路径) | git 增量历史(add -A 自动 commit) |
| 恢复 = unzip 覆盖 | 恢复 = git reset --hard |
敏感文件脱敏 ***REDACTED*** |
token 单独文件 600 + .gitignore 排除 |
| guardian 探活 + failThreshold=3 | 照搬(GUARDIAN_FAIL_THRESHOLD) |
| 回退前 autoSnapshot | pre-rollback commit 坏现场 |
| 重启 + 健康检查自证 | 照搬(startWaitMs + probe) |
| 手动 unzip 兜底 | 命令行 git 兜底 |
| 快照自带三平台恢复脚本 | 不需要(git 本身跨平台) |
bad-* tag,防"回退后又回到同一坏点"死循环git-remote-https 缺失的环境坑git-remote-https 缺失被正确检出(推送自动走 REST API)git-remote-https 缺失环境:REST API 推送成功(159 文件,敏感文件零泄漏)crash-detected + 自动 commit 现场救援工具的信任来自反面测试。我们不信"应该没问题",而是故意把它弄坏,再让它自己爬起来—— 这是本项目的核心测试哲学,也是它敢自称"救援"的底气。
| # | 破坏手段 | 破坏对象 | 验证的救援能力 | 结果 |
|---|---|---|---|---|
| 1 | 篡改配置 | settings.yaml 写入垃圾 |
git 回退恢复原状 | ✅ |
| 2 | 删除文件 | 删除被跟踪的 pnpm-workspace.yaml |
回退找回文件 | ✅ |
| 3 | 连环破坏 | 恢复后再次破坏 | bad 标记防回退死循环 | ✅ |
| 4 | 进程秒杀 | kill -9 dsh web |
心跳过期检出 crash-detected + 自动 commit 现场 |
✅ |
| 5 | 灭门级 | 破坏 cordis.patch.yml 致 DSH 无法启动 |
guardian 自动 git 回退 → 拉起 → 健康自检 | ✅ |
10:21:44 健康检查失败(连续 1/3)
10:21:54 健康检查失败(连续 2/3)
10:22:04 健康检查失败(连续 3/3)→ 触发自动救援
10:22:04 坏点标记: bad-c6a588b ← 坏提交被标记,防再次踩坑
10:22:04 已回退到 bd6824c(from c6a588b) ← git reset --hard 秒级完成
10:22:04 启动 DSH: <自动拉起命令>
10:22:09 ✅ 救援成功:回退后 DSH 恢复正常 ← 5 秒内满血复活
为什么值得"吹":
bad-* tag)保证"回退后再次崩溃不会回到同一个坏点"——这是 zip 方案没有的增量能力为什么必须独立:改插件必须重启 DSH,而重启会中断正在进行的会话 → 插件测试一律在隔离实例进行。
┌─ 主实例(生产/会话)────────────────────────┐
│ dsh web 127.0.0.1:3081 DSH_HOME=~/.dsh │
│ └ 反代 0.0.0.0:3080(局域网访问) │
└──────────────────────────────────────────────┘
┌─ 测试实例(插件热开发,随便崩)───────────────┐
│ dsh web 127.0.0.1:3083-3182(自动分配) │
│ DSH_HOME=workspace/dsh-test-home(完全隔离)│
│ └ 反代 0.0.0.0:3084(局域网访问) │
└──────────────────────────────────────────────┘
要点:
kill -9 测试实例不碰主实例一根汗毛node_modules_local/ → package.json 声明 file: 依赖 → cordis.patch.yml insert → node_modules 补软链(踩坑后总结的解析机制)dsh-clean-env.sh 一键生成"初始、无插件"的纯环境,做插件前后对照 / 隔离排查数据:单元测试 23/23(含真实 GitHub 推送往返)、5 类破坏场景全过、guardian 救援 5 秒自愈。
结果:三个原独立仓库(dsh-snapshot-archive / dsh-guardian / dsh-snapshot-guardian)已并入本仓库并从 GitHub 删除。
| 合并来源 | 归入位置 | 状态 |
|---|---|---|
| zip 快照归档 | components/snapshot-archive/(组件 A) |
✅ 已合并 |
| 守护进程 | components/guardian/(组件 B) |
✅ 已合并 |
| git 版本管理+救援 | components/git-rescue/(组件 C) |
✅ v1.2.0 已开发完成 |
| 整合版(A+B) | 不纳入,已删分支与仓库 | ✅ 已删除 |
三组件协同关系:
| 组件 | 手段 | 职责 |
|---|---|---|
| A 快照归档 | zip 全量快照 | 零依赖兜底,网页全崩也能手动 unzip 恢复 |
| B guardian 守护 | 独立进程探活 | 网页/进程全崩时自动回退 + 拉起 |
| C git 救援 | git 增量历史 | 精细回退、可 diff、GitHub token 远端备份 |
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。