From 4d1d2e290fbbaa11bd5f4606c83f8dddd3bd9aa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=8F=E5=94=AF=20A06?= Date: Sat, 1 Aug 2026 02:47:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(watchdog):=20=E6=96=B0=E5=A2=9E=E4=BF=9D?= =?UTF-8?q?=E6=8A=A4=E8=A7=84=E5=88=99=E8=87=AA=E6=A3=80=E8=84=9A=E6=9C=AC?= =?UTF-8?q?=E5=B9=B6=E8=81=94=E5=8A=A8=E6=AF=8F30min=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/anti-suicide-check.sh | 88 +++++++++++++++++++++++++++++++++++ scripts/health-watchdog.sh | 10 ++++ 2 files changed, 98 insertions(+) create mode 100755 scripts/anti-suicide-check.sh diff --git a/scripts/anti-suicide-check.sh b/scripts/anti-suicide-check.sh new file mode 100755 index 00000000..331717fb --- /dev/null +++ b/scripts/anti-suicide-check.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# ============================================================ +# anti-suicide-check.sh — 防自杀自检(2026-08-01 建立) +# 验证所有"防止 gateway 自毁"的保护规则是否生效。 +# 由 health-watchdog.sh 联动(每 30min),异常时飞书报警。 +# 用法: bash anti-suicide-check.sh +# 返回 0 = 全部保护生效;非 0 = 有保护失效 +# ============================================================ + +FAIL=0 +log() { echo "[$(date '+%H:%M:%S')] $*"; } + +# === 1. unit 文件必须存在 === +UNIT=~/.config/systemd/user/hermes-gateway.service +if [ -f "$UNIT" ]; then + log "✅ unit 文件存在" +else + log "🚨 unit 文件丢失!从备份恢复..." + cp ~/.hermes/systemd-units/hermes-gateway.service "$UNIT" 2>/dev/null && { + systemctl --user daemon-reload 2>/dev/null + log "✅ 已从备份恢复 unit 文件" + } || { log "❌ 备份也缺失!"; FAIL=1; } +fi + +# === 2. stable tag 不得过旧(超过7天=危险)=== +cd ~/.hermes 2>/dev/null +if git rev-parse --verify stable >/dev/null 2>&1; then + TS=$(git log -1 --format="%ct" stable) + NOW=$(date +%s) + AGE_DAYS=$(( (NOW - TS) / 86400 )) + if [ "$AGE_DAYS" -gt 7 ]; then + log "🚨 stable tag 已 $AGE_DAYS 天前(>7),auto-heal 会拒绝回滚——建议手动更新 stable" + # 不置 FAIL(config-protector 已有拒绝保护),但提示 + else + log "✅ stable tag 新鲜(${AGE_DAYS}天前)" + fi +else + log "🚨 stable tag 不存在" + FAIL=1 +fi + +# === 3. config-protector 的 auto-heal 不得包含 hermes === +if grep -q "hermes" ~/.hermes/scripts/config-protector.sh 2>/dev/null; then + # 检查是否在 auto-heal 的进程检测列表里(有 hermes 即危险) + if grep -A 8 "检查关键进程" ~/.hermes/scripts/config-protector.sh 2>/dev/null | grep -q "for p in.*hermes"; then + log "🚨 config-protector auto-heal 仍包含 hermes(会误触发回滚)" + FAIL=1 + else + log "✅ auto-heal 不包含 hermes(注释引用除外)" + fi +else + log "✅ auto-heal 无 hermes 引用" +fi + +# === 4. config.yaml 主模型必须仍是 deepseek-v4-flash === +if grep -q "default: deepseek-v4-flash" ~/.hermes/config.yaml 2>/dev/null; then + log "✅ 主模型 = deepseek-v4-flash(铁律未破)" +else + log "🚨 主模型被改!当前: $(grep 'default:' ~/.hermes/config.yaml | head -1)" + FAIL=1 +fi + +# === 5. 运行时噪音不得被 git 跟踪 === +NOISE_TRACKED=$(cd ~/.hermes && git ls-files 2>/dev/null | grep -cE "^(daemon/(pid|context|journal)|cron/(jobs|ticker)|gateway\.|llm_context|feishu_seen)" || true) +if [ "$NOISE_TRACKED" -eq 0 ] 2>/dev/null; then + log "✅ 运行时噪音未被 git 跟踪" +else + log "🚨 $NOISE_TRACKED 个运行时噪音被 git 跟踪(仓库会永远 dirty)" + FAIL=1 +fi + +# === 6. gateway 服务状态 === +SVC_STATE=$(systemctl --user is-active hermes-gateway.service 2>/dev/null || echo "unknown") +if [ "$SVC_STATE" = "active" ]; then + log "✅ hermes-gateway active" +else + log "🚨 hermes-gateway 状态: $SVC_STATE" + FAIL=1 +fi + +# === 汇总 === +if [ "$FAIL" -eq 0 ]; then + log "🟢 全部防自杀保护生效" + exit 0 +else + log "🔴 $FAIL 项保护失效,请人工介入" + exit 1 +fi diff --git a/scripts/health-watchdog.sh b/scripts/health-watchdog.sh index e7a8d759..1f97bf23 100755 --- a/scripts/health-watchdog.sh +++ b/scripts/health-watchdog.sh @@ -191,6 +191,16 @@ if [ -f "$CONFIG_PROTECTOR" ]; then fi fi +# === 防自杀自检(2026-08-01 新增:每 30min 验证保护规则)=== +ANTI_SUICIDE="$HOME/.hermes/scripts/anti-suicide-check.sh" +if [ -f "$ANTI_SUICIDE" ]; then + ANTI_RESULT=$(bash "$ANTI_SUICIDE" 2>&1) + if [ $? -ne 0 ]; then + ALERTS+="🚨 防自杀保护失效: $(echo "$ANTI_RESULT" | grep '🚨' | head -3)\\n" + CRITICAL=true + fi +fi + # === 状态判断与飞书通知 === # 读取上次状态