Files
Hitonabi 73a20daa52 wartung: Fix double-zero output in self-repair.sh grep command
n="0
0" erzeugt bei 0 Treffern '0\n0'.
Sichere Zuweisung: n=$(grep -cE ...); n=${n:-0}
2026-07-12 14:05:05 +02:00

100 lines
5.3 KiB
Bash
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.
#!/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); n=${n:-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