diff --git a/deploy/deploy.sh b/deploy/deploy.sh index 77d6bbe..b1c0fc6 100644 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -121,6 +121,11 @@ cp "$SRC/deploy/karten-gutachter.sh" "$HOME/.hermes/scripts/karten-gutachter.sh" # Harness + Suiten liegen im Repo ($SRC/deploy/pruefstand/), nur der Runner wird kopiert. cp "$SRC/deploy/trend-radar-feed.sh" "$HOME/.hermes/scripts/trend-radar-feed.sh" cp "$SRC/deploy/pruefstand/pruefstand.sh" "$HOME/.hermes/scripts/pruefstand.sh" +# Restore-Probe + Venv-Audit (17.07.2026, monatliche --no-agent-Crons): echte +# Wiederherstellungs-Drills (PBS-Canary + Tarball) und CVE-/Outdated-Audit der +# Python-Nebendienst-venvs (mem0, voice) — melden nur, ändern nichts. +cp "$SRC/deploy/restore-probe.sh" "$HOME/.hermes/scripts/restore-probe.sh" +cp "$SRC/deploy/venv-audit.sh" "$HOME/.hermes/scripts/venv-audit.sh" # Werkstatt-Kanban-Profil (Ideen-Queue, 10.07.2026): Leitplanken des Worker-Profils nachziehen # (Profil selbst wurde einmalig per `hermes profile create werkstatt --clone` angelegt). [ -d "$HOME/.hermes/profiles/werkstatt" ] && cp "$SRC/deploy/werkstatt-SOUL.md" "$HOME/.hermes/profiles/werkstatt/SOUL.md" @@ -128,7 +133,7 @@ cp "$SRC/deploy/pruefstand/pruefstand.sh" "$HOME/.hermes/scripts/pruefstand.sh" # statt Lucy-default. Profil selbst wird einmalig per `hermes profile create betrieb # --clone-from werkstatt` angelegt (model coder→hermes, Description fürs Specifier-Routing). [ -d "$HOME/.hermes/profiles/betrieb" ] && cp "$SRC/deploy/betrieb-SOUL.md" "$HOME/.hermes/profiles/betrieb/SOUL.md" -chmod +x "$HOME/.hermes/scripts/fremdblick.sh" "$HOME/.hermes/scripts/dreaming-feed.sh" "$HOME/.hermes/scripts/worker.sh" "$HOME/.hermes/scripts/chef-gutachter-feed.sh" "$HOME/.hermes/scripts/hermes-release-radar-feed.sh" "$HOME/.hermes/scripts/radar-selbstkritik-wrapper.sh" "$HOME/.hermes/scripts/idle-radar-feed.sh" "$HOME/.hermes/scripts/selbst-inventur.sh" "$HOME/.hermes/scripts/karten-gutachter.sh" "$HOME/.hermes/scripts/trend-radar-feed.sh" "$HOME/.hermes/scripts/pruefstand.sh" +chmod +x "$HOME/.hermes/scripts/fremdblick.sh" "$HOME/.hermes/scripts/dreaming-feed.sh" "$HOME/.hermes/scripts/worker.sh" "$HOME/.hermes/scripts/chef-gutachter-feed.sh" "$HOME/.hermes/scripts/hermes-release-radar-feed.sh" "$HOME/.hermes/scripts/radar-selbstkritik-wrapper.sh" "$HOME/.hermes/scripts/idle-radar-feed.sh" "$HOME/.hermes/scripts/selbst-inventur.sh" "$HOME/.hermes/scripts/karten-gutachter.sh" "$HOME/.hermes/scripts/trend-radar-feed.sh" "$HOME/.hermes/scripts/pruefstand.sh" "$HOME/.hermes/scripts/restore-probe.sh" "$HOME/.hermes/scripts/venv-audit.sh" # Werkstatt-Skill (Autonomie E6): Selbstwartungs-Kreislauf für Hermes. mkdir -p "$HOME/.hermes/skills/wartung" cp "$SRC/deploy/skills/wartung/SKILL.md" "$HOME/.hermes/skills/wartung/SKILL.md" diff --git a/deploy/restore-probe.sh b/deploy/restore-probe.sh new file mode 100644 index 0000000..5a1c5b1 --- /dev/null +++ b/deploy/restore-probe.sh @@ -0,0 +1,145 @@ +#!/usr/bin/env bash +# Restore-Probe (monatlich, 17.07.2026): „Backups sind Hoffnung, Restores sind Wissen." +# Spielt ECHTE Wiederherstellungen durch, statt nur Sicherungs-Erfolge zu zählen: +# 1) PBS: jüngsten host/aibox-Snapshot ermitteln (Alter < 36 h!), daraus den +# Kanarienvogel (state/backup-canary.txt aus hermes.pxar, selektiv via --pattern — +# ~/.hermes ist ~8 GB, wir ziehen nur die eine Datei) nach /tmp restaurieren und +# den Inhalt EXAKT vergleichen. Erstlauf-Fallback (Canary noch in keinem +# Snapshot): das winzige llamaswap.pxar komplett restaurieren und config.yaml +# auf Substanz prüfen. +# 2) Tarball: jüngstes mc2-state-*.tar.gz (Alter < 36 h) listen und den Canary +# (bzw. beim Erstlauf eine Kern-Datei) herausziehen und prüfen. +# 3) Canary für künftige Läufe sicherstellen (fester Inhalt → exakter Vergleich). +# Läuft als Hermes-Cron --no-agent (stdout = Telegram): monatlicher Herzschlag, bei +# Problemen ⚠️-Alarmtext. Komplett ohne sudo (PBS-Env + Client liegen im User-Raum). +set -uo pipefail + +PBS_ENV="$HOME/.config/pbs-backup/env" +PBS_BIN="$HOME/bin/proxmox-backup-client" +CANARY="$HOME/.hermes/state/backup-canary.txt" +CANARY_SOLL="MC2-Backup-Kanarienvogel v1 — dieser Inhalt ist konstant und wird nach dem Restore exakt verglichen." +TARBALL_DIR="/srv/models/mc2-backups" +MAX_ALTER_H=36 + +TMP="$(mktemp -d /tmp/restore-probe.XXXXXX)" +trap 'rm -rf "$TMP"' EXIT +FEHLER=() +BEFUND=() + +briefkasten() { # $1=Text (stiller Chronik-Spiegel) + 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": "Restore-Probe", + "source": "restore-probe", "priority": "silent"})) +PY +)" >/dev/null 2>&1 || true +} + +# ---------- 0) Canary sicherstellen (für DIESEN Lauf evtl. noch nicht im Backup) ---------- +if [ ! -f "$CANARY" ] || [ "$(cat "$CANARY" 2>/dev/null)" != "$CANARY_SOLL" ]; then + printf '%s' "$CANARY_SOLL" > "$CANARY" +fi + +# ---------- 1) PBS-Restore-Probe ---------- +if [ ! -f "$PBS_ENV" ] || [ ! -x "$PBS_BIN" ]; then + FEHLER+=("PBS-Probe unmöglich: Env ($PBS_ENV) oder Client ($PBS_BIN) fehlt") +else + set -a; source "$PBS_ENV"; set +a + SNAP_JSON="$("$PBS_BIN" snapshot list host/aibox --output-format json 2>/dev/null \ + || "$PBS_BIN" snapshots --output-format json 2>/dev/null || true)" + SNAP_INFO="$(printf '%s' "$SNAP_JSON" | python3 -c ' +import json, sys, time +try: + snaps = json.load(sys.stdin) +except Exception: + print("KEINE"); raise SystemExit +snaps = [s for s in snaps if isinstance(s, dict) + and s.get("backup-type") == "host" and s.get("backup-id") == "aibox"] +if not snaps: + print("KEINE"); raise SystemExit +s = max(snaps, key=lambda x: x.get("backup-time") or 0) +t = s.get("backup-time") or 0 +alter_h = (time.time() - t) / 3600 +stamp = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(t)) +print(f"host/aibox/{stamp}") +print(round(alter_h, 1)) +' 2>/dev/null || echo KEINE)" + SNAP="$(printf '%s\n' "$SNAP_INFO" | sed -n 1p)" + ALTER_H="$(printf '%s\n' "$SNAP_INFO" | sed -n 2p)" + if [ "$SNAP" = "KEINE" ] || [ -z "$SNAP" ]; then + FEHLER+=("PBS: kein host/aibox-Snapshot auffindbar (Sicherung steht evtl. STILL)") + else + if python3 -c "import sys; sys.exit(0 if float('$ALTER_H') <= $MAX_ALTER_H else 1)" 2>/dev/null; then + BEFUND+=("PBS-Snapshot $SNAP ist ${ALTER_H} h alt (frisch)") + else + FEHLER+=("PBS: jüngster Snapshot ist ${ALTER_H} h alt (> ${MAX_ALTER_H} h) — Sicherung steht STILL") + fi + # Selektives Canary-Restore aus hermes.pxar + mkdir -p "$TMP/pbs" + if "$PBS_BIN" restore "$SNAP" hermes.pxar "$TMP/pbs" \ + --pattern "state/backup-canary.txt" >/dev/null 2>&1 \ + && [ -f "$TMP/pbs/state/backup-canary.txt" ]; then + if [ "$(cat "$TMP/pbs/state/backup-canary.txt")" = "$CANARY_SOLL" ]; then + BEFUND+=("PBS-Restore: Canary aus hermes.pxar wiederhergestellt, Inhalt EXAKT korrekt ✅") + else + FEHLER+=("PBS-Restore: Canary wiederhergestellt, aber Inhalt WEICHT AB (Datenkorruption?)") + fi + else + # Erstlauf-Fallback: winziges llamaswap.pxar komplett + mkdir -p "$TMP/ls" + if "$PBS_BIN" restore "$SNAP" llamaswap.pxar "$TMP/ls" >/dev/null 2>&1 \ + && [ -s "$TMP/ls/config.yaml" ] && grep -q 'models:' "$TMP/ls/config.yaml"; then + BEFUND+=("PBS-Restore: llamaswap.pxar wiederhergestellt, config.yaml plausibel ✅ (Canary war noch nicht im Snapshot — ab dem nächsten dabei)") + else + FEHLER+=("PBS-Restore FEHLGESCHLAGEN: weder Canary noch llamaswap.pxar sauber wiederherstellbar") + fi + fi + fi +fi + +# ---------- 2) Tarball-Probe ---------- +TARBALL="$(ls -1t "$TARBALL_DIR"/mc2-state-*.tar.gz 2>/dev/null | head -1 || true)" +if [ -z "$TARBALL" ]; then + FEHLER+=("Tarball: keine mc2-state-Sicherung unter $TARBALL_DIR gefunden") +else + T_ALTER_H="$(python3 -c "import os, time; print(round((time.time()-os.path.getmtime('$TARBALL'))/3600, 1))")" + if python3 -c "import sys; sys.exit(0 if float('$T_ALTER_H') <= $MAX_ALTER_H else 1)"; then + BEFUND+=("Tarball $(basename "$TARBALL") ist ${T_ALTER_H} h alt (frisch)") + else + FEHLER+=("Tarball: jüngste Sicherung ist ${T_ALTER_H} h alt (> ${MAX_ALTER_H} h) — mc2-backup steht STILL") + fi + CANARY_PFAD="$(tar -tzf "$TARBALL" 2>/dev/null | grep 'backup-canary\.txt$' | head -1 || true)" + if [ -n "$CANARY_PFAD" ]; then + if [ "$(tar -xzf "$TARBALL" -O "$CANARY_PFAD" 2>/dev/null)" = "$CANARY_SOLL" ]; then + BEFUND+=("Tarball-Restore: Canary herausgezogen, Inhalt EXAKT korrekt ✅") + else + FEHLER+=("Tarball-Restore: Canary im Archiv, aber Inhalt WEICHT AB") + fi + else + KERN="$(tar -tzf "$TARBALL" 2>/dev/null | grep -E 'cron/|state/' | head -1 || true)" + if [ -n "$KERN" ] && [ -n "$(tar -xzf "$TARBALL" -O "$KERN" 2>/dev/null | head -c 1)" ]; then + BEFUND+=("Tarball-Restore: Kern-Datei ($KERN) herausgezogen, nicht leer ✅ (Canary ab der nächsten Sicherung dabei)") + else + FEHLER+=("Tarball-Restore FEHLGESCHLAGEN: Archiv listet keine Kern-Dateien oder Extraktion leer") + fi + fi +fi + +# ---------- Bericht (stdout = Telegram via --no-agent) ---------- +if [ "${#FEHLER[@]}" -eq 0 ]; then + echo "Commander, monatliche Restore-Probe: beide Wiederherstellungs-Wege funktionieren wirklich." + printf '• %s\n' "${BEFUND[@]}" + briefkasten "Restore-Probe grün: $(printf '%s · ' "${BEFUND[@]}")" +else + echo "⚠️ Commander, die monatliche Restore-Probe hat ein ECHTES Problem gefunden:" + printf '• %s\n' "${FEHLER[@]}" + if [ "${#BEFUND[@]}" -gt 0 ]; then + echo "Was funktioniert hat:" + printf '• %s\n' "${BEFUND[@]}" + fi + echo "Bitte zeitnah draufschauen — ein Backup, das nicht zurückkommt, ist keins." + briefkasten "⚠️ Restore-Probe ROT: $(printf '%s · ' "${FEHLER[@]}")" + exit 1 +fi diff --git a/deploy/self-smoke.sh b/deploy/self-smoke.sh index b1fc52e..62f7290 100644 --- a/deploy/self-smoke.sh +++ b/deploy/self-smoke.sh @@ -158,6 +158,21 @@ else FAILED+=("Browser-Tool (agent-browser fehlt — npm install -g agent-browser && agent-browser install --with-deps)") fi +# ── 7) Disk-Wächter (17.07.2026): /srv/models sammelt Modelle, Backups + Vault wachsen ── +# Schwelle 85 % — meldet mit den größten Brocken, damit die Aufräum-Entscheidung leicht fällt. +DISK_SCHWELLE="${DISK_SCHWELLE:-85}" +while read -r FS NUTZUNG ZIEL; do + PCT="${NUTZUNG%\%}" + if [ "${PCT:-0}" -ge "$DISK_SCHWELLE" ]; then + BROCKEN="$(du -s --block-size=1G /srv/models/*/ 2>/dev/null | sort -rn | head -3 \ + | awk '{printf "%s GB %s · ", $1, $2}' || true)" + say "FAIL · Disk: $ZIEL ist zu $NUTZUNG voll (Schwelle ${DISK_SCHWELLE} %)" + FAILED+=("Disk ($ZIEL zu $NUTZUNG voll — größte Brocken: ${BROCKEN:-unbekannt}Kandidat: rollenlose Fallback-Modelle prüfen)") + else + say "OK · Disk: $ZIEL bei $NUTZUNG" + fi +done < <(df --output=source,pcent,target / /srv/models 2>/dev/null | tail -n +2 | sort -u -k1,1) + # ── Selbstheilungen nur melden, nicht alarmieren ───────────────────────────── if [ "${#HEALED[@]}" -gt 0 ]; then HEAL_MSG="Commander, mein Selbst-Test hat etwas gefunden und direkt selbst repariert: diff --git a/deploy/trend-radar-feed.sh b/deploy/trend-radar-feed.sh index 959a38f..2a95a65 100644 --- a/deploy/trend-radar-feed.sh +++ b/deploy/trend-radar-feed.sh @@ -239,7 +239,7 @@ echo # ===================================================================== echo "### 3. WATCH-LISTE (mechanisch geprüft)" python3 - "$WATCHLIST" "$STATE" "$TMPD/watch.txt" <<'PY' -import json, sys, urllib.request +import json, re, sys, urllib.request def hole(url, timeout=30): req = urllib.request.Request(url, headers={"User-Agent": "mc2-trend-radar"}) @@ -272,6 +272,22 @@ for e in eintraege: neu = " ⚠️ NEU seit letzter Woche!" if tag != gesehen.get(key) else "" zeilen.append(f"- {key}: neuester Release {tag}{neu} ({e['warum']})") gesehen[key] = tag + elif typ == "github_release_major": + # PC-Watch (17.07.): nur MAJOR-Sprünge melden — Electron released wöchentlich, + # relevant ist der Chromium-Jahrgang, nicht jeder Patch. + d = json.loads(hole(f"https://api.github.com/repos/{e['repo']}/releases?per_page=1")) + tag = (d[0].get("tag_name") if isinstance(d, list) and d else "?") or "?" + m = re.search(r"(\d+)", tag) + major = m.group(1) if m else "?" + neu = " ⚠️ NEUE MAJOR-VERSION!" if major != gesehen.get(key, major) and major != "?" else "" + zeilen.append(f"- {key}: neuester Release {tag} (Major {major}){neu} ({e['warum']})") + gesehen[key] = major + elif typ == "pypi": + d = json.loads(hole(f"https://pypi.org/pypi/{e['paket']}/json")) + ver = ((d.get("info") or {}).get("version")) or "?" + neu = " ⚠️ NEU seit letzter Woche!" if ver != gesehen.get(key, ver) and ver != "?" else "" + zeilen.append(f"- {key}: PyPI-Version {ver}{neu} ({e['warum']})") + gesehen[key] = ver elif typ == "url_zeilen": text = hole(e["url"], timeout=45) passend = [z.strip() for z in text.splitlines() if e.get("muster", "") in z] diff --git a/deploy/trend-radar-watchlist.json b/deploy/trend-radar-watchlist.json index dff5d2f..d1b62d4 100644 --- a/deploy/trend-radar-watchlist.json +++ b/deploy/trend-radar-watchlist.json @@ -16,6 +16,20 @@ "bedingung": "Neuer ROCm-Release seit letzter Meldung", "warum": "Seit 7.14 ist TheRock der Produktions-Stack und AMD optimiert offiziell für die Halo-Familie — ROCm könnte Vulkan bei der Token-Erzeugung einholen. Bei neuem Release: Community-Grid-Zeilen unten gegenlesen." }, + { + "key": "electron-major", + "typ": "github_release_major", + "repo": "electron/electron", + "bedingung": "Neue MAJOR-Version seit letzter Meldung", + "warum": "Lucys Desktop-Shell am PC steht auf Electron 33 — jede Major dazwischen ist ein Jahrgang Chromium-Sicherheitspatches. Update = Rebuild-Dance am PC, bleibt Handarbeit; der Radar erinnert nur." + }, + { + "key": "pocket-tts", + "typ": "pypi", + "paket": "pocket-tts", + "bedingung": "Neue Version auf PyPI", + "warum": "Lucys Stimme am PC (installiert 2.1.0, german_24l) — neue Versionen können Stimm-/Pausen-Fixes bringen; Update bleibt Handarbeit am PC (pocket = DIE Stimme, Verdikt 16.07.)." + }, { "key": "llamacpp-rocm-diskussion", "typ": "url_zeilen", diff --git a/deploy/venv-audit.sh b/deploy/venv-audit.sh new file mode 100644 index 0000000..cef818c --- /dev/null +++ b/deploy/venv-audit.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# Venv-Audit (monatlich, 17.07.2026): die Python-Nebendienste (Mem0, 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/.mem0/venv:mem0" "$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##*:}" + if [ ! -x "$VENV/bin/pip" ]; then + ZEILEN+=("$NAME: venv fehlt unter $VENV — bitte prüfen") + continue + fi + # Veraltete Pakete (Anzahl reicht fürs Lagebild) + ALT_N="$("$VENV/bin/pip" list --outdated 2>/dev/null | tail -n +3 | grep -c '' || echo 0)" + # CVE-Prüfung gegen den eingefrorenen Stand (lokale Pfade/Editables ausfiltern) + "$VENV/bin/pip" freeze 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)' || echo 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 diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md index 05a4bc3..c7a15b6 100644 --- a/docs/RUNBOOK.md +++ b/docs/RUNBOOK.md @@ -37,8 +37,12 @@ höchstens „mach". Dieses Blatt ist NUR für den Fall, dass etwas klemmt. - **Mo 05:15** Release-Radar (Hermes-Neuerungen) · **Monatlich 1., 09:00** Monats-Review (Evolution-Radar + Selbstkritik) auf Telegram - **Sa 05:15** Trend-Radar (misst alle Modelle, vergleicht neue Engine-Builds, sucht - bessere Modell-Kandidaten) · **So 01:00** Prüfstand (testet gefundene Kandidaten nachts - mit echten Aufgaben durch — das Ergebnis kommt als Karte, DU entscheidest über Wechsel) + bessere Modell-Kandidaten; beobachtet auch Electron/pocket-tts für den PC) · + **So 01:00** Prüfstand (testet gefundene Kandidaten nachts mit echten Aufgaben durch — + das Ergebnis kommt als Karte, DU entscheidest über Wechsel) +- **Monatlich 1., 06:40** Restore-Probe (stellt eine Datei WIRKLICH aus PBS + Tarball + wieder her — meldet laut, falls ein Backup nicht zurückkommt) · **Monatlich 2., 06:40** + Venv-Audit (prüft die Python-Nebendienste auf bekannte Sicherheitslücken → Karte) ## Pinnwand: eine Ebene ist „GEPINNT" — was heißt das? diff --git a/docs/wissen/STACK.md b/docs/wissen/STACK.md index 4691177..b28ddf4 100644 --- a/docs/wissen/STACK.md +++ b/docs/wissen/STACK.md @@ -87,7 +87,9 @@ per Mini-Request anwärmen (direkt curlen ist zuverlässiger als warmup.sh). | 04:30 | **Chef-Gutachter** (gpt-oss richtet über die autonome Arbeit → Morgenlage) | | 05:15 Mo | **Release-Radar** (hermes-Releases gegen die Eigenbau-Landkarte; erster Lauf 13.07.) | | 05:15 Sa | **Trend-Radar** (Live-Puls ALLER Modell-Rollen + Engine-A/B gegen neuen llama.cpp-Build + Watch-Liste [ROCm/MMQ/Community-Grid] + HF-Kandidaten-Suche → max. 1 Prüfstand-Kandidat/Woche; Frühwarnung vor dem So-Auto-Update) | -| 01:00 So | **Prüfstand** (volles Programm für Modell-Kandidaten: echte Coding-/Agenten-/Recherche-/Deutsch-/Vision-Prüfungen + Tempo auf :5899 gegen die Amtsinhaber-Baseline; Download-Deckel 35 GB, Cache räumt sich selbst, Ergebnis = Karte — Rollen-Wechsel bleibt Commander-Klick) | +| 01:00 So | **Prüfstand** (volles Programm für Modell-Kandidaten: echte Coding-/Agenten-/Recherche-/Deutsch-/Vision-Prüfungen + Tempo auf :5899 gegen die Amtsinhaber-Baseline; Download-Deckel 35 GB, Cache räumt sich selbst, Ergebnis = Karte — Rollen-Wechsel bleibt Commander-Klick. Erkennt Engine-Drift → Tempo-Baseline-Refresh) | +| 06:40, 1. d. M. | **Restore-Probe** (stellt WIRKLICH wieder her: PBS-Canary aus hermes.pxar via --pattern + Tarball-Probe + Frische-Check < 36 h; ⚠️-Alarm, wenn ein Backup nicht zurückkommt) | +| 06:40, 2. d. M. | **Venv-Audit** (pip outdated + pip-audit-CVEs für mem0-/voice-venv; Funde = Karte, Update bleibt Commander-Entscheid) | | 07:00 | QNAP-Volume-Snapshot (7 behalten) | | 07:15 | self-smoke (Gateway/Tools/Voice/:9119; Alarm nur bei Rot) | | 08:00 | Daily-Briefing |