- ARCHITEKTUR.md (neu): Prozesse und Units, Rollen box/homelab und Partner-Instanz aus
Phase 2a (kern/einstellungen.py, kern/zeit.py, kern/partner.py, /api/partner), Modell-Rollen,
Bild-Weiche, wer welche Datei schreibt (inkl. mc2-quittiert.json), Meldeweg mit
Telegram-Zweitweg, alle 62 /api-Routen, Herkunftspruefung, kurzer Ausblick Homelab-Teil.
- BETRIEB.md (neu, loest RUNBOOK.md und BACKUP.md ab): Handgriffe, Meldungen und Betreffzeilen,
Waechter-Regeln (Partner nach 5 Takten, Spracherkennung nur wenn wach, Ausblenden-Knopf),
Dienste schlafen/wecken, zweistufiger Deploy mit Prueftor, Sicherung und Zurueckspielen,
Notfall, Pfade auf der Box.
- UPDATES.md (neu): Sonntags-Kette per Timer, Postchecks, Festhalten und Freigeben, Handbetrieb,
Update-Verlauf, Fallen.
- RADAR.md (neu): Modell-Radar (Leitplanken, Nachtablauf, Pruefstand, Uebernehmen/Verwerfen,
Merkliste) und Stack-Radar.
- WIEDERAUFBAU.md (neu, loest DISASTER_RECOVERY.md ab): entschlackte Schrittfolge, Anhang A
(llama-swap-Unit und Drop-ins) behalten.
Stand der Aussagen: Code in main 75611be.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
16 KiB
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 # welcher Stand seit wann live ist
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 mitOK telegram,OK telegram direkt,QUEUED für Morgen-DigestoderFALLBACK (…). Den Wortlaut nicht ändern:backend/services/update_verlauf.pyliest 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, optionalTELEGRAM_HOME_CHANNEL_THREAD_ID) liestnotify.shaus der Datei inMC_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) startetdeploy/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 alsnight-queue.txt.sendenliegen und kommt mit der nächsten Morgenmeldung. Zuletzt Gesendetes:night-queue.txt.zuletzt-gesendet. Das Skript kürzt außerdem~/mc2-notify.logab 3 MB auf die letzten 2 MB. - Scheitern beide Wege, steht die Meldung mit
FALLBACKim Protokoll und geht perwallan die Box-Konsolen (MC_NOTIFY_OHNE_WALL=1schaltetwallab). - Testen:
bash ~/mission-control-v2/deploy/notify.sh -s "[Test]" "Testmeldung"; nachts landet sie in der Warteschlange, mit-dkommt 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 (inactiveunddisabled) ist kein Befund. - Während eines Updates (ein Prozess
autoupdate.sh,update-engine.sh,update-swap.shoderhermes … updatelä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".
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 inAKTIVindeploy/deploy.sheintragen.
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). Laufen Update- oder Download-Jobs (/api/jobs), bricht der Deploy ab. 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):
pip installausbackend/requirements.txtundbackend/requirements-dev.txt.- Prüftor
deploy/pruefen.sh. - llama-swap-Config nur, wenn sich
deploy/llama-swap.config.yamlin 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-configselbst neu. Weicht die lebende Datei nur ab, gibt es einen Hinweis und sonst nichts. - Alle Repo-Units nach
~/.config/systemd/user/, dazu die Drop-insmc2-steward.service.d/warmset.confundmission-control-2.service.d/override.conf;daemon-reload;enablefür die Units inAKTIV; Timer starten (den Update-Timer nur, wenn er noch nicht läuft). - Cron-Skripte
deploy/jobs/*.shund*.pynach~/.hermes/scripts/. - Skills
deploy/skills/*nach~/.hermes/skills/<name_mit_unterstrich>/, abgelöste Skills nach~/.hermes/skills-archiv/. Pluginsdeploy/hermes-plugins/*nach~/.hermes/plugins/; aktiviert werden sie einmalig von Hand, Hermes startet der Deploy nicht neu. - Neustart von
mc2-gateway,mission-control-2undmc2-steward, dann bis zu 60 s Nachprüfung:/api/health,/gw/health, Steward aktiv.
Erfolg: eine Zeile in /srv/models/mc2-deploy.log und „Deploy ist live". 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 laufender Jobs), 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.
Sicherung
- Wann:
mc2-backup.timertä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 perrsync --deleteauf den Proxmox-Host (/var/lib/vz/mc2-backups, eigener Schlüssel~/.ssh/mc2_offsite; Ziel und Schlüssel überMC_BACKUP_OFFSITEundMC_BACKUP_OFFSITE_KEY). Scheitert der Spiegel, gilt die lokale Sicherung trotzdem. - Inhalt:
- aus
~/.hermes:config.yaml,.env,plugins/,cron/,state/; seit 24.09. auchmemories/(Lucys Gedächtnis),SOUL.md,skills/undscripts/; dazu Reste der früheren Desktop-Anbindung (agent-hooks/,shell-hooks-allowlist.json,desktop-gateway-token,pc-paths.yaml, Drop-insession-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.shspielt sie nicht zurück); - Lucys Stimmreferenz
~/.lucy-stimme/app/ref.wav; known-good/:pip freezeje venv, Versionen (OS, Kernel, MC2- und Hermes-Commit, llama.cpp, llama-swap) und die Liste der Modelldateien.
- aus
- 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>), weilrestore.shMC2 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:
- 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. - Oberfläche immer noch weg: per SSH
systemctl --user status mission-control-2undjournalctl --user -u mission-control-2 -n 100. Hilft ein Neustart der Dienste nicht:bash ~/mission-control-v2/deploy/restore.sh latest. - 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), Sicherungen (mc2-backups/), Radar-Downloads (radar/) |
/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 |