Files

1 line
174 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "banxia-o/aesculap-hermes", "files": {"AGENT.md": {"70052aa3d0e026cf57ca47d262aa45b12b24de4e": {"t": 1785747213.6324172, "n": 8705, "h": "381a130ffc26935d", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:先看 Hermes 已配置的 provider,再检查相关 API key 是否存在(只看「在不在」,绝不读取值)。内置向导目前只检测部分常见 Key,安装 Agent 必须补充检查国内兼容服务:**\n\n```bash\n[ -n \"$DEEPSEEK_API_KEY\" ] && echo \"deepseek available\"\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n# GLM、Kimi/Moonshot 等服务的变量名由用户现有配置决定;不要猜,更不要打印值。\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`。后者可直接连接兼容 OpenAI API 格式的 DeepSeek、智谱 GLM、Kimi/Moonshot、Ollama、vLLM 等服务;使用厂商真实的模型名、`base_url` 和密钥环境变量即可,不要求自建服务。\n\nDeepSeek 官方 API 示例:\n\n```yaml\nprovider: openai_compatible\nmodel: deepseek-v4-pro\nbase_url: https://api.deepseek.com/v1\napi_key_env: DEEPSEEK_API_KEY\n```\n\n**设计上不硬编码任何具体模型名**——示例只说明配置方式;最终型号必须根据当前账号真实可用列表向人类推荐并确认。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. **在启动向导前**运行 `hermes send --list` 查看真实可用目标,让人类选择投递位置并实际发送一条测试消息,例如 `hermes send --to telegram \"Aesculap test\"`。向导本身只接收命令模板、不会替你验证目标;没有可用目标就留空,不能假装通知已配置;\n8. **询问人类:需要人工干预时,蛇杖用什么语言通知?** 当前完整支持 English(`en`)和简体中文(`zh-CN`)。不要根据错误日志、服务器 locale 或模型输出猜用户语言。\n\n产出一个**经过校验**的 `config.yaml`。新安装默认 `mode: fix`,避免监控装好后因忘记切换而长期不修;启动服务前必须明确告诉人类,`observe` 只作为主动干跑或临时降级。通知语言写入 `notify.language`,同时控制分诊结果中的人类可读字段和最终 gateway 消息。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n### 3.4 人工通知语言\n\n安装时直接问人类:**“蛇杖需要找人干预时,用什么语言通知你?”** 将答案写入 `notify.language`。当前支持:\n\n- `en`:English(旧配置默认值,保持向后兼容);\n- `zh-CN`:简体中文。\n\n这个值同时约束两层:分诊 JSON 的人类可读 `diagnosis` 使用所选语言;通知标题、四段结构和原因指引也使用所选语言。`actions` 会被代码继续解析和执行,因此字符串必须保持英文,或使用结构化 action object。JSON key、enum 和内部审计字段也保持英文,不参与本地化。\n\n不要根据故障 evidence、英文堆栈、系统 `LANG` 或发送渠道猜用户语言。Hermes 的发送命令只负责投递,不保证提供收件人 locale;没有明确答案时必须询问,不能静默推断。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "c69ed897b84d6bc9727cdaf96055a8d52e2a2a7c": {"t": 1785771414.7582846, "n": 8705, "h": "381a130ffc26935d", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:先看 Hermes 已配置的 provider,再检查相关 API key 是否存在(只看「在不在」,绝不读取值)。内置向导目前只检测部分常见 Key,安装 Agent 必须补充检查国内兼容服务:**\n\n```bash\n[ -n \"$DEEPSEEK_API_KEY\" ] && echo \"deepseek available\"\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n# GLM、Kimi/Moonshot 等服务的变量名由用户现有配置决定;不要猜,更不要打印值。\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`。后者可直接连接兼容 OpenAI API 格式的 DeepSeek、智谱 GLM、Kimi/Moonshot、Ollama、vLLM 等服务;使用厂商真实的模型名、`base_url` 和密钥环境变量即可,不要求自建服务。\n\nDeepSeek 官方 API 示例:\n\n```yaml\nprovider: openai_compatible\nmodel: deepseek-v4-pro\nbase_url: https://api.deepseek.com/v1\napi_key_env: DEEPSEEK_API_KEY\n```\n\n**设计上不硬编码任何具体模型名**——示例只说明配置方式;最终型号必须根据当前账号真实可用列表向人类推荐并确认。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. **在启动向导前**运行 `hermes send --list` 查看真实可用目标,让人类选择投递位置并实际发送一条测试消息,例如 `hermes send --to telegram \"Aesculap test\"`。向导本身只接收命令模板、不会替你验证目标;没有可用目标就留空,不能假装通知已配置;\n8. **询问人类:需要人工干预时,蛇杖用什么语言通知?** 当前完整支持 English(`en`)和简体中文(`zh-CN`)。不要根据错误日志、服务器 locale 或模型输出猜用户语言。\n\n产出一个**经过校验**的 `config.yaml`。新安装默认 `mode: fix`,避免监控装好后因忘记切换而长期不修;启动服务前必须明确告诉人类,`observe` 只作为主动干跑或临时降级。通知语言写入 `notify.language`,同时控制分诊结果中的人类可读字段和最终 gateway 消息。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n### 3.4 人工通知语言\n\n安装时直接问人类:**“蛇杖需要找人干预时,用什么语言通知你?”** 将答案写入 `notify.language`。当前支持:\n\n- `en`:English(旧配置默认值,保持向后兼容);\n- `zh-CN`:简体中文。\n\n这个值同时约束两层:分诊 JSON 的人类可读 `diagnosis` 使用所选语言;通知标题、四段结构和原因指引也使用所选语言。`actions` 会被代码继续解析和执行,因此字符串必须保持英文,或使用结构化 action object。JSON key、enum 和内部审计字段也保持英文,不参与本地化。\n\n不要根据故障 evidence、英文堆栈、系统 `LANG` 或发送渠道猜用户语言。Hermes 的发送命令只负责投递,不保证提供收件人 locale;没有明确答案时必须询问,不能静默推断。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "d4d49c3cb03db6a00ca7dfbcb9f1ac922dad4ca5": {"t": 1785771416.2393186, "n": 8314, "h": "b3e865de7d4f29ec", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. **在启动向导前**运行 `hermes send --list` 查看真实可用目标,让人类选择投递位置并实际发送一条测试消息,例如 `hermes send --to telegram \"Aesculap test\"`。向导本身只接收命令模板、不会替你验证目标;没有可用目标就留空,不能假装通知已配置;\n8. **询问人类:需要人工干预时,蛇杖用什么语言通知?** 当前完整支持 English(`en`)和简体中文(`zh-CN`)。不要根据错误日志、服务器 locale 或模型输出猜用户语言。\n\n产出一个**经过校验**的 `config.yaml`。新安装默认 `mode: fix`,避免监控装好后因忘记切换而长期不修;启动服务前必须明确告诉人类,`observe` 只作为主动干跑或临时降级。通知语言写入 `notify.language`,同时控制分诊结果中的人类可读字段和最终 gateway 消息。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n### 3.4 人工通知语言\n\n安装时直接问人类:**“蛇杖需要找人干预时,用什么语言通知你?”** 将答案写入 `notify.language`。当前支持:\n\n- `en`:English(旧配置默认值,保持向后兼容);\n- `zh-CN`:简体中文。\n\n这个值同时约束两层:分诊 JSON 的人类可读 `diagnosis` 使用所选语言;通知标题、四段结构和原因指引也使用所选语言。`actions` 会被代码继续解析和执行,因此字符串必须保持英文,或使用结构化 action object。JSON key、enum 和内部审计字段也保持英文,不参与本地化。\n\n不要根据故障 evidence、英文堆栈、系统 `LANG` 或发送渠道猜用户语言。Hermes 的发送命令只负责投递,不保证提供收件人 locale;没有明确答案时必须询问,不能静默推断。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "270840d2f6d23b20f32966ef71887879369989e0": {"t": 1785771417.5393512, "n": 8241, "h": "911fc3078a2ce233", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. **在启动向导前**运行 `hermes send --list` 查看真实可用目标,让人类选择投递位置并实际发送一条测试消息,例如 `hermes send --to telegram \"Aesculap test\"`。向导本身只接收命令模板、不会替你验证目标;没有可用目标就留空,不能假装通知已配置;\n8. **询问人类:需要人工干预时,蛇杖用什么语言通知?** 当前完整支持 English(`en`)和简体中文(`zh-CN`)。不要根据错误日志、服务器 locale 或模型输出猜用户语言。\n\n产出一个**经过校验**的 `config.yaml`。通知语言写入 `notify.language`,同时控制分诊结果中的人类可读字段和最终 gateway 消息。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n### 3.4 人工通知语言\n\n安装时直接问人类:**“蛇杖需要找人干预时,用什么语言通知你?”** 将答案写入 `notify.language`。当前支持:\n\n- `en`:English(旧配置默认值,保持向后兼容);\n- `zh-CN`:简体中文。\n\n这个值同时约束两层:分诊 JSON 的人类可读 `diagnosis` 使用所选语言;通知标题、四段结构和原因指引也使用所选语言。`actions` 会被代码继续解析和执行,因此字符串必须保持英文,或使用结构化 action object。JSON key、enum 和内部审计字段也保持英文,不参与本地化。\n\n不要根据故障 evidence、英文堆栈、系统 `LANG` 或发送渠道猜用户语言。Hermes 的发送命令只负责投递,不保证提供收件人 locale;没有明确答案时必须询问,不能静默推断。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "0d68893f5920c612937063cde7a059a5ad182384": {"t": 1785771418.902116, "n": 8120, "h": "f88d93e8aa43368f", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. 填通知发送命令模板(默认复用 Hermes gateway);\n8. **询问人类:需要人工干预时,蛇杖用什么语言通知?** 当前完整支持 English(`en`)和简体中文(`zh-CN`)。不要根据错误日志、服务器 locale 或模型输出猜用户语言。\n\n产出一个**经过校验**的 `config.yaml`。通知语言写入 `notify.language`,同时控制分诊结果中的人类可读字段和最终 gateway 消息。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n### 3.4 人工通知语言\n\n安装时直接问人类:**“蛇杖需要找人干预时,用什么语言通知你?”** 将答案写入 `notify.language`。当前支持:\n\n- `en`:English(旧配置默认值,保持向后兼容);\n- `zh-CN`:简体中文。\n\n这个值同时约束两层:分诊 JSON 的人类可读 `diagnosis` 使用所选语言;通知标题、四段结构和原因指引也使用所选语言。`actions` 会被代码继续解析和执行,因此字符串必须保持英文,或使用结构化 action object。JSON key、enum 和内部审计字段也保持英文,不参与本地化。\n\n不要根据故障 evidence、英文堆栈、系统 `LANG` 或发送渠道猜用户语言。Hermes 的发送命令只负责投递,不保证提供收件人 locale;没有明确答案时必须询问,不能静默推断。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "f154463d09caf8a35ee53d542ce3aaa65dd99dd1": {"t": 1785771420.2014217, "n": 7583, "h": "ff95768eb654b117", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问,并自动写 `.gitignore`,见下注) |\n\n> **git 仓库的干净做法(实测建议):** 若回滚目标是 Hermes 配置目录(如 `~/.hermes/`),**只追踪可回滚资产**(config / skills / scripts),用 `.gitignore` 把运行时产物排除掉——`logs/`、`sessions/`、`cron/output/`、`image_cache/`。否则一个 `git init` 会把几 GB 会话日志拖进仓库,`git reset` 回滚也会被噪声淹没。安装向导的 `git init` 会**自动写入这套 `.gitignore`**(幂等、保留用户已有条目);你也可以手动确认它生效。\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`(会顺手写入排除运行时产物的 `.gitignore`,只追踪 config/skills/scripts);\n6. 选 systemd 档(user / system);\n7. 填通知发送命令模板(默认复用 Hermes gateway)。\n\n产出一个**经过校验**的 `config.yaml`。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "bfa69fa412a34b3fca60e096eb9c9444f8a1bfd9": {"t": 1785771421.5323029, "n": 7208, "h": "7e80de778cc1498b", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问) |\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`;\n6. 选 systemd 档(user / system);\n7. 填通知发送命令模板(默认复用 Hermes gateway)。\n\n产出一个**经过校验**的 `config.yaml`。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的——按修复档位分\n\n#### 🔧 self_fix(自修,第一档)\n**只允许两类动作**,其余一律强制升级(`gate/blast_radius.py` 执行,LLM 建议无效):\n\n| 动作 | 实现方式 | 说明 |\n|------|---------|------|\n| `write_file` | `Path.write_text(content)`,**不经过 shell** | 分诊模型在 JSON 里直接给出文件新内容;改前备份,验证失败自动回滚 |\n| `restart_process` | `subprocess.run(argv, shell=False)` | 重启指定进程;命令经过 tripwire 扫描后才执行 |\n\n**self_fix 绝对不能运行任意 shell 命令(§6.2)。** 任意命令(`RUN_COMMAND`)的爆炸半径本质未知——\n即使命令看起来无害,只要 LLM 在 self_fix 路由下提议 `RUN_COMMAND`,`blast_radius.py`\n就会强制升级为 `coding_agent` 或 `human`,`confidence` 再高也拦不住。\n\n#### 🤖 coding_agent(外部工具,第二档)\n调 Claude Code CLI(`claude -p`)或 Codex CLI,在 git 仓库内操作。\n它可以运行命令、修改多个文件,但改动落 git commit,失败 `git reset` 回滚。\n\n#### 📢 human(通知人类,第三档)\n任何 coding_agent 失败或不可用时,通知你(四件套:哪坏了 / 试过什么 / 要你做什么 / 一行指引)。\n\n### ✅ 可以改的文件范围\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}, "7569041831ac416999cf3e448864b383130f6f42": {"t": 1785771422.961051, "n": 6457, "h": "f8691f0079b1c19f", "c": "# AGENT.md — Aesculap 安装与运维操作手册(给 Hermes agent 读)\n\n> **你是谁,在读什么。** 你是一个 Hermes agent。你的人类让你「装上这个自愈插件」。\n> 这份文档是给**你**(agent)看的操作手册,不是给人看的——人看 [`README.md`](./README.md)。\n> 照着下面的步骤做:自检环境 → 引导人类做必要决策 → 装好 → 交接。\n>\n> **贯穿全程的最高原则(PRD §1):LLM 提议,代码拍板。** 你只负责诊断和建议;\n> 能不能动手、动到什么程度,由 `aesculap/gate/` 的确定性代码裁决,你跨不过去。\n> 安装阶段同理——**凡是涉及「给多大权限」「用哪个模型」「碰不碰敏感文件」的决策,\n> 你必须把选项摆给人类、让人类拍板,不要替人类决定。**\n\n---\n\n## 0. 这是什么\n\nAesculap 是装在 Hermes 旁边的**常驻自愈守护进程**。它实时检测 Hermes 故障,在人类授权的\n安全边界内自动修复,修不了就升级到外部编码工具(Claude Code / Codex),再不行就通知人类。\n\n它由 systemd 托管(崩溃自动拉起),但**从不自我重启、从不修改自己的目录**(§9.3)。\n\n---\n\n## 1. 先做环境自检(只读,不改任何东西)\n\n动手装之前,先把下面这些查清楚,并把结果讲给人类听。**全部是只读探测,不要在这一步改任何文件。**\n\n### 1.1 运行时与仓库前置\n\n| 检查项 | 怎么查 | 不满足怎么办 |\n|--------|--------|-------------|\n| Python ≥ 3.11 | `python --version` | 提示人类升级,停在这一步 |\n| 项目在 git 仓库内(§7.1 前置) | `git -C <项目目录> rev-parse --is-inside-work-tree` | **必须**——自修靠 `git reset` 回滚。不在仓库内就引导人类 `git init`(向导会主动问) |\n| Hermes 日志落到**文件**(§2 前置) | 看 `~/.hermes/logs/` 下有没有日志文件 | Hermes 默认只 stdout。**必须先让 Hermes 把输出写进日志文件**(建议 `~/.hermes/logs/hermes.log`),否则日志监听无从谈起。引导人类改 Hermes 配置 |\n| systemd 可用 | `systemctl --user` 能用 / 有没有 root | 决定装 user 档还是 system 档(见 §4) |\n\n### 1.2 自检「有哪些模型可选」(§5.1)\n\nAesculap 需要两个 LLM 角色(可以是同一个,也可以分开):\n\n- **分诊模型(triage)**:判断故障性质、提议修复路线。**建议用强模型**——它判断错了会连累整条链路。\n- **自修模型(selffix)**:执行具体小修。可以用便宜些的模型。\n\n**怎么查有哪些 provider 可用:看环境变量里有哪些 API key(只看「在不在」,绝不读取值):**\n\n```bash\n# 安装向导内置了这套自检,但你也可以自己先看一眼:\n[ -n \"$ANTHROPIC_API_KEY\" ] && echo \"anthropic available\"\n[ -n \"$OPENAI_API_KEY\" ] && echo \"openai available\"\n```\n\n支持的 provider:`openai`、`anthropic`、`openai_compatible`(自建/兼容端点,如 vLLM、Ollama,需填 `base_url`)。\n**设计上不硬编码任何具体模型名**——具体型号由人类填,你只负责给建议。\n\n### 1.3 自检「能不能升级到编码工具」(§6.4)\n\n```bash\nwhich claude # Claude Code CLI\nwhich codex # Codex CLI\n```\n\n装了哪个,自修失败时就能升级给它接手。两个都没有,`coding_agent` 这一档会**自动降级为直接通知人类**——不会假装能修。\n\n### 1.4 自检「哪些是身份文件」(决策 #1,§9.2)\n\n扫 Hermes 配置目录(默认 `~/.hermes`),列出疑似**人格 / 记忆 / 身份**文件候选(`SOUL.md`、`MEMORY.md`、`USER.md`、`persona.md`、`identity.md` 等)。\n**这些是要写进黑名单、永远禁止改动的候选。** 安装向导会把候选列给人类勾选——**不要自己静默决定**,让人类确认要锁哪些。\n\n---\n\n## 2. 安装\n\n```bash\n# 1) 装包 + 按需装 provider SDK(薄适配,不引 litellm)\npip install -e \".[openai,anthropic]\" # 按 §1.2 自检结果,装实际用得到的\n\n# 2) 跑交互式安装向导(它会把 §1 的自检自动跑一遍,并引导人类做决策)\npython -m aesculap install ./config.yaml\n```\n\n向导会依次做:\n1. 问项目目录、Hermes 配置目录;\n2. **强制人类选权限档 A/B/C**(无默认值,见 §3);\n3. 扫身份文件候选 → 让人类勾选写入黑名单(决策 #1);\n4. 列出已配置的 provider → 让人类选分诊模型,并填型号(见 §1.2);\n5. 检查 file logging 与 git 前置,缺 git 仓库时主动问要不要 `git init`;\n6. 选 systemd 档(user / system);\n7. 填通知发送命令模板(默认复用 Hermes gateway)。\n\n产出一个**经过校验**的 `config.yaml`。然后装 systemd 单元:\n\n```bash\npython -m aesculap install-systemd ./config.yaml --scope user # 打印单元 + enable 指令\npython -m aesculap install-systemd ./config.yaml --scope user --write # 真正写入\n```\n\n---\n\n## 3. 你必须让人类拍板的决策(不要自己定)\n\n### 3.1 权限档 A/B/C —— 这是最重要的一次授权\n\n**无默认值,必须人类显式选。** 你的职责是把风险讲清楚,并给出**保守建议**:\n\n| 档位 | 可写范围 | 你应当怎么建议 |\n|------|---------|---------------|\n| **A** | 仅项目目录 | **默认推荐这个。** 绝大多数情况够用且最安全 |\n| **B** | Hermes 配置目录 + 项目目录 | 仅当这台机是 Hermes 专用机才建议 |\n| **C** | 整台机器 | **强烈劝阻,除非整机只跑 Hermes、无其他重要数据。** 向导会二次确认 + 追问是否专用机,非专用一律中止 |\n\n> 如果人类说不清这台机器是干嘛的,**默认按 A 走**,并说明为什么保守。不要主动鼓励选 B/C。\n\n### 3.2 模型选择\n\n- 分诊:建议强模型(判断质量直接影响安全)。\n- 自修:可便宜些。\n- provider 从 §1.2 自检到的里面选;型号名由人类填(设计上不替人类钦定)。\n\n### 3.3 🔑 API key 安全铁律(§8.3,**不可违反**)\n\n- **永远不要让人类把 key 粘进聊天框 / 日志 / 任何会被记录的地方。**\n- **永远不要回显、打印、转述任何 key 的值。**\n- 配置里只存**环境变量的名字**(如 `api_key_env: ANTHROPIC_API_KEY`),**绝不存 key 本身**。\n- 需要 key 时,你只告诉人类**key 该放在哪**(哪个文件 / 哪个环境变量 + 格式示例),让人类自己去设。\n- 这条在安装期和运行期都生效。运行期需要凭证时同理:只说「去哪填」,绝不要值。\n\n---\n\n## 4. systemd 托管\n\n| 档 | 路径 | 需要 root | 特性 |\n|----|------|----------|------|\n| `--scope user` | `~/.config/systemd/user/` | 否 | 推荐;可能需 `loginctl enable-linger` 让它在你登出后仍运行 |\n| `--scope system` | `/etc/systemd/system/` | 是 | 开机自启 |\n\n单元里 `Restart=always`、`NoNewPrivileges=true`。**Aesculap 崩了由 systemd 拉起,但它自己绝不自重启**(§9.3,防递归自修灾难)。\n\n---\n\n## 5. 装好之后它有多大权力?能改什么、不能改什么\n\n这是你(和人类)最该弄清的部分。**边界由代码强制,不是靠你自觉。**\n\n### ✅ 它**能**改的\n\n- 在人类所选**权限档边界内**(A=项目目录 / B=+配置目录 / C=整机)的、**不在黑名单里**的文件。\n- 默认放行(default-allow):边界内除黑名单外都可改。\n\n### ⛔ 它**永远不能**改的(硬写死在 `gate/scope.py`,配置放宽不了,只能加严)\n\n| 类别 | 具体 | 依据 |\n|------|------|------|\n| 🧠 身份文件 | `SOUL.md` / `MEMORY.md` / `USER.md` / persona / identity 等(人类勾选的那批) | §9.2 |\n| 🔑 凭证文件 | `.env` / `.env.*` / `*.key` / `*.pem` / `*.p12` / `id_rsa` / `credentials` / `.netrc` / `.git-credentials`,以及文件名含 `secret`/`token`/`apikey`/`password` 的 | §9.2 |\n| 🔒 只读文件 | 没有 owner 写位的(≈ `chmod 444`) | §9.2 |\n| ⚙️ 自身目录 | `aesculap_home` 及其下一切(不能自己改自己) | §9.3 |\n| 🖥️ 系统敏感路径 | `/etc` `/boot` `/usr` `/bin` `/sbin` `/lib` `/lib64` `/sys` `/proc` `/dev` `/var/lib` `/root/.ssh`——**即使选了 C 档也排除** | §9.2 |\n\n### ⛔ 被硬绊线拦死的**操作**(`gate/tripwires.py`,一律转人工)\n\n- 危险命令:`rm` / `rmdir` / `shred` / `mkfs` / `dd`,以及 `rm -rf`、`> /dev/sd*`、`chmod -R` 这类形状;\n- `git push --force` / `--force-with-lease` / `-f`;\n- **删文件**(即使在范围内,删除是破坏性的,默认转人工);\n- 触碰**计费 / 付费接口**(含 billing/payment/checkout/invoice 等字样)。\n\n### 路由由「爆炸半径」强制(§6.2)\n\n闸门不看「难不难」,看「炸得多大」。即使分诊模型自信地说 `self_fix`(自修),只要改动是\n**多文件 / 基础设施级 / 不可逆 / 范围未知**,代码也会强制升级,不让自修。`confidence` 置信度**从不**用作放行依据,只记录。\n\n---\n\n## 6. 出故障时它会怎么走(升级阶梯,只升不降,§6.3)\n\n```\n检测到故障 → 去抖确认(§4) → Tier 0 探针复查 → 分诊(提议) → ★代码闸门(裁决)\n │\n self_fix(≤3 次) 备份→改→全量验证→观察窗口;失败→先重新诊断→回滚→升级\n │ 失败\n coding_agent git 内 checkpoint→调 claude/codex→验证;失败→git reset→升级\n │ 失败 / 未装\n human 四件套通知你:哪坏了 · 试过什么 · 要你做什么 · 一行指引\n```\n\n- **全量验证判据(决策 #2)**:原本 FAIL 的探针转 OK 即算修好;其余探针维持原状即可,**不要求全绿**。\n- **级联保护(§7.3)**:多个探针同时 FAIL → 判为系统级 → 直接喊人,不浪费 token 去分诊。\n- **观察窗口**:修完盯一段时间,确认没复发才收工。\n\n---\n\n## 7. 装完自检 + 交接\n\n```bash\npython -m aesculap config ./config.yaml # 校验配置合法\npython -m aesculap probe ./config.yaml # 跑一遍 Tier 0 探针,看当前健康基线\npython -m aesculap status ./config.yaml # 模式 / 开关 / 最近审计 / 挂起问题\n```\n\n确认无误后,告诉人类:\n\n1. 装好了,权限档是 **X**(复述你们选的那档及含义);\n2. 分诊 / 自修分别用什么模型;\n3. **控制权在他手里**:`disable` 一键全停、`mode observe` 只看不动手、`mode fix` 恢复(细节见 README);\n4. 出事会怎么通知他、通过哪个通道。\n\n---\n\n## 8. 你自己运维时的红线(复诵一遍,别越界)\n\n- **代码拍板,不是你拍板。** 你的路由建议只是建议,闸门可以推翻你。\n- **绝不碰**:身份文件、凭证、只读文件、系统路径、Aesculap 自身目录(§8.1/§9)。\n- **绝不执行**:`rm`、`git push --force`、删文件、计费接口(§8.1)。\n- **key 只说去哪填,绝不要值、绝不回显**(§8.3)。\n- **拿不准就升级喊人,不猜、不硬上。** 分诊返回看不懂(JSON 解析失败 / 字段非法 / 缺 `route`)→ 直接降级 human,不猜不重试(决策 #3)。\n- **怀疑自己判断飘了**,建议人类切 `observe` 模式(只检测不动手)。\n\n> 完整规约见 [`Aesculap_PRD.md`](./Aesculap_PRD.md)。配置字段示例见\n> [`aesculap/resources/config.example.yaml`](./aesculap/resources/config.example.yaml)。\n"}}, "SKILL.md": {"70052aa3d0e026cf57ca47d262aa45b12b24de4e": {"t": 1785747213.6985729, "n": 15250, "h": "50d93f0cd2c3236c", "c": "---\nname: aesculap-hermes\ndescription: Use when a user asks an agent to install, configure, validate, operate, or troubleshoot Aesculap, the safety-gated self-healing daemon for Hermes Agent. Guides environment discovery, explicit permission-tier selection, provider setup without exposing keys, notification target and language confirmation, explicit fix-mode disclosure, systemd installation, and end-to-end verification.\nversion: 0.1.0\nauthor: banxia-O\nlicense: MIT\nmetadata:\n hermes:\n tags: [hermes, self-healing, reliability, systemd, monitoring, incident-response]\n related_skills: [hermes-agent]\n---\n\n# Aesculap for Hermes Agent\n\n## Overview\n\nAesculap is a resident health-monitoring and recovery daemon for Hermes Agent. It detects persistent failures, asks an LLM to diagnose and propose a route, then lets deterministic code decide whether any action is allowed. Safe, bounded repairs may run automatically; risky, ambiguous, repeated, or unsupported cases escalate to a coding agent or a human.\n\nThis skill is the installation and operations entrypoint. Read [`AGENT.md`](./AGENT.md) for the complete agent-facing manual, [`README.md`](./README.md) for the product overview, and [`Aesculap_PRD.md`](./Aesculap_PRD.md) when auditing design decisions.\n\n**Core invariant:** the LLM proposes; code gates decide. Never describe Aesculap as unrestricted autonomous repair.\n\n## When to Use\n\nUse this skill when the user asks to:\n\n- install Aesculap beside a Hermes deployment;\n- configure probes, providers, permission boundaries, or notifications;\n- choose between permission tiers A/B/C;\n- run Aesculap in observe or fix mode;\n- install or troubleshoot the systemd service;\n- inspect status, audit records, or pending escalations;\n- verify whether human-intervention notifications actually arrive.\n\nDo not use it as a generic server-monitoring guide, a replacement for backups, or authorization to edit identity files, credentials, billing settings, or unrelated applications.\n\n## Operating Contract\n\nBefore writing files or starting a service, explain and obtain explicit answers for every consequential decision below.\n\n| Decision | Required behavior |\n|---|---|\n| Writable scope | Present A/B/C with risks. Recommend A. Never silently choose C. |\n| Identity files | Show detected candidates and let the user confirm the immutable list. |\n| Triage provider/model | Detect configured providers by key presence only; never read or print key values. Include OpenAI-compatible domestic services such as DeepSeek, GLM, and Kimi/Moonshot instead of assuming OpenAI or Anthropic. |\n| Coding-agent escalation | Report whether Claude Code, Codex, or another supported tool is actually available. |\n| Notification target | Run `hermes send --list`; let the user choose a real destination; send a test message. |\n| Notification language | Ask: **“Aesculap needs human intervention. Which language should it use to notify you: English or Simplified Chinese?”** Persist the answer as `notify.language`. |\n| Service scope | Ask whether systemd should use user or system scope. Prefer user scope unless system scope is necessary. |\n| Activation mode | New installs default to `fix` so protection is active immediately. State this before service start. Switch to `observe` only when the user explicitly wants a dry run or temporary safety downgrade. |\n\nNever infer notification language from logs, stack traces, server locale, model output, or an occasional message. Supported values are `en` and `zh-CN`; legacy configurations without the field default to `en`.\n\n## Installation Workflow\n\n### 1. Read-only preflight\n\nRun these checks without changing the system:\n\n```bash\npython3 --version\ngit -C <project-root> rev-parse --is-inside-work-tree\nhermes --version\nhermes gateway status\nhermes send --list\ncommand -v systemctl || true\ncommand -v claude || true\ncommand -v codex || true\n```\n\nAlso inspect:\n\n- whether Hermes writes logs to a file that Aesculap can watch;\n- whether the protected project is a git repository;\n- whether `~/.hermes` or the active profile contains identity files such as `SOUL.md`, `MEMORY.md`, `USER.md`, persona, or identity documents;\n- which provider environment variables exist, checking only presence;\n- available disk space and Python ≥ 3.11.\n\n**Completion criterion:** report every prerequisite as pass, missing, or intentionally disabled. Do not begin installation while file logging or the intended rollback repository is unresolved.\n\n### 2. Ask for the safety boundary\n\nPresent the tiers in plain language:\n\n- **A — project tree only:** safest and recommended for most users.\n- **B — Hermes configuration plus project tree:** only for a dedicated Hermes host and only after identity/credential exclusions are confirmed.\n- **C — whole host:** highest risk. Use only after explicit user selection and confirmation that the machine is dedicated and contains no unrelated important data.\n\nAesculap still hard-blocks identity files, credentials, its own directory, read-only files, sensitive system paths, destructive commands, force pushes, deletion, and billing/payment operations. A larger tier never removes those hard tripwires.\n\n**Completion criterion:** record the user’s explicit tier and immutable identity-file choices. If the user is uncertain, stop at A.\n\n### 3. Prepare an isolated Python environment\n\nFrom the repository or SkillHub-installed directory:\n\n```bash\npython3 -m venv .venv\n.venv/bin/python -m pip install --upgrade pip\n.venv/bin/pip install -e .\n```\n\nInstall only the provider extras actually selected:\n\n```bash\n.venv/bin/pip install -e '.[openai]'\n# or\n.venv/bin/pip install -e '.[anthropic]'\n# or both only when both are genuinely needed\n```\n\nThe `openai` extra also powers `openai_compatible` endpoints. Domestic services can be used directly; self-hosting is optional, not required. For example:\n\n```yaml\ntriage:\n provider: openai_compatible\n model: deepseek-v4-pro\n base_url: https://api.deepseek.com/v1\n api_key_env: DEEPSEEK_API_KEY\n```\n\nThe same adapter supports GLM, Kimi/Moonshot, Ollama, and vLLM when they expose an OpenAI-compatible endpoint. Use each provider's real model ID, base URL, and key environment-variable name; do not reuse the DeepSeek values for another provider.\n\nNever paste API keys into chat or `config.yaml`. The configuration stores environment-variable names such as `OPENAI_API_KEY`, not secret values. Tell the user which approved environment file or service environment to edit, then verify only that the variable exists.\n\n**Completion criterion:** `.venv/bin/aesculap --version` exits successfully and no credential value appears in shell history, logs, config, or chat.\n\n### 4. Resolve notification delivery before running the wizard\n\nList actual Hermes destinations:\n\n```bash\nhermes send --list\n```\n\nAsk the user which destination should receive human-intervention alerts. Build a command template from a real target, for example:\n\n```yaml\nnotify:\n command_template: \"hermes send --to telegram {message}\"\n```\n\nTargets may be a platform home channel or an explicit platform/chat/thread destination. Use the exact syntax shown by `hermes send --help` on the installed Hermes version. Test the target before relying on it:\n\n```bash\nhermes send --to <target> \"Aesculap notification test\"\n```\n\nIf no destination is available, leave `notify.command_template` empty and state clearly that escalations will be audited but not delivered. Never retain an obsolete notification subcommand copied from an older Hermes release.\n\nThen ask the language question and retain the explicit answer:\n\n- English → `notify.language: en`\n- 简体中文 → `notify.language: zh-CN`\n\nThe selected language controls the human-readable triage diagnosis and final notification shell. Machine-consumed action strings, JSON keys, enum values, and audit fields remain stable English or structured objects.\n\n**Completion criterion:** either a real test message arrived at the user-selected destination, or delivery is explicitly marked disabled; the chosen language is documented.\n\n### 5. Run the interactive installer\n\n```bash\n.venv/bin/aesculap install ./config.yaml\n```\n\nUse the answers already confirmed with the user. Do not reinterpret them during the CLI wizard. When asked for the notification template, paste the verified template or leave it blank. When asked for notification language, enter `en` or `zh-CN` exactly.\n\nAfter generation, inspect the configuration without printing secret values:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n```\n\nConfirm at minimum:\n\n- `scope.tier` matches the user’s choice;\n- project and Hermes paths are correct;\n- identity files are protected;\n- provider and model names are intended;\n- `notify.command_template` is either tested or empty;\n- `notify.language` matches the explicit answer;\n- `mode` is `fix` unless the user deliberately requested `observe`;\n- no API key value is stored in YAML.\n\n**Completion criterion:** config validation exits 0 and every consequential field matches a user-confirmed decision.\n\n### 6. Establish a health baseline before service start\n\nNew configurations default to `fix`; this avoids a monitoring-only install being forgotten. Before starting the resident service, state plainly that bounded repairs may run within the selected tier, then inspect the baseline:\n\n```bash\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\n```\n\nA failing probe is not automatically an installer failure. Determine whether it reflects a real Hermes issue, an incorrect path, or a probe that should be disabled. Do not start the service merely to make the output green.\n\nIf the user explicitly wants a dry run or a temporary safety downgrade, switch modes before service start:\n\n```bash\n.venv/bin/aesculap mode observe ./config.yaml\n```\n\n**Completion criterion:** every enabled probe has an explained result, the active mode is stated to the user, and `fix` remains enabled unless the user deliberately selected `observe`.\n\n### 7. Install systemd with a dry run first\n\nRender the unit before writing it:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user\n# or, only if explicitly selected:\n.venv/bin/aesculap install-systemd ./config.yaml --scope system\n```\n\nReview the executable path, working directory, config path, service user, and hardening directives. Then install only after approval:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user --write\n```\n\nUse the enable/start command printed by the installer. For user services that must survive logout, check whether linger is required before enabling it.\n\n**Completion criterion:** systemd reports the unit active, the process uses the intended `.venv`, and logs show one clean startup rather than a restart loop.\n\n### 8. Verify end to end\n\nRun:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\nsystemctl --user status aesculap.service --no-pager\n```\n\nAdapt the final command for system scope. Inspect recent audit entries and service logs. Trigger only a harmless, reversible test condition or use a test fixture; do not break a production agent merely to prove recovery.\n\nVerify separately:\n\n1. Aesculap detects and audits the test event.\n2. In default `fix` mode, every attempted repair remains inside the selected tier and deterministic gate; if the user selected `observe`, no repair runs.\n3. A human escalation reaches the configured target.\n4. The title, diagnosis, headings, and guidance use the chosen language.\n5. Technical evidence may remain in its original language but credentials are redacted.\n6. Repeated equivalent events respect deduplication/cooldown.\n\nIf the user temporarily selected `observe`, restore the normal active mode once the dry run is complete unless they explicitly choose to remain observation-only:\n\n```bash\n.venv/bin/aesculap mode fix ./config.yaml\n```\n\n**Completion criterion:** detection, audit, delivery, language, redaction, safety-gate behavior, and service health are all verified with real output; the final mode is stated explicitly.\n\n## Routine Operations\n\n```bash\n.venv/bin/aesculap status ./config.yaml\n.venv/bin/aesculap mode observe ./config.yaml\n.venv/bin/aesculap mode fix ./config.yaml\n.venv/bin/aesculap disable ./config.yaml\n.venv/bin/aesculap enable ./config.yaml\n.venv/bin/aesculap stop\n```\n\nUse `observe` immediately when a diagnosis or repair route appears suspicious. `disable` is the master stop for Aesculap behavior; stopping the systemd service additionally stops the daemon process.\n\nWhen a notification requests a credential, tell the user which environment variable and file need attention. Never request, echo, transmit, or log the credential itself.\n\n## Common Pitfalls\n\n1. **Accepting an obsolete notification command.** Current Hermes uses `hermes send`; verify with live `--help` and `--list`. An untested template means notification delivery is not configured.\n2. **Guessing the user’s language.** Always ask during installation. Logs and locale are evidence about software, not the person receiving alerts.\n3. **Localizing machine actions.** `actions` are parsed downstream. Keep strings in English or use structured action objects; localize only human-facing diagnosis and notification copy.\n4. **Leaving a new install in observation-only mode by accident.** New installs default to `fix` so protection is active. Use `observe` deliberately for a dry run or incident downgrade, and record whether/when it should return to `fix`.\n5. **Treating tier C as unrestricted root.** Hard tripwires and protected paths still apply. C is not permission to edit identity, credentials, billing, or Aesculap itself.\n6. **Running without git rollback.** Resolve the intended rollback repository before enabling repairs.\n7. **Claiming success from config validation alone.** A complete install requires service health, probe results, a real notification test, and language verification.\n8. **Mixing project source with production dirty changes.** Use an isolated worktree for development and preserve the deployed checkout until changes are reviewed and deliberately rolled out.\n\n## Verification Checklist\n\n- [ ] Python ≥ 3.11 and isolated `.venv` are in use\n- [ ] Hermes file logging and project git rollback are available\n- [ ] Permission tier and identity-file protections were explicitly confirmed\n- [ ] Provider choice was detected without reading or printing secrets\n- [ ] `hermes send --list` was checked on the live installation\n- [ ] Notification target was tested or explicitly disabled\n- [ ] Notification language was explicitly selected and persisted\n- [ ] `config`, `probe`, and `status` commands were exercised\n- [ ] Initial mode is `fix`, unless the user deliberately selected `observe`\n- [ ] User was told that starting the service in `fix` permits bounded repairs within the selected tier\n- [ ] systemd unit was reviewed before `--write`\n- [ ] Audit, notification delivery, localization, and redaction were verified end to end\n- [ ] Any deliberate use of `observe` includes a recorded decision about whether/when to restore `fix`\n- [ ] Final report states scope tier, mode, service status, notification target/language, and unresolved probe failures\n"}, "c69ed897b84d6bc9727cdaf96055a8d52e2a2a7c": {"t": 1785771414.0902727, "n": 15250, "h": "50d93f0cd2c3236c", "c": "---\nname: aesculap-hermes\ndescription: Use when a user asks an agent to install, configure, validate, operate, or troubleshoot Aesculap, the safety-gated self-healing daemon for Hermes Agent. Guides environment discovery, explicit permission-tier selection, provider setup without exposing keys, notification target and language confirmation, explicit fix-mode disclosure, systemd installation, and end-to-end verification.\nversion: 0.1.0\nauthor: banxia-O\nlicense: MIT\nmetadata:\n hermes:\n tags: [hermes, self-healing, reliability, systemd, monitoring, incident-response]\n related_skills: [hermes-agent]\n---\n\n# Aesculap for Hermes Agent\n\n## Overview\n\nAesculap is a resident health-monitoring and recovery daemon for Hermes Agent. It detects persistent failures, asks an LLM to diagnose and propose a route, then lets deterministic code decide whether any action is allowed. Safe, bounded repairs may run automatically; risky, ambiguous, repeated, or unsupported cases escalate to a coding agent or a human.\n\nThis skill is the installation and operations entrypoint. Read [`AGENT.md`](./AGENT.md) for the complete agent-facing manual, [`README.md`](./README.md) for the product overview, and [`Aesculap_PRD.md`](./Aesculap_PRD.md) when auditing design decisions.\n\n**Core invariant:** the LLM proposes; code gates decide. Never describe Aesculap as unrestricted autonomous repair.\n\n## When to Use\n\nUse this skill when the user asks to:\n\n- install Aesculap beside a Hermes deployment;\n- configure probes, providers, permission boundaries, or notifications;\n- choose between permission tiers A/B/C;\n- run Aesculap in observe or fix mode;\n- install or troubleshoot the systemd service;\n- inspect status, audit records, or pending escalations;\n- verify whether human-intervention notifications actually arrive.\n\nDo not use it as a generic server-monitoring guide, a replacement for backups, or authorization to edit identity files, credentials, billing settings, or unrelated applications.\n\n## Operating Contract\n\nBefore writing files or starting a service, explain and obtain explicit answers for every consequential decision below.\n\n| Decision | Required behavior |\n|---|---|\n| Writable scope | Present A/B/C with risks. Recommend A. Never silently choose C. |\n| Identity files | Show detected candidates and let the user confirm the immutable list. |\n| Triage provider/model | Detect configured providers by key presence only; never read or print key values. Include OpenAI-compatible domestic services such as DeepSeek, GLM, and Kimi/Moonshot instead of assuming OpenAI or Anthropic. |\n| Coding-agent escalation | Report whether Claude Code, Codex, or another supported tool is actually available. |\n| Notification target | Run `hermes send --list`; let the user choose a real destination; send a test message. |\n| Notification language | Ask: **“Aesculap needs human intervention. Which language should it use to notify you: English or Simplified Chinese?”** Persist the answer as `notify.language`. |\n| Service scope | Ask whether systemd should use user or system scope. Prefer user scope unless system scope is necessary. |\n| Activation mode | New installs default to `fix` so protection is active immediately. State this before service start. Switch to `observe` only when the user explicitly wants a dry run or temporary safety downgrade. |\n\nNever infer notification language from logs, stack traces, server locale, model output, or an occasional message. Supported values are `en` and `zh-CN`; legacy configurations without the field default to `en`.\n\n## Installation Workflow\n\n### 1. Read-only preflight\n\nRun these checks without changing the system:\n\n```bash\npython3 --version\ngit -C <project-root> rev-parse --is-inside-work-tree\nhermes --version\nhermes gateway status\nhermes send --list\ncommand -v systemctl || true\ncommand -v claude || true\ncommand -v codex || true\n```\n\nAlso inspect:\n\n- whether Hermes writes logs to a file that Aesculap can watch;\n- whether the protected project is a git repository;\n- whether `~/.hermes` or the active profile contains identity files such as `SOUL.md`, `MEMORY.md`, `USER.md`, persona, or identity documents;\n- which provider environment variables exist, checking only presence;\n- available disk space and Python ≥ 3.11.\n\n**Completion criterion:** report every prerequisite as pass, missing, or intentionally disabled. Do not begin installation while file logging or the intended rollback repository is unresolved.\n\n### 2. Ask for the safety boundary\n\nPresent the tiers in plain language:\n\n- **A — project tree only:** safest and recommended for most users.\n- **B — Hermes configuration plus project tree:** only for a dedicated Hermes host and only after identity/credential exclusions are confirmed.\n- **C — whole host:** highest risk. Use only after explicit user selection and confirmation that the machine is dedicated and contains no unrelated important data.\n\nAesculap still hard-blocks identity files, credentials, its own directory, read-only files, sensitive system paths, destructive commands, force pushes, deletion, and billing/payment operations. A larger tier never removes those hard tripwires.\n\n**Completion criterion:** record the user’s explicit tier and immutable identity-file choices. If the user is uncertain, stop at A.\n\n### 3. Prepare an isolated Python environment\n\nFrom the repository or SkillHub-installed directory:\n\n```bash\npython3 -m venv .venv\n.venv/bin/python -m pip install --upgrade pip\n.venv/bin/pip install -e .\n```\n\nInstall only the provider extras actually selected:\n\n```bash\n.venv/bin/pip install -e '.[openai]'\n# or\n.venv/bin/pip install -e '.[anthropic]'\n# or both only when both are genuinely needed\n```\n\nThe `openai` extra also powers `openai_compatible` endpoints. Domestic services can be used directly; self-hosting is optional, not required. For example:\n\n```yaml\ntriage:\n provider: openai_compatible\n model: deepseek-v4-pro\n base_url: https://api.deepseek.com/v1\n api_key_env: DEEPSEEK_API_KEY\n```\n\nThe same adapter supports GLM, Kimi/Moonshot, Ollama, and vLLM when they expose an OpenAI-compatible endpoint. Use each provider's real model ID, base URL, and key environment-variable name; do not reuse the DeepSeek values for another provider.\n\nNever paste API keys into chat or `config.yaml`. The configuration stores environment-variable names such as `OPENAI_API_KEY`, not secret values. Tell the user which approved environment file or service environment to edit, then verify only that the variable exists.\n\n**Completion criterion:** `.venv/bin/aesculap --version` exits successfully and no credential value appears in shell history, logs, config, or chat.\n\n### 4. Resolve notification delivery before running the wizard\n\nList actual Hermes destinations:\n\n```bash\nhermes send --list\n```\n\nAsk the user which destination should receive human-intervention alerts. Build a command template from a real target, for example:\n\n```yaml\nnotify:\n command_template: \"hermes send --to telegram {message}\"\n```\n\nTargets may be a platform home channel or an explicit platform/chat/thread destination. Use the exact syntax shown by `hermes send --help` on the installed Hermes version. Test the target before relying on it:\n\n```bash\nhermes send --to <target> \"Aesculap notification test\"\n```\n\nIf no destination is available, leave `notify.command_template` empty and state clearly that escalations will be audited but not delivered. Never retain an obsolete notification subcommand copied from an older Hermes release.\n\nThen ask the language question and retain the explicit answer:\n\n- English → `notify.language: en`\n- 简体中文 → `notify.language: zh-CN`\n\nThe selected language controls the human-readable triage diagnosis and final notification shell. Machine-consumed action strings, JSON keys, enum values, and audit fields remain stable English or structured objects.\n\n**Completion criterion:** either a real test message arrived at the user-selected destination, or delivery is explicitly marked disabled; the chosen language is documented.\n\n### 5. Run the interactive installer\n\n```bash\n.venv/bin/aesculap install ./config.yaml\n```\n\nUse the answers already confirmed with the user. Do not reinterpret them during the CLI wizard. When asked for the notification template, paste the verified template or leave it blank. When asked for notification language, enter `en` or `zh-CN` exactly.\n\nAfter generation, inspect the configuration without printing secret values:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n```\n\nConfirm at minimum:\n\n- `scope.tier` matches the user’s choice;\n- project and Hermes paths are correct;\n- identity files are protected;\n- provider and model names are intended;\n- `notify.command_template` is either tested or empty;\n- `notify.language` matches the explicit answer;\n- `mode` is `fix` unless the user deliberately requested `observe`;\n- no API key value is stored in YAML.\n\n**Completion criterion:** config validation exits 0 and every consequential field matches a user-confirmed decision.\n\n### 6. Establish a health baseline before service start\n\nNew configurations default to `fix`; this avoids a monitoring-only install being forgotten. Before starting the resident service, state plainly that bounded repairs may run within the selected tier, then inspect the baseline:\n\n```bash\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\n```\n\nA failing probe is not automatically an installer failure. Determine whether it reflects a real Hermes issue, an incorrect path, or a probe that should be disabled. Do not start the service merely to make the output green.\n\nIf the user explicitly wants a dry run or a temporary safety downgrade, switch modes before service start:\n\n```bash\n.venv/bin/aesculap mode observe ./config.yaml\n```\n\n**Completion criterion:** every enabled probe has an explained result, the active mode is stated to the user, and `fix` remains enabled unless the user deliberately selected `observe`.\n\n### 7. Install systemd with a dry run first\n\nRender the unit before writing it:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user\n# or, only if explicitly selected:\n.venv/bin/aesculap install-systemd ./config.yaml --scope system\n```\n\nReview the executable path, working directory, config path, service user, and hardening directives. Then install only after approval:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user --write\n```\n\nUse the enable/start command printed by the installer. For user services that must survive logout, check whether linger is required before enabling it.\n\n**Completion criterion:** systemd reports the unit active, the process uses the intended `.venv`, and logs show one clean startup rather than a restart loop.\n\n### 8. Verify end to end\n\nRun:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\nsystemctl --user status aesculap.service --no-pager\n```\n\nAdapt the final command for system scope. Inspect recent audit entries and service logs. Trigger only a harmless, reversible test condition or use a test fixture; do not break a production agent merely to prove recovery.\n\nVerify separately:\n\n1. Aesculap detects and audits the test event.\n2. In default `fix` mode, every attempted repair remains inside the selected tier and deterministic gate; if the user selected `observe`, no repair runs.\n3. A human escalation reaches the configured target.\n4. The title, diagnosis, headings, and guidance use the chosen language.\n5. Technical evidence may remain in its original language but credentials are redacted.\n6. Repeated equivalent events respect deduplication/cooldown.\n\nIf the user temporarily selected `observe`, restore the normal active mode once the dry run is complete unless they explicitly choose to remain observation-only:\n\n```bash\n.venv/bin/aesculap mode fix ./config.yaml\n```\n\n**Completion criterion:** detection, audit, delivery, language, redaction, safety-gate behavior, and service health are all verified with real output; the final mode is stated explicitly.\n\n## Routine Operations\n\n```bash\n.venv/bin/aesculap status ./config.yaml\n.venv/bin/aesculap mode observe ./config.yaml\n.venv/bin/aesculap mode fix ./config.yaml\n.venv/bin/aesculap disable ./config.yaml\n.venv/bin/aesculap enable ./config.yaml\n.venv/bin/aesculap stop\n```\n\nUse `observe` immediately when a diagnosis or repair route appears suspicious. `disable` is the master stop for Aesculap behavior; stopping the systemd service additionally stops the daemon process.\n\nWhen a notification requests a credential, tell the user which environment variable and file need attention. Never request, echo, transmit, or log the credential itself.\n\n## Common Pitfalls\n\n1. **Accepting an obsolete notification command.** Current Hermes uses `hermes send`; verify with live `--help` and `--list`. An untested template means notification delivery is not configured.\n2. **Guessing the user’s language.** Always ask during installation. Logs and locale are evidence about software, not the person receiving alerts.\n3. **Localizing machine actions.** `actions` are parsed downstream. Keep strings in English or use structured action objects; localize only human-facing diagnosis and notification copy.\n4. **Leaving a new install in observation-only mode by accident.** New installs default to `fix` so protection is active. Use `observe` deliberately for a dry run or incident downgrade, and record whether/when it should return to `fix`.\n5. **Treating tier C as unrestricted root.** Hard tripwires and protected paths still apply. C is not permission to edit identity, credentials, billing, or Aesculap itself.\n6. **Running without git rollback.** Resolve the intended rollback repository before enabling repairs.\n7. **Claiming success from config validation alone.** A complete install requires service health, probe results, a real notification test, and language verification.\n8. **Mixing project source with production dirty changes.** Use an isolated worktree for development and preserve the deployed checkout until changes are reviewed and deliberately rolled out.\n\n## Verification Checklist\n\n- [ ] Python ≥ 3.11 and isolated `.venv` are in use\n- [ ] Hermes file logging and project git rollback are available\n- [ ] Permission tier and identity-file protections were explicitly confirmed\n- [ ] Provider choice was detected without reading or printing secrets\n- [ ] `hermes send --list` was checked on the live installation\n- [ ] Notification target was tested or explicitly disabled\n- [ ] Notification language was explicitly selected and persisted\n- [ ] `config`, `probe`, and `status` commands were exercised\n- [ ] Initial mode is `fix`, unless the user deliberately selected `observe`\n- [ ] User was told that starting the service in `fix` permits bounded repairs within the selected tier\n- [ ] systemd unit was reviewed before `--write`\n- [ ] Audit, notification delivery, localization, and redaction were verified end to end\n- [ ] Any deliberate use of `observe` includes a recorded decision about whether/when to restore `fix`\n- [ ] Final report states scope tier, mode, service status, notification target/language, and unresolved probe failures\n"}, "d4d49c3cb03db6a00ca7dfbcb9f1ac922dad4ca5": {"t": 1785771415.8759592, "n": 14573, "h": "fd9428c05a7335b8", "c": "---\nname: aesculap-hermes\ndescription: Use when a user asks an agent to install, configure, validate, operate, or troubleshoot Aesculap, the safety-gated self-healing daemon for Hermes Agent. Guides environment discovery, explicit permission-tier selection, provider setup without exposing keys, notification target and language confirmation, explicit fix-mode disclosure, systemd installation, and end-to-end verification.\nversion: 0.1.0\nauthor: banxia-O\nlicense: MIT\nmetadata:\n hermes:\n tags: [hermes, self-healing, reliability, systemd, monitoring, incident-response]\n related_skills: [hermes-agent]\n---\n\n# Aesculap for Hermes Agent\n\n## Overview\n\nAesculap is a resident health-monitoring and recovery daemon for Hermes Agent. It detects persistent failures, asks an LLM to diagnose and propose a route, then lets deterministic code decide whether any action is allowed. Safe, bounded repairs may run automatically; risky, ambiguous, repeated, or unsupported cases escalate to a coding agent or a human.\n\nThis skill is the installation and operations entrypoint. Read [`AGENT.md`](./AGENT.md) for the complete agent-facing manual, [`README.md`](./README.md) for the product overview, and [`Aesculap_PRD.md`](./Aesculap_PRD.md) when auditing design decisions.\n\n**Core invariant:** the LLM proposes; code gates decide. Never describe Aesculap as unrestricted autonomous repair.\n\n## When to Use\n\nUse this skill when the user asks to:\n\n- install Aesculap beside a Hermes deployment;\n- configure probes, providers, permission boundaries, or notifications;\n- choose between permission tiers A/B/C;\n- run Aesculap in observe or fix mode;\n- install or troubleshoot the systemd service;\n- inspect status, audit records, or pending escalations;\n- verify whether human-intervention notifications actually arrive.\n\nDo not use it as a generic server-monitoring guide, a replacement for backups, or authorization to edit identity files, credentials, billing settings, or unrelated applications.\n\n## Operating Contract\n\nBefore writing files or starting a service, explain and obtain explicit answers for every consequential decision below.\n\n| Decision | Required behavior |\n|---|---|\n| Writable scope | Present A/B/C with risks. Recommend A. Never silently choose C. |\n| Identity files | Show detected candidates and let the user confirm the immutable list. |\n| Triage provider/model | Detect configured providers by key presence only; never read or print key values. |\n| Coding-agent escalation | Report whether Claude Code, Codex, or another supported tool is actually available. |\n| Notification target | Run `hermes send --list`; let the user choose a real destination; send a test message. |\n| Notification language | Ask: **“Aesculap needs human intervention. Which language should it use to notify you: English or Simplified Chinese?”** Persist the answer as `notify.language`. |\n| Service scope | Ask whether systemd should use user or system scope. Prefer user scope unless system scope is necessary. |\n| Activation mode | New installs default to `fix` so protection is active immediately. State this before service start. Switch to `observe` only when the user explicitly wants a dry run or temporary safety downgrade. |\n\nNever infer notification language from logs, stack traces, server locale, model output, or an occasional message. Supported values are `en` and `zh-CN`; legacy configurations without the field default to `en`.\n\n## Installation Workflow\n\n### 1. Read-only preflight\n\nRun these checks without changing the system:\n\n```bash\npython3 --version\ngit -C <project-root> rev-parse --is-inside-work-tree\nhermes --version\nhermes gateway status\nhermes send --list\ncommand -v systemctl || true\ncommand -v claude || true\ncommand -v codex || true\n```\n\nAlso inspect:\n\n- whether Hermes writes logs to a file that Aesculap can watch;\n- whether the protected project is a git repository;\n- whether `~/.hermes` or the active profile contains identity files such as `SOUL.md`, `MEMORY.md`, `USER.md`, persona, or identity documents;\n- which provider environment variables exist, checking only presence;\n- available disk space and Python ≥ 3.11.\n\n**Completion criterion:** report every prerequisite as pass, missing, or intentionally disabled. Do not begin installation while file logging or the intended rollback repository is unresolved.\n\n### 2. Ask for the safety boundary\n\nPresent the tiers in plain language:\n\n- **A — project tree only:** safest and recommended for most users.\n- **B — Hermes configuration plus project tree:** only for a dedicated Hermes host and only after identity/credential exclusions are confirmed.\n- **C — whole host:** highest risk. Use only after explicit user selection and confirmation that the machine is dedicated and contains no unrelated important data.\n\nAesculap still hard-blocks identity files, credentials, its own directory, read-only files, sensitive system paths, destructive commands, force pushes, deletion, and billing/payment operations. A larger tier never removes those hard tripwires.\n\n**Completion criterion:** record the user’s explicit tier and immutable identity-file choices. If the user is uncertain, stop at A.\n\n### 3. Prepare an isolated Python environment\n\nFrom the repository or SkillHub-installed directory:\n\n```bash\npython3 -m venv .venv\n.venv/bin/python -m pip install --upgrade pip\n.venv/bin/pip install -e .\n```\n\nInstall only the provider extras actually selected:\n\n```bash\n.venv/bin/pip install -e '.[openai]'\n# or\n.venv/bin/pip install -e '.[anthropic]'\n# or both only when both are genuinely needed\n```\n\nNever paste API keys into chat or `config.yaml`. The configuration stores environment-variable names such as `OPENAI_API_KEY`, not secret values. Tell the user which approved environment file or service environment to edit, then verify only that the variable exists.\n\n**Completion criterion:** `.venv/bin/aesculap --version` exits successfully and no credential value appears in shell history, logs, config, or chat.\n\n### 4. Resolve notification delivery before running the wizard\n\nList actual Hermes destinations:\n\n```bash\nhermes send --list\n```\n\nAsk the user which destination should receive human-intervention alerts. Build a command template from a real target, for example:\n\n```yaml\nnotify:\n command_template: \"hermes send --to telegram {message}\"\n```\n\nTargets may be a platform home channel or an explicit platform/chat/thread destination. Use the exact syntax shown by `hermes send --help` on the installed Hermes version. Test the target before relying on it:\n\n```bash\nhermes send --to <target> \"Aesculap notification test\"\n```\n\nIf no destination is available, leave `notify.command_template` empty and state clearly that escalations will be audited but not delivered. Never retain an obsolete notification subcommand copied from an older Hermes release.\n\nThen ask the language question and retain the explicit answer:\n\n- English → `notify.language: en`\n- 简体中文 → `notify.language: zh-CN`\n\nThe selected language controls the human-readable triage diagnosis and final notification shell. Machine-consumed action strings, JSON keys, enum values, and audit fields remain stable English or structured objects.\n\n**Completion criterion:** either a real test message arrived at the user-selected destination, or delivery is explicitly marked disabled; the chosen language is documented.\n\n### 5. Run the interactive installer\n\n```bash\n.venv/bin/aesculap install ./config.yaml\n```\n\nUse the answers already confirmed with the user. Do not reinterpret them during the CLI wizard. When asked for the notification template, paste the verified template or leave it blank. When asked for notification language, enter `en` or `zh-CN` exactly.\n\nAfter generation, inspect the configuration without printing secret values:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n```\n\nConfirm at minimum:\n\n- `scope.tier` matches the user’s choice;\n- project and Hermes paths are correct;\n- identity files are protected;\n- provider and model names are intended;\n- `notify.command_template` is either tested or empty;\n- `notify.language` matches the explicit answer;\n- `mode` is `fix` unless the user deliberately requested `observe`;\n- no API key value is stored in YAML.\n\n**Completion criterion:** config validation exits 0 and every consequential field matches a user-confirmed decision.\n\n### 6. Establish a health baseline before service start\n\nNew configurations default to `fix`; this avoids a monitoring-only install being forgotten. Before starting the resident service, state plainly that bounded repairs may run within the selected tier, then inspect the baseline:\n\n```bash\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\n```\n\nA failing probe is not automatically an installer failure. Determine whether it reflects a real Hermes issue, an incorrect path, or a probe that should be disabled. Do not start the service merely to make the output green.\n\nIf the user explicitly wants a dry run or a temporary safety downgrade, switch modes before service start:\n\n```bash\n.venv/bin/aesculap mode observe ./config.yaml\n```\n\n**Completion criterion:** every enabled probe has an explained result, the active mode is stated to the user, and `fix` remains enabled unless the user deliberately selected `observe`.\n\n### 7. Install systemd with a dry run first\n\nRender the unit before writing it:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user\n# or, only if explicitly selected:\n.venv/bin/aesculap install-systemd ./config.yaml --scope system\n```\n\nReview the executable path, working directory, config path, service user, and hardening directives. Then install only after approval:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user --write\n```\n\nUse the enable/start command printed by the installer. For user services that must survive logout, check whether linger is required before enabling it.\n\n**Completion criterion:** systemd reports the unit active, the process uses the intended `.venv`, and logs show one clean startup rather than a restart loop.\n\n### 8. Verify end to end\n\nRun:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\nsystemctl --user status aesculap.service --no-pager\n```\n\nAdapt the final command for system scope. Inspect recent audit entries and service logs. Trigger only a harmless, reversible test condition or use a test fixture; do not break a production agent merely to prove recovery.\n\nVerify separately:\n\n1. Aesculap detects and audits the test event.\n2. In default `fix` mode, every attempted repair remains inside the selected tier and deterministic gate; if the user selected `observe`, no repair runs.\n3. A human escalation reaches the configured target.\n4. The title, diagnosis, headings, and guidance use the chosen language.\n5. Technical evidence may remain in its original language but credentials are redacted.\n6. Repeated equivalent events respect deduplication/cooldown.\n\nIf the user temporarily selected `observe`, restore the normal active mode once the dry run is complete unless they explicitly choose to remain observation-only:\n\n```bash\n.venv/bin/aesculap mode fix ./config.yaml\n```\n\n**Completion criterion:** detection, audit, delivery, language, redaction, safety-gate behavior, and service health are all verified with real output; the final mode is stated explicitly.\n\n## Routine Operations\n\n```bash\n.venv/bin/aesculap status ./config.yaml\n.venv/bin/aesculap mode observe ./config.yaml\n.venv/bin/aesculap mode fix ./config.yaml\n.venv/bin/aesculap disable ./config.yaml\n.venv/bin/aesculap enable ./config.yaml\n.venv/bin/aesculap stop\n```\n\nUse `observe` immediately when a diagnosis or repair route appears suspicious. `disable` is the master stop for Aesculap behavior; stopping the systemd service additionally stops the daemon process.\n\nWhen a notification requests a credential, tell the user which environment variable and file need attention. Never request, echo, transmit, or log the credential itself.\n\n## Common Pitfalls\n\n1. **Accepting an obsolete notification command.** Current Hermes uses `hermes send`; verify with live `--help` and `--list`. An untested template means notification delivery is not configured.\n2. **Guessing the user’s language.** Always ask during installation. Logs and locale are evidence about software, not the person receiving alerts.\n3. **Localizing machine actions.** `actions` are parsed downstream. Keep strings in English or use structured action objects; localize only human-facing diagnosis and notification copy.\n4. **Leaving a new install in observation-only mode by accident.** New installs default to `fix` so protection is active. Use `observe` deliberately for a dry run or incident downgrade, and record whether/when it should return to `fix`.\n5. **Treating tier C as unrestricted root.** Hard tripwires and protected paths still apply. C is not permission to edit identity, credentials, billing, or Aesculap itself.\n6. **Running without git rollback.** Resolve the intended rollback repository before enabling repairs.\n7. **Claiming success from config validation alone.** A complete install requires service health, probe results, a real notification test, and language verification.\n8. **Mixing project source with production dirty changes.** Use an isolated worktree for development and preserve the deployed checkout until changes are reviewed and deliberately rolled out.\n\n## Verification Checklist\n\n- [ ] Python ≥ 3.11 and isolated `.venv` are in use\n- [ ] Hermes file logging and project git rollback are available\n- [ ] Permission tier and identity-file protections were explicitly confirmed\n- [ ] Provider choice was detected without reading or printing secrets\n- [ ] `hermes send --list` was checked on the live installation\n- [ ] Notification target was tested or explicitly disabled\n- [ ] Notification language was explicitly selected and persisted\n- [ ] `config`, `probe`, and `status` commands were exercised\n- [ ] Initial mode is `fix`, unless the user deliberately selected `observe`\n- [ ] User was told that starting the service in `fix` permits bounded repairs within the selected tier\n- [ ] systemd unit was reviewed before `--write`\n- [ ] Audit, notification delivery, localization, and redaction were verified end to end\n- [ ] Any deliberate use of `observe` includes a recorded decision about whether/when to restore `fix`\n- [ ] Final report states scope tier, mode, service status, notification target/language, and unresolved probe failures\n"}, "270840d2f6d23b20f32966ef71887879369989e0": {"t": 1785771417.3090918, "n": 13612, "h": "430f0f9e9e2454d9", "c": "---\nname: aesculap-hermes\ndescription: Use when a user asks an agent to install, configure, validate, operate, or troubleshoot Aesculap, the safety-gated self-healing daemon for Hermes Agent. Guides environment discovery, explicit permission-tier selection, provider setup without exposing keys, notification target and language confirmation, observe-first rollout, systemd installation, and end-to-end verification.\nversion: 0.1.0\nauthor: banxia-O\nlicense: MIT\nmetadata:\n hermes:\n tags: [hermes, self-healing, reliability, systemd, monitoring, incident-response]\n related_skills: [hermes-agent]\n---\n\n# Aesculap for Hermes Agent\n\n## Overview\n\nAesculap is a resident health-monitoring and recovery daemon for Hermes Agent. It detects persistent failures, asks an LLM to diagnose and propose a route, then lets deterministic code decide whether any action is allowed. Safe, bounded repairs may run automatically; risky, ambiguous, repeated, or unsupported cases escalate to a coding agent or a human.\n\nThis skill is the installation and operations entrypoint. Read [`AGENT.md`](./AGENT.md) for the complete agent-facing manual, [`README.md`](./README.md) for the product overview, and [`Aesculap_PRD.md`](./Aesculap_PRD.md) when auditing design decisions.\n\n**Core invariant:** the LLM proposes; code gates decide. Never describe Aesculap as unrestricted autonomous repair.\n\n## When to Use\n\nUse this skill when the user asks to:\n\n- install Aesculap beside a Hermes deployment;\n- configure probes, providers, permission boundaries, or notifications;\n- choose between permission tiers A/B/C;\n- run Aesculap in observe or fix mode;\n- install or troubleshoot the systemd service;\n- inspect status, audit records, or pending escalations;\n- verify whether human-intervention notifications actually arrive.\n\nDo not use it as a generic server-monitoring guide, a replacement for backups, or authorization to edit identity files, credentials, billing settings, or unrelated applications.\n\n## Operating Contract\n\nBefore writing files or starting a service, explain and obtain explicit answers for every consequential decision below.\n\n| Decision | Required behavior |\n|---|---|\n| Writable scope | Present A/B/C with risks. Recommend A. Never silently choose C. |\n| Identity files | Show detected candidates and let the user confirm the immutable list. |\n| Triage provider/model | Detect configured providers by key presence only; never read or print key values. |\n| Coding-agent escalation | Report whether Claude Code, Codex, or another supported tool is actually available. |\n| Notification target | Run `hermes send --list`; let the user choose a real destination; send a test message. |\n| Notification language | Ask: **“Aesculap needs human intervention. Which language should it use to notify you: English or Simplified Chinese?”** Persist the answer as `notify.language`. |\n| Service scope | Ask whether systemd should use user or system scope. Prefer user scope unless system scope is necessary. |\n| Activation mode | Start with `observe`; move to `fix` only after probes and notifications are verified and the user approves. |\n\nNever infer notification language from logs, stack traces, server locale, model output, or an occasional message. Supported values are `en` and `zh-CN`; legacy configurations without the field default to `en`.\n\n## Installation Workflow\n\n### 1. Read-only preflight\n\nRun these checks without changing the system:\n\n```bash\npython3 --version\ngit -C <project-root> rev-parse --is-inside-work-tree\nhermes --version\nhermes gateway status\nhermes send --list\ncommand -v systemctl || true\ncommand -v claude || true\ncommand -v codex || true\n```\n\nAlso inspect:\n\n- whether Hermes writes logs to a file that Aesculap can watch;\n- whether the protected project is a git repository;\n- whether `~/.hermes` or the active profile contains identity files such as `SOUL.md`, `MEMORY.md`, `USER.md`, persona, or identity documents;\n- which provider environment variables exist, checking only presence;\n- available disk space and Python ≥ 3.11.\n\n**Completion criterion:** report every prerequisite as pass, missing, or intentionally disabled. Do not begin installation while file logging or the intended rollback repository is unresolved.\n\n### 2. Ask for the safety boundary\n\nPresent the tiers in plain language:\n\n- **A — project tree only:** safest and recommended for most users.\n- **B — Hermes configuration plus project tree:** only for a dedicated Hermes host and only after identity/credential exclusions are confirmed.\n- **C — whole host:** highest risk. Use only after explicit user selection and confirmation that the machine is dedicated and contains no unrelated important data.\n\nAesculap still hard-blocks identity files, credentials, its own directory, read-only files, sensitive system paths, destructive commands, force pushes, deletion, and billing/payment operations. A larger tier never removes those hard tripwires.\n\n**Completion criterion:** record the user’s explicit tier and immutable identity-file choices. If the user is uncertain, stop at A.\n\n### 3. Prepare an isolated Python environment\n\nFrom the repository or SkillHub-installed directory:\n\n```bash\npython3 -m venv .venv\n.venv/bin/python -m pip install --upgrade pip\n.venv/bin/pip install -e .\n```\n\nInstall only the provider extras actually selected:\n\n```bash\n.venv/bin/pip install -e '.[openai]'\n# or\n.venv/bin/pip install -e '.[anthropic]'\n# or both only when both are genuinely needed\n```\n\nNever paste API keys into chat or `config.yaml`. The configuration stores environment-variable names such as `OPENAI_API_KEY`, not secret values. Tell the user which approved environment file or service environment to edit, then verify only that the variable exists.\n\n**Completion criterion:** `.venv/bin/aesculap --version` exits successfully and no credential value appears in shell history, logs, config, or chat.\n\n### 4. Resolve notification delivery before running the wizard\n\nList actual Hermes destinations:\n\n```bash\nhermes send --list\n```\n\nAsk the user which destination should receive human-intervention alerts. Build a command template from a real target, for example:\n\n```yaml\nnotify:\n command_template: \"hermes send --to telegram {message}\"\n```\n\nTargets may be a platform home channel or an explicit platform/chat/thread destination. Use the exact syntax shown by `hermes send --help` on the installed Hermes version. Test the target before relying on it:\n\n```bash\nhermes send --to <target> \"Aesculap notification test\"\n```\n\nIf no destination is available, leave `notify.command_template` empty and state clearly that escalations will be audited but not delivered. Never retain an obsolete notification subcommand copied from an older Hermes release.\n\nThen ask the language question and retain the explicit answer:\n\n- English → `notify.language: en`\n- 简体中文 → `notify.language: zh-CN`\n\nThe selected language controls the human-readable triage diagnosis and final notification shell. Machine-consumed action strings, JSON keys, enum values, and audit fields remain stable English or structured objects.\n\n**Completion criterion:** either a real test message arrived at the user-selected destination, or delivery is explicitly marked disabled; the chosen language is documented.\n\n### 5. Run the interactive installer\n\n```bash\n.venv/bin/aesculap install ./config.yaml\n```\n\nUse the answers already confirmed with the user. Do not reinterpret them during the CLI wizard. When asked for the notification template, paste the verified template or leave it blank. When asked for notification language, enter `en` or `zh-CN` exactly.\n\nAfter generation, inspect the configuration without printing secret values:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n```\n\nConfirm at minimum:\n\n- `scope.tier` matches the user’s choice;\n- project and Hermes paths are correct;\n- identity files are protected;\n- provider and model names are intended;\n- `notify.command_template` is either tested or empty;\n- `notify.language` matches the explicit answer;\n- no API key value is stored in YAML.\n\n**Completion criterion:** config validation exits 0 and every consequential field matches a user-confirmed decision.\n\n### 6. Establish a health baseline in observe mode\n\nBefore starting a resident service:\n\n```bash\n.venv/bin/aesculap mode observe ./config.yaml\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\n```\n\nA failing probe is not automatically an installer failure. Determine whether it reflects a real Hermes issue, an incorrect path, or a probe that should be disabled. Do not switch to `fix` merely to make the output green.\n\n**Completion criterion:** every enabled probe has an explained result, and the user understands that observe mode detects and reports without modifying the protected system.\n\n### 7. Install systemd with a dry run first\n\nRender the unit before writing it:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user\n# or, only if explicitly selected:\n.venv/bin/aesculap install-systemd ./config.yaml --scope system\n```\n\nReview the executable path, working directory, config path, service user, and hardening directives. Then install only after approval:\n\n```bash\n.venv/bin/aesculap install-systemd ./config.yaml --scope user --write\n```\n\nUse the enable/start command printed by the installer. For user services that must survive logout, check whether linger is required before enabling it.\n\n**Completion criterion:** systemd reports the unit active, the process uses the intended `.venv`, and logs show one clean startup rather than a restart loop.\n\n### 8. Verify end to end\n\nRun:\n\n```bash\n.venv/bin/aesculap config ./config.yaml\n.venv/bin/aesculap probe ./config.yaml\n.venv/bin/aesculap status ./config.yaml\nsystemctl --user status aesculap.service --no-pager\n```\n\nAdapt the final command for system scope. Inspect recent audit entries and service logs. Trigger only a harmless, reversible test condition or use a test fixture; do not break a production agent merely to prove recovery.\n\nVerify separately:\n\n1. Aesculap detects and audits the test event.\n2. Observe mode performs no repair.\n3. A human escalation reaches the configured target.\n4. The title, diagnosis, headings, and guidance use the chosen language.\n5. Technical evidence may remain in its original language but credentials are redacted.\n6. Repeated equivalent events respect deduplication/cooldown.\n\nAfter this passes, explain what `fix` mode can change under the selected tier and ask for approval before switching:\n\n```bash\n.venv/bin/aesculap mode fix ./config.yaml\n```\n\n**Completion criterion:** detection, audit, delivery, language, redaction, and service health are all verified with real output; activation mode matches the user’s final decision.\n\n## Routine Operations\n\n```bash\n.venv/bin/aesculap status ./config.yaml\n.venv/bin/aesculap mode observe ./config.yaml\n.venv/bin/aesculap mode fix ./config.yaml\n.venv/bin/aesculap disable ./config.yaml\n.venv/bin/aesculap enable ./config.yaml\n.venv/bin/aesculap stop\n```\n\nUse `observe` immediately when a diagnosis or repair route appears suspicious. `disable` is the master stop for Aesculap behavior; stopping the systemd service additionally stops the daemon process.\n\nWhen a notification requests a credential, tell the user which environment variable and file need attention. Never request, echo, transmit, or log the credential itself.\n\n## Common Pitfalls\n\n1. **Accepting an obsolete notification command.** Current Hermes uses `hermes send`; verify with live `--help` and `--list`. An untested template means notification delivery is not configured.\n2. **Guessing the user’s language.** Always ask during installation. Logs and locale are evidence about software, not the person receiving alerts.\n3. **Localizing machine actions.** `actions` are parsed downstream. Keep strings in English or use structured action objects; localize only human-facing diagnosis and notification copy.\n4. **Starting directly in fix mode.** Establish an observe-mode baseline first, then request approval to enable repairs.\n5. **Treating tier C as unrestricted root.** Hard tripwires and protected paths still apply. C is not permission to edit identity, credentials, billing, or Aesculap itself.\n6. **Running without git rollback.** Resolve the intended rollback repository before enabling repairs.\n7. **Claiming success from config validation alone.** A complete install requires service health, probe results, a real notification test, and language verification.\n8. **Mixing project source with production dirty changes.** Use an isolated worktree for development and preserve the deployed checkout until changes are reviewed and deliberately rolled out.\n\n## Verification Checklist\n\n- [ ] Python ≥ 3.11 and isolated `.venv` are in use\n- [ ] Hermes file logging and project git rollback are available\n- [ ] Permission tier and identity-file protections were explicitly confirmed\n- [ ] Provider choice was detected without reading or printing secrets\n- [ ] `hermes send --list` was checked on the live installation\n- [ ] Notification target was tested or explicitly disabled\n- [ ] Notification language was explicitly selected and persisted\n- [ ] `config`, `probe`, and `status` commands were exercised\n- [ ] Initial service ran in `observe` mode\n- [ ] systemd unit was reviewed before `--write`\n- [ ] Audit, notification delivery, localization, and redaction were verified end to end\n- [ ] User approved any transition from `observe` to `fix`\n- [ ] Final report states scope tier, mode, service status, notification target/language, and unresolved probe failures\n"}}}}