Systemaudit vom 27.08.2026. Alle Befunde gemessen, nicht vermutet.
VIER STILLE DEFEKTE
1. mc2-steward startete seit Wochen nicht (live: 207.609 Neustarts).
steward.py importierte services.memory, das beim Mem0-Ausbau geloescht
wurde -> ImportError bei jedem Start. Re-Warm- und Health-Waechter
waren damit tot.
2. Jedes Hermes-Update wurde automatisch zurueckgerollt.
hermes-postcheck.sh prueft vier Dinge, die es seit dem 07.08. nicht mehr
gibt (Sidecar :8765, /api/memory, memory.provider, mc2-memory-Plugin).
Die Checks konnten nicht gruen werden -> autoupdate.sh wertete jedes
Update als rot und rollte es zurueck. Checks ersatzlos entfernt; der
Tool-Smoke laeuft ohnehin durch den echten Agenten.
3. 7 von 12 Skills waren per Knopfdruck nicht startbar.
deploy.sh kopiert Skills mit tr '-' '_' nach ~/.hermes/skills/,
routers/skills.py gab Hermes aber den Ordnernamen MIT Bindestrich.
Der Knopf meldete Erfolg, ausgefuehrt wurde nichts. Neu: _hermes_name().
4. deploy.sh warf bei jedem Deploy die Live-Modellkonfiguration weg.
MC2 schreibt /etc/llama-swap/config.yaml selbst; die Repo-Datei ist nur
ein Abzug (ihm fehlt u.a. kritiker/Devstral). Jetzt: erst sichern, Diff
zeigen, dann kopieren. MC_DEPLOY_SKIP_SWAP_CONFIG=1 ueberspringt.
MEM0-AUSBAU VOLLENDET (Kriterium 3: 17 -> 0 Dateien)
- mem0_service/, mcp/mcp_memory.py und hermes/plugins/mc2-memory entfernt;
das Plugin schickte bei JEDEM Turn zwei 404-Requests an tote Routen.
- MEMORY_DB/MEM0_SERVICE_URL, _mem0_reachable(), MC_MEMORY_DB und
MC_MEM_DEDUPE_ENABLED aus Config/Router/Unit entfernt.
- mem0_ms war strukturell tot (park("retrieve") wird nirgends mehr
aufgerufen) -> aus Backend, API-Typ und Latenzkarte entfernt.
- Verbinden-Tab: tote Gedaechtnis-MCP-Leitung raus, Status-Kachel bleibt.
- AGENTS.md beschrieb Mem0 noch als aktiv - korrigiert.
GATEWAY-ROBUSTHEIT
- _proxy gab bei ungueltigen Payloads HTTP 500 (gemessen 5/5: Rohtext,
leerer Body, JSON-Liste, JSON-String, null) -> jetzt 5/5 HTTP 400.
- Bild-Weiche ohne Deckel: 10 Bilder x 2 Versuche x 240 s hielten den
Client bis zu 80 min. Neu: MC_CODER_IMAGE_MAX (4), Rueckfall auf die
Vision-Umleitung.
- /v1/models: nicht-JSON von der Engine gab 500 -> jetzt 502.
UNITS UND DEPLOY
- mc2-steward.service, dessen warmset-Drop-in und voice-service.service
fehlten im Repo, obwohl maintenance.py und stack-postcheck.sh sie
voraussetzen. 1:1 von der laufenden Box uebernommen.
- deploy.sh startete mc2-steward nie neu; restore.sh liess mc2-gateway und
mc2-steward mit alter Config weiterlaufen. Beide ergaenzt.
FRONTEND
- useEigenleben rief /api/eigenleben - existiert im Backend nicht und wurde
nirgends genutzt. Samt Typen entfernt.
- Anleitung beschrieb einen Gedaechtnis-Tab, den es nicht gibt.
- Abgeglichen: alle uebrigen 63 Frontend-Aufrufe treffen echte Routen, alle
5 SSE-Invalidation-Keys sind gemappt, keine ungefangenen Promises.
Gates: compileall gruen - ruff "All checks passed" - tsc gruen - vite build
gruen (dist aktualisiert) - Importe app/steward/gateway_app gruen.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
99 lines
4.6 KiB
Bash
99 lines
4.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Venv-Audit (monatlich, 17.07.2026): die Python-Nebendienste (Voice) altern
|
|
# eingefroren — kein Auto-Update-Kanal deckt sie ab. Dieser Audit MELDET nur
|
|
# (bewusst kein Auto-Update: Python-Deps brechen gern):
|
|
# je venv: veraltete Pakete zählen (pip list --outdated) + bekannte
|
|
# Sicherheitslücken prüfen (pip-audit gegen den eingefrorenen Stand).
|
|
# Werkzeug: eigenes Audit-venv (~/.venv-audit, wird beim Erstlauf angelegt) — die
|
|
# Dienst-venvs selbst werden NICHT angefasst. CVE-Funde → Kanban-Karte (triage,
|
|
# idempotent je Monat). Läuft als Hermes-Cron --no-agent (stdout = Telegram).
|
|
set -uo pipefail
|
|
|
|
VENVS=("$HOME/.voice/venv:voice")
|
|
AUDIT_VENV="$HOME/.venv-audit"
|
|
HERMES="$HOME/.local/bin/hermes"
|
|
MONAT="$(date '+%Y-%m')"
|
|
TMP="$(mktemp -d /tmp/venv-audit.XXXXXX)"
|
|
trap 'rm -rf "$TMP"' EXIT
|
|
|
|
briefkasten() {
|
|
curl -sf -m 5 -X POST "${MC_ANNOUNCE_URL:-http://127.0.0.1:9001/api/voice/announce}" \
|
|
-H 'Content-Type: application/json' \
|
|
--data "$(python3 - "$1" <<'PY'
|
|
import json, sys
|
|
print(json.dumps({"text": sys.argv[1], "subject": "Venv-Audit",
|
|
"source": "venv-audit", "priority": "silent"}))
|
|
PY
|
|
)" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
# ---------- Werkzeug-venv sicherstellen (einmalig) ----------
|
|
if [ ! -x "$AUDIT_VENV/bin/pip-audit" ]; then
|
|
python3 -m venv "$AUDIT_VENV" >/dev/null 2>&1 || true
|
|
"$AUDIT_VENV/bin/pip" install -q --upgrade pip pip-audit >/dev/null 2>&1 || true
|
|
fi
|
|
|
|
ZEILEN=()
|
|
CVE_DETAILS=""
|
|
CVES_GESAMT=0
|
|
|
|
for EINTRAG in "${VENVS[@]}"; do
|
|
VENV="${EINTRAG%%:*}"; NAME="${EINTRAG##*:}"
|
|
# uv-venvs haben KEIN eigenes pip (Befund Erstlauf 17.07.) → das Audit-venv
|
|
# inspiziert deren site-packages von außen (pip --path); Dienst-venvs bleiben unberührt.
|
|
SP="$("$VENV/bin/python" -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])' 2>/dev/null || true)"
|
|
if [ -z "$SP" ] || [ ! -d "$SP" ]; then
|
|
ZEILEN+=("$NAME: venv fehlt/unlesbar unter $VENV — bitte prüfen")
|
|
continue
|
|
fi
|
|
# Veraltete Pakete (Anzahl reicht fürs Lagebild). grep -c druckt IMMER genau eine
|
|
# Zahl → KEIN "|| echo 0" (das hängte eine zweite Zeile an → Rechenfehler, Befund
|
|
# 17.07.); zur Sicherheit auf Ziffern reduzieren.
|
|
ALT_N="$("$AUDIT_VENV/bin/pip" list --outdated --path "$SP" 2>/dev/null | tail -n +3 | grep -c '.')"
|
|
ALT_N="${ALT_N//[!0-9]/}"; ALT_N="${ALT_N:-0}"
|
|
# CVE-Prüfung gegen den eingefrorenen Stand (lokale Pfade/Editables ausfiltern)
|
|
"$AUDIT_VENV/bin/pip" list --format=freeze --path "$SP" 2>/dev/null \
|
|
| grep -vE ' @ |^-e |^#' > "$TMP/$NAME.txt" || true
|
|
CVE_N=0
|
|
if [ -x "$AUDIT_VENV/bin/pip-audit" ] && [ -s "$TMP/$NAME.txt" ]; then
|
|
AUDIT_OUT="$("$AUDIT_VENV/bin/pip-audit" -r "$TMP/$NAME.txt" --progress-spinner off 2>&1 || true)"
|
|
if printf '%s' "$AUDIT_OUT" | grep -qi 'No known vulnerabilities'; then
|
|
CVE_N=0
|
|
else
|
|
CVE_N="$(printf '%s\n' "$AUDIT_OUT" | grep -cE '^[a-zA-Z0-9_.-]+ +[0-9][^ ]* +(GHSA|PYSEC|CVE)')"
|
|
CVE_N="${CVE_N//[!0-9]/}"; CVE_N="${CVE_N:-0}"
|
|
if [ "${CVE_N:-0}" -gt 0 ]; then
|
|
CVE_DETAILS="${CVE_DETAILS}
|
|
== ${NAME} ==
|
|
$(printf '%s\n' "$AUDIT_OUT" | grep -E '^[a-zA-Z0-9_.-]+ +[0-9][^ ]* +(GHSA|PYSEC|CVE)' | head -10)"
|
|
fi
|
|
fi
|
|
else
|
|
ZEILEN+=("$NAME: pip-audit nicht verfügbar (Audit-venv kaputt oder offline?) — nur Outdated-Zählung")
|
|
fi
|
|
CVES_GESAMT=$(( CVES_GESAMT + ${CVE_N:-0} ))
|
|
ZEILEN+=("$NAME: ${ALT_N} Pakete veraltet · ${CVE_N:-0} bekannte Sicherheitslücken")
|
|
done
|
|
|
|
# ---------- Bericht ----------
|
|
if [ "$CVES_GESAMT" -eq 0 ]; then
|
|
echo "Commander, monatlicher Venv-Audit der Python-Nebendienste — keine bekannten Sicherheitslücken:"
|
|
printf '• %s\n' "${ZEILEN[@]}"
|
|
echo "(Veraltete Pakete sind nur ein Lagebild; aktualisiert wird bewusst nur mit Anlass.)"
|
|
briefkasten "Venv-Audit grün: $(printf '%s · ' "${ZEILEN[@]}")"
|
|
else
|
|
echo "⚠️ Commander, der monatliche Venv-Audit hat ${CVES_GESAMT} bekannte Sicherheitslücken gefunden:"
|
|
printf '• %s\n' "${ZEILEN[@]}"
|
|
echo "Details liegen als Karte in der Ideen-Queue — Update bleibt dein Entscheid."
|
|
if [ -x "$HERMES" ]; then
|
|
"$HERMES" kanban create "Venv-Audit ${MONAT}: ${CVES_GESAMT} Sicherheitslücken in Python-Diensten" \
|
|
--body "Automatischer monatlicher Audit (restore-/venv-Kreislauf 17.07.). Funde (pip-audit):
|
|
${CVE_DETAILS}
|
|
|
|
Empfehlung: betroffene Pakete gezielt aktualisieren (venv-weise, mit Dienst-Restart + Postcheck) — KEIN pauschales Upgrade." \
|
|
--triage --created-by venv-audit --idempotency-key "venv-audit-${MONAT}" >/dev/null 2>&1 || true
|
|
fi
|
|
briefkasten "⚠️ Venv-Audit: ${CVES_GESAMT} Sicherheitslücken — Karte liegt in der Queue."
|
|
exit 1
|
|
fi
|