# Danger Ops Guard

> Use when 高危命令/删除/日志排查。事前拦截与事后检测，保护记忆/SQLite/密钥/git。

- Skill: `yyyyyhhhhh0639/danger-ops-guard` (Agent Skill)
- Install (CLI): `npx skillmds@latest add yyyyyhhhhh0639/danger-ops-guard`
- Raw SKILL.md: https://api.skillmd.com/api/skills/yyyyyhhhhh0639/danger-ops-guard/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: yyyyyhhhhh0639 (https://skillmd.com/u/yyyyyhhhhh0639)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/yyyyyhhhhh0639/danger-ops-guard

---


# 危险操作防护体系 (Danger Ops Guard)

## Overview

解决"记忆/技能存在但未被应用"的根本方案——**不依赖 LLM 记得规则，而是结构性拦截/检测**（确定性脚本，非概率决策）。错误按"损失发生时点"分三层，用不同机制防护。

## When to Use

- 准备执行高危命令（rm/删除/覆盖/密钥写入/git push）
- 排查错误日志（WinError/锁/Cloudflare/依赖降级等已知特征）
- 删除记忆/SQLite/配置/技能等受保护资产
- 用户问"这个操作安全吗/会不会删掉重要的东西"

**Don't use for:**
- 记忆价值判断 → `memory-storage-management`
- 会话知识沉淀 → `session-knowledge-capture`
- 变更决策（改还是重建）→ `change-decision-framework`

## 错误分层与机制选择

```
L2 不可逆损失（发生即重大）→ 事前屏障（danger-check BLOCK + safe-rm 转回收）
  删 SQLite 主库 / 覆盖记忆 / 泄漏密钥 / 误推 git
L1 可恢复但代价高 → 事后检测 + 回滚点（.bak/git）
L0 可轻松重跑     → 事后检测（日志特征暴露）
```

**原则：对 L2 用事前拦截（检测到时损失已发生=无效）；对 L0/L1 用事后检测（暴露即够）。**

## 工具一：danger-check.py（命令前置检查 + 日志扫描）

位置：`~/AppData/Local/hermes/scripts/danger-check.py`

```bash
PY="$HOME/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
DANGER="$HERMES_HOME/scripts/danger-check.py"

# 检查命令（执行前调用）
"$PY" "$DANGER" rm -rf ~/AppData/Local/hermes/memories   # → BLOCK exit=2
"$PY" "$DANGER" git push origin main                      # → BLOCK exit=2
"$PY" "$DANGER" uv pip install torch                      # → WARN exit=3
"$PY" "$DANGER" ls -la /tmp                               # → 安全 exit=0

# 扫描日志错误特征（排查时调用）
"$PY" "$DANGER" --scan-log "$HERMES_HOME/logs/errors.log"
```

退出码：0=安全 / 2=BLOCK（阻止）/ 3=WARN（确认后执行）

### 现有模式库（BLOCK/WARN）

| 模式 | 级别 | 提示 |
|------|:---:|------|
| rm -rf 指向受保护路径 | BLOCK | 记忆/SQLite/配置/技能/venv |
| git push | BLOCK | hermes-state-git 私有边界 |
| 密钥写入命令 | BLOCK | api_key/token/secret 值进命令 |
| rm 记忆/技能文件 | BLOCK | 不可逆 |
| chmod 777 敏感文件 | BLOCK | 凭证泄露 |
| cp/mv 覆盖关键文件 | WARN | 确认备份 |
| SQL 删记忆/日志 | WARN | 确认意图 |
| uv pip install torch | WARN | CUDA 降级风险 |
| uv pip install 非 --no-deps | WARN | pyarrow/torch 降级 |
| hermes-scope-recall upgrade | WARN | 需 doctor 全绿+备份 |
| rm *.sqlite3 | BLOCK | 运行中库禁止 |

### 日志特征库（B1a）

