Files
mission-control-v2/docs/BETRIEB.md
T
HitonabiandClaude Opus 5.5 bff8478203 doku: Einstellungen, Stand-Datei, Zeitfenster und Radar-Schalter
- BEDIENUNG.md: Meldungen mit Telegram-Test, Update-Zeitfenster, Modell-Radar,
  Software-Stand, Altreste im Aufräumen, Telegram-Tabelle.
- BETRIEB.md: Einstellungsdatei, Drop-in und Stempel gegen das Nachholen,
  Neustart-Fenster, Radar-Schalter im Deploy, Stand-Datei, FALLBACK mit Grund.
- OFFENE-FAEDEN.md: Altreste stehen jetzt im Aufräumen; was bewusst nicht in
  der Liste steht; tote crontab-Zeile (curator-idle-watchdog.sh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 20:37:30 +02:00

23 KiB
Raw Blame History

Betrieb — Handgriffe, Meldungen, Wächter, Deploy, Sicherung, Notfall

Stand 24.09.2026, Code in main = 75611be. Für Techniker und Agenten. Gilt für die Instanz auf der KI-Box (Rolle box); die Homelab-Instanz ist noch nicht eingerichtet. Die Bedienung für den User steht in BEDIENUNG.md, die Update-Kette in UPDATES.md, das Modell-Radar in RADAR.md.

Handgriffe (SSH auf die Box)

ssh hitonabi@192.168.178.151
export XDG_RUNTIME_DIR=/run/user/$(id -u)              # sonst sieht systemctl --user nichts
systemctl --user status mission-control-2 mc2-gateway mc2-steward
systemctl --user list-timers                            # Radar, Sicherung, Updates, Morgenmeldung, projekte-sync
journalctl --user -u mc2-steward -n 100                 # Wächter; ebenso mc2-radar, mc2-autoupdate, mc2-backup
curl -s http://127.0.0.1:9001/api/health                # Gesamtzustand, Rolle und Instanz
curl -s http://127.0.0.1:9001/api/partner               # Lebenszeichen der anderen Instanz (falls eingerichtet)
curl -s http://127.0.0.1:9010/gw/health                 # Gateway und Motor
bash -lc 'hermes cron list'                             # Hermes-Jobs (hermes ist über SSH nicht im PATH)
tail -n 50 ~/mc2-notify.log                             # was zuletzt gemeldet wurde
tail -n 5 /srv/models/mc2-deploy.log                    # welche Stände wann live gingen
cat /srv/models/mc2-stand.json                          # welcher Stand gerade live ist (seit 24.09.)
cat /srv/models/mc2-einstellungen.json                  # Update-Zeitfenster und Radar-Schalter der Oberfläche
sudo journalctl -u llama-swap -n 100                    # Motor (System-Dienst)

Meldungen

  • Ein Weg: bash ~/mission-control-v2/deploy/notify.sh [-d] [-s "[Betreff]"] "Text" legt die Meldung in Lucys Briefkasten und schickt sie an Telegram. Protokoll: ~/mc2-notify.log, je Meldung eine Zeile mit OK telegram, OK telegram direkt, QUEUED für Morgen-Digest oder FALLBACK (…). Den Wortlaut nicht ändern: backend/services/update_verlauf.py liest ihn.
  • Zwei Wege zu Telegram (seit 24.09.): zuerst hermes send. Scheitert das oder fehlt Hermes, geht die Meldung direkt an die Telegram-Bot-API; die Zugangsdaten (TELEGRAM_BOT_TOKEN, TELEGRAM_HOME_CHANNEL, optional TELEGRAM_HOME_CHANNEL_THREAD_ID) liest notify.sh aus der Datei in MC_TELEGRAM_ENV (Standard ~/.hermes/.env). Das Token steht dabei nicht in der Prozessliste. Live bewiesen am 24.09. um 15:41.
  • Nachtruhe: 00:00–06:59 landet alles Nicht-Dringende in ~/.hermes/night-queue.txt. Dringend ist -d, ein Betreff mit „Alarm" oder „Notfall" oder ein Text, der mit „KRITISCH" beginnt.
  • Morgenmeldung: mc2-morgenmeldung.timer (07:00) startet deploy/morgenmeldung.sh. Es schickt eine Nachricht „Guten Morgen, Commander. Heute Nacht gab es N Meldungen" mit höchstens 3500 Zeichen. Drei Versuche im Abstand von 60 s; scheitert Telegram, bleibt der Stapel als night-queue.txt.senden liegen und kommt mit der nächsten Morgenmeldung. Zuletzt Gesendetes: night-queue.txt.zuletzt-gesendet. Das Skript kürzt außerdem ~/mc2-notify.log ab 3 MB auf die letzten 2 MB.
  • Scheitern beide Wege, steht die Meldung mit FALLBACK im Protokoll und geht per wall an die Box-Konsolen (MC_NOTIFY_OHNE_WALL=1 schaltet wall ab). Seit 24.09. steht im FALLBACK-Eintrag auch, warum der Zweitweg scheiterte: FALLBACK (telegram fehlgeschlagen: <Ausgabe von hermes send>; Zweitweg: <Grund>): <Text>, etwa „Zugangsdatei … fehlt oder ist nicht lesbar“ oder „Telegram lehnt ab, HTTP-Fehler“ (ohne Klammern, damit update_verlauf.py den Eintrag weiter trennen kann).
  • Testen: Einstellungen → Meldungen → „Test senden“ (je Instanz; POST /api/einstellungen/telegram-test bzw. /api/homelab/einstellungen/telegram-test). Der Knopf ruft notify.sh -d -s "[Test]" … mit MC_NOTIFY_NO_ANNOUNCE=1 (Lucy spricht den Test nicht) und liest das Ergebnis samt Grund über eine Kennung aus dem Melde-Log (services/einstellungen.py). Höchstens ein Test alle 20 s. Von Hand: bash ~/mission-control-v2/deploy/notify.sh -s "[Test]" "Testmeldung"; nachts landet sie in der Warteschlange, mit -d kommt sie sofort.
Betreff Absender Inhalt
[Box-Update] autoupdate.sh, jobs/sonntags-update.sh Ergebnis je Baustein, Wochenbericht, Neustart-Ankündigung; beginnt der Text mit „KRITISCH", ist es dringend
[Box-Problem] Wächter neuer roter Hinweis; nach 6 h erneut mit „Immer noch:"
[Box wieder ok] Wächter ein gemeldeter roter Hinweis ist erledigt
[Homelab-Problem] / [Homelab wieder ok] Wächter der Homelab-Instanz wie oben, sobald diese Instanz läuft
[Modell-Radar] backend/radar_lauf.py ein Kandidat hat den Nachttest bestanden
[Stack-Radar] jobs/stack-radar.sh Samstagsbericht
[Morgenmeldung] morgenmeldung.sh Sammelmeldung der Nacht, 07:00
[Alarm] Deploy deploy.sh Deploy gescheitert, der alte Stand läuft wieder (dringend)
ohne Betreff jobs/news-melden.sh Daily News Report, danach die Sprachnachricht

Wächter (backend/services/waechter.py, im mc2-steward)

Takt jede Minute, der erste 60 s nach dem Start. Ein Befund wird nach 2 Takten zum Hinweis; Timer-, Job-, Platten- und Pin-Befunde sofort, die Partner-Instanz erst nach 5 Takten (MC_WAECHTER_PARTNER_TAKTE, ein Neustart soll kein Alarm sein).

Prüfung Rot Gelb
Dienste (systemd) llama-swap, hermes-gateway, mc2-gateway, mission-control-2 voice-service, lucy-stimme, hermes-builtin-ui
Timer-Läufe mc2-backup, mc2-morgenmeldung, mc2-autoupdate projekte-sync, mc2-radar
Hermes-Jobs fehlgeschlagener Job mit „update" im Namen andere fehlgeschlagene Jobs; Werkzeugfehler im letzten Lauf
Kern (HTTP) Motor, Hirn, Hermes, MC2, Gateway antworten nicht; die Spracherkennung nur, wenn sie nicht schläft –
Platte (MC_DATEN_DIR, auf der Box /srv/models) ab 90 % ab 80 %
Festgehaltene Updates – jeder Pin
Partner-Instanz (nur mit MC_PARTNER_URL) „ antwortet nicht" –
Abgestürzte Prüfung – „Eine Prüfung des Wächters lief nicht"

In der Rolle homelab prüft der Wächter bisher nur Platte und Partner und meldet mit „[Homelab-Problem]".

  • Selbstreparatur: Nur ein abgestürzter Dienst (ActiveState=failed) wird neu gestartet, höchstens 2× je Stunde und Hinweis. Ein gestoppter Dienst (inactive) wird nur gemeldet. Ein schlafender Dienst (inactive und disabled) ist kein Befund. Bei Timer-Läufen schläft der Timer, nicht der Dienst dahinter (der ist static): Ist mc2-radar.timer abgeschaltet (Einstellungen → Radar aus), ist ein alter Fehlschlag von mc2-radar kein Befund mehr.
  • Während eines Updates (ein Prozess autoupdate.sh, update-engine.sh, update-swap.sh oder hermes … update läuft) prüft er Dienste und Kern nicht und repariert nichts. Die Oberfläche zeigt dann „Update läuft".
  • Meldungen: Rote Hinweise gehen an Telegram und in den Briefkasten, bei Fortbestand alle 6 h erneut; nachts gilt die Nachtruhe. Gelbe Hinweise stehen nur in der Oberfläche.
  • Knöpfe am Hinweis: „Neu starten" bzw. „Starten", „Protokoll", „Jetzt erneut laufen lassen" (Timer), „Erneut ausführen" (hermes cron run), „Freigeben" (Pin), „Ausblenden bis zum nächsten Lauf" (Werkzeugfehler eines Jobs; MC2 merkt sich den Lauf in /srv/models/mc2-quittiert.json, hat der nächste Lauf wieder Fehler, erscheint der Hinweis erneut).
  • Der Wächter ist der einzige Schreiber von /srv/models/mc2-waechter.json. Ist sein letzter Takt älter als 5 Minuten, zeigt die Startseite „Wächter schweigt".

Einstellungen der Oberfläche (Zeitfenster, Radar-Schalter)

Seit 24.09.2026, Logik in backend/services/einstellungen.py, Schnittstellen unter /api/einstellungen.

  • Eine Datei: /srv/models/mc2-einstellungen.json (update_fenster: {tag: 1–7, uhrzeit: "HH:MM"}, radar: {an}). Nur MC2 schreibt sie; deploy.sh und autoupdate.sh lesen sie. Fehlt sie, gilt So 04:30 und Radar an. Sie steckt in jeder Sicherung (mc2-*.json).
  • Update-Zeitfenster: Speichern schreibt das Drop-in ~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf (OnCalendar= leer, dann der neue Plan). Ablauf: Timer stoppen → Drop-in → daemon-reload → Stempel ~/.local/share/systemd/timers/stamp-mc2-autoupdate.timer auf jetzt → Timer starten. Grund: Der Timer hat Persistent=true. Ein laufender Timer rechnet beim Reload mit seinem letzten Lauf und dem neuen Plan, ein frisch gestarteter mit dem Stempel. Beides hätte einen schon vorbei gewesenen Termin sofort nachgeholt (so am 24.09. mittags passiert). Scheitert ein Schritt, kommt das alte Drop-in zurück, und der Timer läuft wieder. Während mc2-autoupdate.service läuft, lehnt MC2 das Ändern ab.
  • Neustart-Fenster: deploy/wartungsfenster.sh (von autoupdate.sh eingebunden) erlaubt den Neustart nur in den drei Stunden ab der vollen Stunde des Beginns: So 04:30 → So 04:00–06:59, Sa 23:30 → Sa 23:00 – So 01:59. Es liest das Fenster mit jq aus der Einstellungsdatei; MC_WARTUNGSFENSTER="<Tag> <HH:MM>" und MC_FENSTER_JETZT sind Test-Schalter. MC_AUTOUPDATE_REBOOT_JETZT=1 erzwingt den Neustart wie bisher.
  • Radar-Schalter: Aus = systemctl --user disable --now mc2-radar.timer (ein laufender Nachttest endet noch). An = enable, Stempel stamp-mc2-radar.timer auf jetzt, start — kein Nachholen, also tagsüber kein Laden.
  • Deploy: Das Drop-in fasst deploy.sh nie an. Steht das Radar auf aus, lässt der Deploy den Timer aus (disable --now) statt ihn wie früher einzuschalten; steht es auf an und läuft der Timer nicht, startet ihn der Deploy mit Stempel, also ohne Nachholen.
  • Wächter: Ein ausgeschaltetes Radar schläft (Timer inactive und disabled) und ist kein Befund; die Oberfläche zeigt unter Einstellungen „Schläft“.
  • Prüfen auf der Box: systemctl --user cat mc2-autoupdate.timer, systemctl --user list-timers mc2-autoupdate.timer mc2-radar.timer, systemctl --user is-enabled mc2-radar.timer.

Software-Stand

  • Stand-Datei: Nach dem Umschalten schreibt deploy.sh (nach der Nachprüfung) /srv/models/mc2-stand.json: commit (kurz), betreff, commit_datum, deploy_zeit. deploy/homelab/ausrollen.sh schreibt dasselbe nach erfolgreichem einrichten.sh in den Container (/var/lib/mc2/mc2-stand.json, Eigentümer mc2). Beide nutzen deploy/stand-schreiben.py (nur Standardbibliothek, atomar). Scheitert nur das Schreiben, gilt der Deploy trotzdem.
  • Anzeige: /api/instanz liefert stand mit, /api/partner/instanz den der anderen Instanz; Einstellungen → Software-Stand zeigt beide und einen Hinweis, wenn sie abweichen. Ohne Stand-Datei liest MC2 den Stand aus git (quelle: "git", ohne Deploy-Zeit), sonst unbekannt.

Dienste schlafen legen und wecken

  • Schlafen legen: systemctl --user disable --now <unit> (seit 24.09.: box-console, voice-service).
  • Wecken bis zum nächsten Neustart der Box: Knopf „Wecken" unter „Dienste und Protokolle" oder systemctl --user start <unit>.
  • Dauerhaft wecken: systemctl --user enable --now <unit>; für einen Neuaufbau die Unit zusätzlich in AKTIV in deploy/deploy.sh eintragen.

Deploy

Voraussetzung: Der Stand liegt in main auf Gitea (Branch, Prüftor grün, Merge). Dann auf der Box:

bash ~/mission-control-v2/deploy/deploy.sh

Stufe 1 (die bisherige Fassung des Skripts): Sperre gegen einen zweiten Deploy (flock auf $XDG_RUNTIME_DIR/mc2-deploy.lock). Läuft ein Update-Auftrag (Gruppe maintenance in /api/jobs), bricht der Deploy ab — das Update führt Skripte aus diesem Checkout aus. Downloads laufen weiter: Aufträge sind eigene systemd-Einheiten und überleben den Neustart von MC2. Dann den alten Stand merken, git fetch und git merge --ff-only origin/main und die neue Fassung als Stufe 2 starten.

Stufe 2 (die neue Fassung):

  1. pip install aus backend/requirements.txt und backend/requirements-dev.txt.
  2. Prüftor deploy/pruefen.sh.
  3. llama-swap-Config nur, wenn sich deploy/llama-swap.config.yaml in diesem Deploy geändert hat: Sicherung /etc/llama-swap/config.yaml.bak-<Zeit> (die letzten 5 bleiben), dann ersetzen. llama-swap lädt dank --watch-config selbst neu. Weicht die lebende Datei nur ab, gibt es einen Hinweis und sonst nichts.
  4. Alle Repo-Units nach ~/.config/systemd/user/, dazu die Drop-ins mc2-steward.service.d/warmset.conf und mission-control-2.service.d/override.conf; daemon-reload; enable für die Units in AKTIV; Timer starten (den Update-Timer nur, wenn er noch nicht läuft). Das Drop-in mc2-autoupdate.timer.d/zeitfenster.conf gehört der Oberfläche und bleibt unangetastet. Den Radar-Timer schaltet der Deploy nach dem Schalter in mc2-einstellungen.json: aus = disable --now, an = enable und, falls er nicht läuft, Start mit Stempel.
  5. Cron-Skripte deploy/jobs/*.sh und *.py nach ~/.hermes/scripts/.
  6. Skills deploy/skills/* nach ~/.hermes/skills/<name_mit_unterstrich>/, abgelöste Skills nach ~/.hermes/skills-archiv/. Plugins deploy/hermes-plugins/* nach ~/.hermes/plugins/; aktiviert werden sie einmalig von Hand, Hermes startet der Deploy nicht neu.
  7. Neustart von mc2-gateway, mission-control-2 und mc2-steward, dann bis zu 60 s Nachprüfung: /api/health, /gw/health, Steward aktiv.

Erfolg: eine Zeile in /srv/models/mc2-deploy.log, die Stand-Datei /srv/models/mc2-stand.json und „Deploy ist live". Danach (Schritt 8) zieht der Deploy den Homelab-Teil mit, sobald box-partner.sh einen Partner eingerichtet hat: deploy/homelab/ausrollen.sh mit der IP aus partner.conf. Scheitert das, bleibt die Box live und es kommt „[Alarm] Deploy"; MC_DEPLOY_OHNE_HOMELAB=1 lässt den Schritt aus. Scheitert ein Schritt: git reset --hard auf den alten Stand, llama-swap-Config zurück (falls ersetzt), Dienste neu, Zeile GESCHEITERT im Log und die dringende Meldung „[Alarm] Deploy".

Schalter: MC_DEPLOY_TROTZDEM=1 (trotz laufendem Update-Auftrag), MC_DEPLOY_OHNE_TESTS=1 (Prüftor überspringen, nur im Notfall), MC_DEPLOY_SKIP_SWAP_CONFIG=1 (llama-swap-Config nie anfassen).

Nicht Teil des Deploys: das Frontend bauen (frontend/dist kommt fertig aus Git), die Root-Kopie von warmup.sh, Neustarts von llama-swap und Hermes.

Prüftor deploy/pruefen.sh (am PC vor dem Push, auf der Box im Deploy): Shell-Syntax (bash -n für deploy/*.sh und deploy/jobs/*.sh), Python-Syntax aller versionierten .py außerhalb von frontend/, ruff check . (nur wo ruff installiert ist; requirements-dev.txt bringt nur pytest mit), Import von app, gateway_app, steward und radar_lauf, dann pytest backend/tests. Die Frontend-Prüfungen (npm run lint, npm test, npm run build) laufen nur am PC.

Probelauf auf der Box deploy/probelauf-box.sh (am PC, vor dem Merge nach main): schickt den lokalen HEAD als Abzug nach /tmp auf der Box und lässt dort das Prüftor mit dem Python des Box-Checkouts laufen. Ändert auf der Box sonst nichts. Grund: Unter Linux zeigen sich Wettläufe, die am Windows-PC durchgehen (24.09.).

Homelab-Teil einrichten (Phase 3/4)

Jeder Schritt braucht das OK des Users (Container anlegen, Ausführer als root auf dem Host, Telegram-Zugang in den Container). Alles läuft am PC in Git-Bash, im Repo; SSH-Zugang zu pve (Schlüssel id_lucy_infra).

  1. bash deploy/homelab/container-anlegen.sh — unprivilegierter Debian-13-Container (nächste freie ID, 1 Kern, 1 GB RAM, 4 GB, DHCP, Autostart, Etikett mc2), SSH-Schlüssel wie bei allen Gästen. Gibt die IP aus.
  2. bash deploy/homelab/ausrollen.sh <ip> — Code von HEAD in /opt/mc2, einrichten.sh (Nutzer mc2, Python- Umgebung, Units mc2-homelab, mc2-homelab-steward, mc2-homelab-morgenmeldung.timer). Auch jedes spätere Update des Homelab-Teils geht so (erst Prüftor und Probelauf auf der Box).
  3. Telegram-Zugang (nur mit OK): TELEGRAM_BOT_TOKEN und TELEGRAM_HOME_CHANNEL in /etc/mc2/telegram.env (Eigentümer root:mc2, 0640).
  4. bash deploy/homelab/ausfuehrer-einrichten.sh <ip> — Ausführer, Unit und Konfiguration (0600) auf den Host.
  5. bash deploy/homelab/box-partner.sh <ip> — Drop-ins partner.conf für mission-control-2 und mc2-steward auf der Box; ab dann prüfen sich beide Instanzen gegenseitig.

Prüfen: curl http://<ip>:9001/api/homelab/ziele (nach etwa einer Minute stehen die Geräte darin), systemctl status mc2-ausfuehrer auf dem Host, Seite „Homelab“ der Oberfläche.

Sicherung

  • Wann: mc2-backup.timer täglich 03:30 (+≤5 min); außerdem vor jedem Hermes-Update, vor jedem Zurückspielen und per Knopf „Jetzt sichern". Von Hand: bash ~/mission-control-v2/deploy/backup.sh.
  • Wohin: /srv/models/mc2-backups/mc2-state-<Zeit>.tar.gz, Rechte 600 (enthält ~/.hermes/.env), die letzten 14 bleiben. Danach Spiegel per rsync --delete auf den Proxmox-Host (/var/lib/vz/mc2-backups, eigener Schlüssel ~/.ssh/mc2_offsite; Ziel und Schlüssel über MC_BACKUP_OFFSITE und MC_BACKUP_OFFSITE_KEY). Scheitert der Spiegel, gilt die lokale Sicherung trotzdem.
  • Inhalt:
    • aus ~/.hermes: config.yaml, .env, plugins/, cron/, state/; seit 24.09. auch memories/ (Lucys Gedächtnis), SOUL.md, skills/ und scripts/; dazu Reste der früheren Desktop-Anbindung (agent-hooks/, shell-hooks-allowlist.json, desktop-gateway-token, pc-paths.yaml, Drop-in session-token.conf);
    • /etc/llama-swap/config.yaml;
    • der Box-Wart-Zustand /srv/models/mc2-*.json;
    • die Units aus ~/.config/systemd/user/ und /etc/systemd/system/llama-swap.service.d/ (nur zum Nachschlagen, restore.sh spielt sie nicht zurück);
    • Lucys Stimmreferenz ~/.lucy-stimme/app/ref.wav;
    • known-good/: pip freeze je venv, Versionen (OS, Kernel, MC2- und Hermes-Commit, llama.cpp, llama-swap) und die Liste der Modelldateien.
  • Eine Sicherung ist seit 24.09. rund 12 MB groß.
  • Nicht enthalten: Modelle (neu ladbar), Code (Git), venvs, ~/.ssh (auch nicht der Spiegel-Schlüssel).
  • Weitere Schichten: Die Sicherung der Box nach PBS (pbs-backup.timer) ist seit 21.08. aus. PBS sichert die Proxmox-Container, das QNAP macht Snapshots; beides läuft auf den anderen Geräten und ist hier nicht geprüft.

Zurückspielen

  • Per Oberfläche: Updates → Sicherungen → „Zurückspielen". MC2 startet restore.sh --yes <Datei> als eigene systemd-Unit (mc2-restore-<Zeit>), weil restore.sh MC2 selbst stoppt.
  • Per SSH:
cd ~/mission-control-v2
bash deploy/restore.sh --list                     # lokal und auf dem Proxmox-Host
bash deploy/restore.sh --dry-run latest           # zeigt, was passieren würde
bash deploy/restore.sh latest                     # mit Rückfrage; --yes ohne
bash deploy/restore.sh --mit-gedaechtnis latest   # Gedächtnis und Zustand auch überschreiben
bash deploy/restore.sh --pull-offsite             # alle Sicherungen vom Proxmox-Host holen

Ablauf: Sicherheits-Sicherung des jetzigen Stands → Dienste mission-control-2, mc2-gateway, mc2-steward, hermes-gateway stoppen → Hermes-Config, .env, Plugins, cron/, state/, llama-swap-Config und die Desktop-Reste zurück → Gedächtnis, SOUL.md, Skills, Cron-Skripte und mc2-*.json nur, wenn sie fehlen oder mit --mit-gedaechtnis → Dienste starten → /api/health. Fehlt eine Sicherung lokal, holt restore.sh sie vom Proxmox-Host. Sicherungen von vor dem 27.08. enthalten noch das Verzeichnis des abgelösten Gedächtnis-Dienstes; es wird nicht zurückgespielt.

Notfall

Box tot oder Oberfläche weg:

  1. Strom und Netz prüfen, die Box einmal per Knopf neu starten. Alles startet von selbst (systemd, Linger). Nach 2–3 Minuten http://192.168.178.151:9001 öffnen.
  2. Oberfläche immer noch weg: per SSH systemctl --user status mission-control-2 und journalctl --user -u mission-control-2 -n 100. Hilft ein Neustart der Dienste nicht: bash ~/mission-control-v2/deploy/restore.sh latest.
  3. Totalschaden (neue Platte, neue Hardware): WIEDERAUFBAU.md.

Deploy kaputt: deploy.sh rollt selbst zurück. Von Hand: den vorigen Commit aus /srv/models/mc2-deploy.log nehmen, git -C ~/mission-control-v2 reset --hard <commit> und systemctl --user restart mc2-gateway mission-control-2 mc2-steward.

llama-swap-Config kaputt: ls -t /etc/llama-swap/config.yaml.bak-*, die passende Sicherung nach /etc/llama-swap/config.yaml kopieren; llama-swap lädt selbst neu. Ältere Stände stecken in jeder Sicherung.

Motor startet keine Modelle: sudo journalctl -u llama-swap -n 100. Nach einem Engine-Sprung ist die typische Ursache ein gestrichenes Flag (wissen/FALLEN.md). Den vorigen Build hebt update-engine.sh in /opt/llamacpp-vulkan.bak auf, die vorige llama-swap-Version update-swap.sh in /usr/local/bin/llama-swap.bak.

Hermes kaputt: journalctl --user -u hermes-gateway -n 100, dann bash ~/mission-control-v2/deploy/hermes-postcheck.sh. Rückweg wie in UPDATES.md: alter Commit in ~/.hermes/hermes-agent, Config aus der letzten Sicherung, systemctl --user restart hermes-gateway.

Festgehaltener Baustein: Knopf „Freigeben" (Startseite oder Updates-Seite); der nächste Sonntagslauf versucht das Update erneut.

Wo was liegt (Box)

Pfad Inhalt
~/mission-control-v2 Checkout von main (nur über deploy.sh ändern)
~/mission-control-v2/backend/.venv Python-Umgebung des Box-Warts (Python 3.14)
~/.config/systemd/user/ User-Units und Drop-ins
/srv/models/ Modelle, Box-Wart-Zustand (mc2-*.json, darunter mc2-einstellungen.json und mc2-stand.json), Sicherungen (mc2-backups/), Radar-Downloads (radar/)
~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf Update-Zeitfenster aus der Oberfläche (nur MC2 schreibt es)
/etc/llama-swap/config.yaml lebende llama-swap-Config (+ .bak-*)
/opt/llamacpp-vulkan/, /usr/local/bin/llama-server Motor (llama.cpp Vulkan)
/usr/local/bin/llama-swap, /usr/local/bin/llama-swap-warmup.sh Router und Vorwärm-Skript (Root-Kopie)
~/.hermes/ Hermes: Code (hermes-agent/), config.yaml, .env, SOUL.md, memories/, skills/, scripts/, cron/, logs/
~/.lucy-stimme/ Lucys Stimme (pocket-tts), Referenz app/ref.wav
~/.voice/ Umgebung der Spracherkennung (voice_service/install.sh)
~/projekte/ Spiegel der Gitea-Repos (projekte-sync)
~/mc2-notify.log, ~/.hermes/night-queue.txt Meldeprotokoll, Nacht-Warteschlange