Autonomie 0d+0g: Lucy-Alarm-Weg, taegliche Selbst-Smokes, Selbstreparatur nach rotem Update
- /api/alarm: Lucy-unabhaengiger Telegram-Weg (fuer den PC-Lucy-Watchdog, wenn die App haengt). - self-smoke.sh + mc2-selfsmoke.timer (taeglich 07:15): Gateway/Tools/Voice aktiv durchspielen, Meldung nur bei Rot. Ergaenzt den passiven Health-Waechter um echte Funktion. - self-repair.sh + autoupdate.sh: bei rotem Hermes-Update zieht die Box Config-Brueche selbst (nur eindeutige, nicht-sicherheitsrelevante Keys; Backup -> YAML-Check -> Gehirn-Check, sonst zurueck). Greift es nicht, haengt eine LLM-Diagnose an die Rollback-Meldung. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env bash
|
||||
# Selbstreparatur-Modus (Autonomie 0g, Kür): Macht ein Hermes-Update den Gehirn-Check rot,
|
||||
# WEIL sich Config-Schlüssel geändert haben (v0.18-Klasse: „Unknown key … → stiller Default →
|
||||
# alle Tools hingen"), versucht die Box den Config-Bruch SELBST zu ziehen — bevor zurückgerollt
|
||||
# wird, um die neue Version zu behalten. NUR Config, NIE Code, NIE Security-Schlüssel.
|
||||
#
|
||||
# Sicher durch Kapselung — jeder Schritt ist reversibel und hart gegatet:
|
||||
# Backup → nur EINDEUTIGE (genau 1× vorkommende), nicht-sicherheitsrelevante Keys auskommentieren
|
||||
# → YAML muss gültig bleiben → Gehirn-Check (hermes-postcheck.sh) muss GRÜN werden → sonst zurück.
|
||||
# Schlimmster Fall bei Fehlgriff = exakt der heutige: Rollback. Der Aufrufer (autoupdate.sh) ruft
|
||||
# dies VOR seinem Rollback; bei Rückgabe 2 rollt er wie gehabt zurück + pinnt.
|
||||
#
|
||||
# Rückgabe: 0 = repariert (Gehirn-Check danach grün) · 2 = nichts sicher reparierbar.
|
||||
# Gibt bei Misserfolg eine Zeile „SELFREPAIR_SUGGESTION=<LLM-Diagnose>" auf stdout aus.
|
||||
set -uo pipefail
|
||||
|
||||
SRC_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
HERMES="${HERMES_HOME:-$HOME/.hermes}"
|
||||
CFG="$HERMES/config.yaml"
|
||||
WARN_FILE="${HERMES_CONFIG_WARNINGS:-/tmp/hermes-config-warnings.txt}"
|
||||
LLAMA="${LLAMA_SWAP_URL:-http://127.0.0.1:8080}"
|
||||
VENV_PY="$HERMES/hermes-agent/venv/bin/python"
|
||||
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}"
|
||||
|
||||
say(){ echo "[self-repair] $*"; }
|
||||
|
||||
# ── 1) Evidenz: Postcheck-Warnungen + frisches Gateway-Journal ────────────────
|
||||
EVID="$(cat "$WARN_FILE" 2>/dev/null)"
|
||||
JOURN="$(journalctl --user -u hermes-gateway --since '-6 minutes' --no-pager -o cat 2>/dev/null \
|
||||
| grep -iE "Unknown [a-z._]+ '|deprecated .*(setting|option|config)|defaulting to|invalid config" \
|
||||
| grep -v check_fn | head -10)"
|
||||
[ -z "$EVID" ] && EVID="$JOURN"
|
||||
if [ -z "$EVID" ]; then
|
||||
say "Keine Config-Bruch-Hinweise gefunden — hier ist (sicher) nichts zu reparieren."
|
||||
exit 2
|
||||
fi
|
||||
say "Config-Hinweise:"; echo "$EVID"
|
||||
|
||||
# LLM-Diagnose/Empfehlung (best-effort) — für die Meldung, egal ob wir reparieren.
|
||||
SUGG="$(curl -sf -m 60 "$LLAMA/v1/chat/completions" -H 'Content-Type: application/json' \
|
||||
-d "$(python3 - "$EVID" <<'PY'
|
||||
import json, sys
|
||||
p = ("Ein Hermes-Agent-Update hat den Selbsttest rot gemacht. Log-Hinweise:\n" + sys.argv[1] +
|
||||
"\n\nNenne auf Deutsch in 1-2 kurzen Sätzen die wahrscheinliche Ursache und die konkrete "
|
||||
"Config-Korrektur in ~/.hermes/config.yaml (Schlüssel → neuer Wert). Keine Einleitung.")
|
||||
print(json.dumps({"model": "coder-lite", "max_tokens": 200, "temperature": 0.1,
|
||||
"messages": [{"role": "user", "content": p}]}))
|
||||
PY
|
||||
)" 2>/dev/null | python3 -c 'import sys,json; print((json.load(sys.stdin).get("choices") or [{}])[0].get("message",{}).get("content","").strip())' 2>/dev/null)"
|
||||
|
||||
# ── 2) Offending Leaf-Keys ziehen ────────────────────────────────────────────
|
||||
KEYS="$(echo "$EVID" | grep -oE "Unknown [a-zA-Z0-9_.]+|'[a-zA-Z0-9_.]+'" | sed -E "s/^Unknown //; s/'//g" | sort -u)"
|
||||
LEAVES="$(for k in $KEYS; do echo "${k##*.}"; done | sort -u | grep -vE '^(true|false|null|)$')"
|
||||
|
||||
SEC_RX='token|secret|password|approval|api_server_key|ufw|sudo|allowlist|credential'
|
||||
BAK="$CFG.selfrepair-bak-$(date +%Y%m%d-%H%M%S)"
|
||||
cp -a "$CFG" "$BAK"
|
||||
|
||||
CHANGED=""; SKIPPED=""
|
||||
for leaf in $LEAVES; do
|
||||
if echo "$leaf" | grep -qiE "$SEC_RX"; then SKIPPED="$SKIPPED $leaf(security-tabu)"; continue; fi
|
||||
# Nur EINDEUTIGE Schlüssel-Zeilen (genau 1×) anfassen — Mehrdeutige sind zu riskant.
|
||||
n="$(grep -cE "^[[:space:]]*${leaf}:" "$CFG" 2>/dev/null || echo 0)"
|
||||
if [ "$n" = "1" ]; then
|
||||
sed -i -E "s|^([[:space:]]*)(${leaf}:.*)$|\1# [selbstrepariert $(date +%F)] \2|" "$CFG"
|
||||
CHANGED="$CHANGED $leaf"; say "auskommentiert: $leaf (unbekannt/veraltet)"
|
||||
else
|
||||
SKIPPED="$SKIPPED $leaf(${n}x)"
|
||||
fi
|
||||
done
|
||||
[ -n "$SKIPPED" ] && say "nicht automatisch angefasst:$SKIPPED"
|
||||
|
||||
if [ -z "$CHANGED" ]; then
|
||||
say "Nichts sicher automatisch reparierbar."
|
||||
cp -a "$BAK" "$CFG"
|
||||
echo "SELFREPAIR_SUGGESTION=$SUGG"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# ── 3) YAML noch gültig? ──────────────────────────────────────────────────────
|
||||
if [ -x "$VENV_PY" ] && ! "$VENV_PY" -c "import yaml; yaml.safe_load(open('$CFG'))" 2>/dev/null; then
|
||||
say "YAML nach Fix ungültig → zurück zum Backup."
|
||||
cp -a "$BAK" "$CFG"; echo "SELFREPAIR_SUGGESTION=$SUGG"; exit 2
|
||||
fi
|
||||
|
||||
# ── 4) Neustart + Gehirn-Check ────────────────────────────────────────────────
|
||||
systemctl --user restart hermes-gateway; sleep 6
|
||||
if bash "$SRC_DIR/hermes-postcheck.sh" >/dev/null 2>&1; then
|
||||
say "Gehirn-Check nach Selbstreparatur GRÜN."
|
||||
bash "$SRC_DIR/notify.sh" -s "[Box-Update]" \
|
||||
"Commander, nach dem Hermes-Update hakte der Selbsttest wegen geänderter Einstellungen — ich habe das selbst gerichtet (angepasst:${CHANGED// /, }). Der Test ist wieder grün, die neue Version läuft. Ein Rollback war nicht nötig." || true
|
||||
exit 0
|
||||
fi
|
||||
|
||||
say "Auch nach Selbstreparatur rot → zurück zum Backup (der Aufrufer rollt zurück)."
|
||||
cp -a "$BAK" "$CFG"
|
||||
systemctl --user restart hermes-gateway; sleep 6
|
||||
echo "SELFREPAIR_SUGGESTION=$SUGG"
|
||||
exit 2
|
||||
Reference in New Issue
Block a user