| 特征 | 根因提示 |
|------|---------|
| `F:\f\` 或 `F:\c\` | MSYS 跨盘拼接（native 程序收 /f/） |
| `WinError 126 + torch` | Python ABI 不匹配（外部 Py 进程经 PYTHONPATH 加载 venv torch）；先用 venv 自身 python 验证 torch 是否真坏 |
| database is locked | SQLite 锁 |
| error code: 1010 | Cloudflare UA 拦截（nightly-llm-ua.patch） |
| ModuleNotFoundError: dotenv | uv sync 进错 .venv |
| trusted non-CLI user principal | scope-desktop-principal.patch |
| did not emit a valid JSON object | doctor GBK（installer-utf8.patch） |
| 2.13.0+cpu | CUDA torch 降级 |
| lancedb unavailable fallback | ML 依赖被清（restore-ml-deps.ps1） |
| exclude-newer 过滤 | uv 时间门（--exclude-newer 绕过） |

## 工具二：safe-rm.py（删除转回收）

位置：`~/AppData/Local/hermes/scripts/safe-rm.py`

```bash
PY="$HOME/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
SAFERM="$HERMES_HOME/scripts/safe-rm.py"

"$PY" "$SAFERM" /tmp/temp-file.txt        # 普通删除
"$PY" "$SAFERM" ~/AppData/Local/hermes/memories/x.txt  # 受保护→转回收站
"$PY" "$SAFERM" --list-protected          # 查看保护列表
"$PY" "$SAFERM" --force <path>            # 强制永久删除（确认过）
```

- 回收站：`F:/AI/Hermes/trash/<日期>/`（可恢复）
- 受保护路径与 danger-check 一致（memories/SQLite/lancedb/config/auth/.env/skills/venv/state-git）
- **MSYS 路径已处理**：/tmp/x → C:/Users/.../Temp/x，/f/x → F:/x（2026-08-07 实证修复）

## 工具三：backup-gate.py（修改前强制备份门）

位置：`~/AppData/Local/hermes/scripts/backup-gate.py`

```bash
PY="$HOME/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
GATE="$HERMES_HOME/scripts/backup-gate.py"

"$PY" "$GATE" --check <path>          # 检查是否受保护（2=受保护需先备份）
"$PY" "$GATE" <path>                  # 为受保护路径生成 .bak.<ts>
"$PY" "$GATE" --list-protected
```

- 修改 memories/config/auth/.env/skills/SQLite 前调用，自动快照
- 与 danger-check 互补：拦删除（check）、管修改（gate）
- **MSYS 路径已处理**（/f/x → F:/x，2026-08-07 实证）

## 工具四：post-check.py（高频命令后置验证）

位置：`~/AppData/Local/hermes/scripts/post-check.py`

```bash
PY="$HOME/AppData/Local/hermes/hermes-agent/venv/Scripts/python.exe"
PC="$HERMES_HOME/scripts/post-check.py"

"$PY" "$PC"             # torch CUDA + ML 依赖 + 插件版本 + doctor 全绿
"$PY" "$PC" --quick     # 跳过 doctor（快速）
"$PY" "$PC" --torch-only
```

- upgrade/install/装包后运行，验证：torch 未降级（2.6.0+cu124 True）、ST/lancedb 存在、插件版本、doctor 全绿
- 退出码：0=通过 / 2=有失败项

## 工具五：trash-clean.py（回收站定期清理）

位置：`~/AppData/Local/hermes/scripts/trash-clean.py` + `trash-clean-wrapper.py`（cron 用）

```bash
"$PY" trash-clean.py --days 30 --dry-run   # 预览
"$PY" trash-clean.py --days 30             # 清理 30 天前
```

- cron：`trash-cleanup`（每周日 4:00，no_agent）

## 看门狗与统计

- cron `danger-watchdog`（每小时）：`danger-watch.py` → danger-check --watch --hours=24，命中才报
- 统计：`~/AppData/Local/hermes/logs/danger-watchdog-stats.jsonl`（每次运行一行：ts/hits/exit/elapsed_s）
- 查看统计：`tail -20 ~/AppData/Local/hermes/logs/danger-watchdog-stats.jsonl`

## 工具六：Shell Hook（官方推荐，主防线）——block-hermes-assets.py

**这是官方推荐的扩展方式**（非源码补丁）：config.yaml 的 `hooks.pre_tool_call` 在**每次 terminal 工具调用前**触发脚本，返回 `{"decision":"block"}` 即拦截——独立于 approval 系统，覆盖所有命令。

位置：`~/AppData/Local/hermes/agent-hooks/block-hermes-assets.py`

```yaml
# config.yaml（已配置）
hooks:
  pre_tool_call:
    - matcher: terminal
      command: $HERMES_HOME/hermes-agent/venv/Scripts/python.exe $HERMES_HOME/agent-hooks/block-hermes-assets.py
      timeout: 5
hooks_auto_accept: true
```

拦截（与 danger-check 一致）：
- `rm` 指向 memories/ → block（不可逆记忆丢失）
- `rm *.sqlite3` → block（不可逆）
- `git push` → block（本地私有边界）
- 放行：trash/备份/.bak 路径（不误拦回收站清理）；`safe-rm.py`（转回收，可恢复）

**⚠️ 正则边界（2026-08-07 修复）**：rm 匹配必须用 `(?:^|[;&|\s])\s*rm\b` 前缀限定命令位置——裸 `\brm\b` 会误拦 `safe-rm.py`（rm 前是 `-` 也构成词边界）。已修复并 10 项回归测试通过。

**探针日志**：`~/AppData/Local/hermes/logs/block-hermes-assets.probe.log` 记录每次 hook 调用（时间戳+命令），保留作审计。

**验证命令**：
```bash
hermes hooks list    # 应显示 ✓ allowed
hermes hooks test pre_tool_call --payload-file <json>  # payload 用 args 键（非 tool_input！）
```

**⚠️ 关键坑（2026-08-07 实证）**：
1. **Windows 下 command 必须带 python 解释器**（裸 .py 报 WinError 193）
2. **allowlist 按精确 command 串匹配**——改 command 后必须同步更新 `shell-hooks-allowlist.json`
3. **hooks test 的 payload 用 `args` 键**（`_serialize_payload` 把 args→tool_input）；`--for-tool` 合成 payload 无 command
4. **hermes config set 不支持 dict/list**（只转 bool/int/float）——hooks 块需直接编辑 config.yaml（agent 工具层保护，需用户手动或终端脚本插入）
5. **consent**：非 TTY 需 `hooks_auto_accept: true` 或预写 `shell-hooks-allowlist.json`（approvals 数组，精确 command 串）

> **为什么不用源码补丁**（DANGEROUS_PATTERNS）？官方文档明确：`pre_tool_call` 是"block a tool before it reaches the approval system"的指定拦截点（hooks.md 1103 行）；源码补丁升级被覆盖、且 Hermes 有官方 shell hooks 机制。2026-08-07 曾先做源码补丁（approval.py +3 正则），后按官方文档改用 Shell Hook 并回滚源码补丁。

### ⚠️ 已知缺口：`hermes serve`（桌面端）不注册 shell hooks（2026-08-07 实证 + 已补丁）

**现象**：桌面 app 会话（`hermes_cli.main serve` 进程）中执行 terminal 命令，pre_tool_call hook 从不触发（探针日志为空）。

**根因**：`register_from_config` 只在 cli.py:1047（CLI）和 gateway/run.py:10965（gateway）调用。`hermes serve`（桌面后端）**不经过 `_prepare_agent_startup` 的 agent-command 守卫**（`_AGENT_COMMANDS = {None,"chat","acp","rl"}`），且 `cmd_dashboard` 无显式注册——桌面会话的 hook 从未注册。

**修复（补丁 `serve-hooks-registration.patch`）**：
1. `_AGENT_COMMANDS` 加入 `"serve","dashboard"`（让守卫通过）
2. `cmd_dashboard` 中显式调用 `register_from_config`（serve 入口）

**验证**：启动 `hermes_cli.main serve` 测试实例 → agent.log 出现 "shell hook registered: pre_tool_call -> block-hermes-assets.py"（21:48:20 实证）。

> **补丁后需重启桌面 app**（其 serve 进程是补丁前启动的旧进程）。升级 Hermes 会覆盖 main.py——需重打此补丁。

## Common Pitfalls

1. **对 L2 用事后检测** — 检测到时损失已发生；L2 必须事前拦截（BLOCK/转回收）
2. **模式库不更新** — 每次发现新错误特征（如新错误模式），立即补进 danger-check.py 的 LOG_FEATURES/BLOCK_PATTERNS
3. **忘记调用** — danger-check 是手动触发的；高频命令（upgrade/install）可固化进流程（如 upgrade 前先 doctor 全绿已有）
4. **safe-rm --force 滥用** — 仅确认过才用；受保护路径的 --force 会永久删除
5. **路径判断靠 resolve()** — junction（HERMES_HOME）下相对/绝对路径都能正确识别

## Verification Checklist

- [ ] 高危命令执行前跑了 danger-check（BLOCK 则未执行）
- [ ] 删除受保护资产用了 safe-rm（而非裸 rm）
- [ ] 排查错误时跑了 --scan-log 检查已知特征
- [ ] 新错误特征已补入模式库
- [ ] trash 定期清理（回收站不自动过期）

