diff --git a/docs/ARCHITEKTUR.md b/docs/ARCHITEKTUR.md
new file mode 100644
index 0000000..80bc5ab
--- /dev/null
+++ b/docs/ARCHITEKTUR.md
@@ -0,0 +1,177 @@
+# Architektur des Homelab Orchestrators (Teil Box-Wart)
+
+_Stand 24.09.2026, Code in `main` = `75611be`. Für Agenten und Techniker. Versionen, Ports und Modelle mit
+Messwerten: [wissen/STACK.md](wissen/STACK.md)._
+
+Der Homelab Orchestrator (vormals Mission Control 2, kurz „MC2") hat zwei Bereiche: „Box-Wart" für die KI-Box und
+„Homelab" für den Proxmox-PC. Zwei Instanzen, eine Oberfläche: Dieselbe Codebasis läuft auf der KI-Box (Rolle `box`)
+und später als Container auf dem Proxmox-PC (Rolle `homelab`). Die Homelab-Instanz ist noch nicht eingerichtet
+(Phase 3, braucht User-OK); dieses Dokument beschreibt deshalb vor allem die Rolle `box`.
+
+Der Box-Wart hält die KI-Box aktuell, passt auf sie auf und sucht bessere Modelle. Er besteht aus vier eigenen
+Python-Prozessen, einer Bash-Schicht für Updates, Sicherung und Meldungen und aus Zustandsdateien unter
+`/srv/models`. Er steuert zwei fremde Programme: llama-swap mit llama.cpp (die Modelle) und Hermes (der Agent „Lucy"
+mit Telegram).
+
+## Überblick
+
+```mermaid
+flowchart LR
+ subgraph Netz["Heimnetz"]
+ BR["Browser (PC, Handy)"]
+ OC["OpenChamber (PC)"]
+ LD["Lucy-Desktop (PC)"]
+ NQ["NerdQuiz (Arcane)"]
+ end
+ subgraph Box["KI-Box"]
+ MC2["MC2 :9001
Oberfläche, /api"]
+ GW["mc2-gateway :9010
/v1, Bild-Weiche"]
+ ST["mc2-steward
Wächter, Re-Warm"]
+ RD["mc2-radar
00:30"]
+ HE["Hermes :8642
Lucy, Telegram"]
+ LS["llama-swap :8080"]
+ end
+ BR --> MC2
+ OC -->|/v1| MC2
+ LD -->|/api, /v1| MC2
+ MC2 -->|/v1 roh| GW
+ HE -->|/v1| GW
+ GW --> LS
+ NQ -->|/v1, Alias fast| LS
+ RD -->|Baseline| LS
+ ST -.->|prüft| MC2
+```
+
+Alle Modell-Anfragen enden bei llama-swap, das je Modell einen `llama-server` startet. NerdQuiz geht als einziger
+Client an MC2 vorbei direkt auf `:8080`. Nur den Radar-Kandidaten startet der Radar-Lauf nachts als eigenen
+`llama-server` auf `:5899`, neben llama-swap.
+
+## Prozesse
+
+| Prozess (Unit) | Einstieg | Aufgabe | Eigener Zustand |
+|---|---|---|---|
+| `mission-control-2` (`:9001`) | `backend/app.py` | Oberfläche aus `frontend/dist`; 62 `/api`-Routen; reicht `/v1` roh an den Gateway weiter (`MC_V1_UPSTREAM`); reicht das Hermes-Dashboard unter `/hermes-ui/` durch (HTTP und WebSocket); Erinnerungen; Update- und Download-Jobs als Kindprozesse (`services/jobengine.py`) | Briefkasten, Erinnerungen, Routing-Policy, Hugging-Face-Zugang, ausgeblendete Hinweise |
+| `mc2-gateway` (`127.0.0.1:9010`) | `backend/gateway_app.py` | `/v1` mit `model: auto` und Bild-Weiche, Kontext-Warnung, `/gw/health` | Token-Zähler (`~/.hermes/token_stats.json`) |
+| `mc2-steward` | `backend/steward.py` | Re-Warm (alle 90 s, lädt das Hirn nach, wenn nichts geladen ist), Config-Watch (5 s), Wächter (jede Minute) | `mc2-waechter.json` (einziger Schreiber) |
+| `mc2-radar` (Timer 00:30) | `backend/radar_lauf.py` | Suche und Nachttest neuer Modelle | `mc2-radar.json`, Baseline, `/srv/models/radar/` |
+| Bash-Schicht | `deploy/*.sh` | Updates (`autoupdate.sh` mit `update-swap.sh`, `update-engine.sh`, Postchecks, `self-repair.sh`), Sicherung (`backup.sh`, `restore.sh`), Meldungen (`notify.sh`, `morgenmeldung.sh`), Vorwärmen (`warmup.sh`), `projekte-sync.sh`, Deploy (`deploy.sh`, `pruefen.sh`) | Pins, Meldeprotokoll, Nacht-Warteschlange, Deploy-Log |
+
+Alle vier Python-Prozesse teilen die flachen Pakete `backend/services/` und `backend/kern/` (Import über
+`PYTHONPATH` und `WorkingDirectory` der Units). Router bleiben dünn, die Logik liegt in `backend/services/`
+(siehe `AGENTS.md`).
+
+**Warum getrennte Prozesse** (Umbau v3, 15.07.): Der Gateway ist klein, wird kaum angefasst und startet sich
+selbst neu (`Restart=always`, `TimeoutStopSec=5`). MC2 darf deshalb neu starten, ohne dass Anfragen von Lucy und
+OpenChamber abreißen. Der Steward überlebt MC2-Neustarts und kann MC2 selbst überwachen. Rückweg ist jeweils eine
+Zeile in `deploy/mission-control-2.service` (`MC_V1_UPSTREAM` bzw. `MC_REWARM_ENABLED=0`/`MC_SENTRY_ENABLED=0`
+entfernen).
+
+Fremde Dienste, die der Box-Wart nur steuert oder überwacht: `llama-swap` (System-Unit, `--watch-config`),
+`hermes-gateway`, `hermes-builtin-ui`, `lucy-stimme`, `voice-service` und `box-console` (beide schlafen seit 24.09.).
+
+## Rollen und Partner-Instanz (seit 24.09., Phase 2a)
+
+- **`backend/kern/einstellungen.py`:** `MC_ROLLE` (`box` oder `homelab`, Standard `box`), `MC_INSTANZ` (Anzeigename,
+ Standard „Box-Wart" bzw. „Homelab"), `MC_DATEN_DIR` (Zustandsdateien; Standard `/srv/models` auf der Box,
+ `/var/lib/mc2` im Homelab), `MC_PARTNER_URL` (Basis-URL der anderen Instanz, leer = keine) und `MC_PARTNER_NAME`.
+- **`backend/kern/zeit.py`:** die eine Zeitzone `MC_LOCAL_TZ` (Standard `Europe/Berlin`) statt einer Kopie je Modul.
+- **`backend/kern/partner.py`:** Lebenszeichen der anderen Instanz über deren `/api/health` (5 s Zeitlimit, 15 s
+ zwischengespeichert).
+- **Rolle `box`** hängt alle Box-Router ein. **Rolle `homelab`** lädt nur `/api/health` und `/api/partner`; die
+ Homelab-Router folgen in Phase 3. `steward.py` betreibt Re-Warm und Config-Watch nur in der Rolle `box`; der
+ Wächter prüft im Homelab nur Platte und Partner.
+- **`/api/health`** nennt `rolle` und `instanz`; `engine_reachable`, `gateway_reachable` und `brain` gibt es nur auf
+ der Box.
+- **`GET /api/partner`** liefert das Lebenszeichen der anderen Instanz. **`/api/partner/`** reicht an
+ `/api/` weiter (alle Methoden, nach der Herkunftsprüfung). `partner/…` und `stream` werden nicht
+ weitergereicht: Zwei Instanzen sollen sich keine Anfrage endlos zureichen, und der Live-Strom würde offen bleiben.
+- **Wächter:** Antwortet die andere Instanz nicht, entsteht der Hinweis „ antwortet nicht", rot erst nach
+ `MC_WAECHTER_PARTNER_TAKTE` = 5 Takten, damit ein Neustart kein Alarm ist.
+- Die Units setzen weder `MC_ROLLE` noch `MC_PARTNER_URL`: Die Box läuft in der Rolle `box` und ohne Partner, bis die
+ zweite Instanz eingerichtet ist.
+
+## Modelle und Modell-Rollen
+
+- **Rollen-Aliase statt Namen:** Clients fragen `hermes`/`fast` (Hirn), `coder`/`heavy` (Coder), `vision` und
+ `coder-bild` (Bild-Zwillinge), `embed`, `reranker`. Die Eintragsnamen ändern sich beim Tausch, die Aliase nicht.
+- **Gruppen:** `brains` (`swap: false`, `persistent: true`, `exclusive: false`) enthält nur das Hirn, es bleibt
+ geladen. `bild` (`swap: true`, `exclusive: false`) enthält die zwei Zwillinge, höchstens einer ist geladen.
+ Alles andere lädt bei Bedarf und geht nach `ttl` wieder raus.
+- **Bild-Weiche** (`routers/gateway_proxy.py`, `services/router_logic.py`): Hat der aktuelle Schritt ein Bild, geht
+ die Anfrage an den Zwilling der Rolle (Coder-Ziele an `coder-bild`, alles andere an `vision`). Ältere Bilder
+ beschreibt `vision` einmal als Text (Cache je Bild), damit der Rest beim schnellen Modell mit Draft bleibt.
+- **`model: auto`** ist die Chat-Spur: normal `fast`, bei langen oder schweren Anfragen `heavy` (Schwellen in der
+ Routing-Policy `mc2-routing.json`, ohne Datei gelten die Env-Defaults).
+- **Warm halten:** `warmup.sh` (Root-Kopie in `/usr/local/bin/llama-swap-warmup.sh`) läuft nach jedem Start von
+ llama-swap. Danach übernimmt der Re-Warm im Steward; welches Modell warm bleibt, sagt `MC_WARMSET` im Drop-in
+ `mc2-steward.service.d/warmset.conf` (heute nur das Hirn).
+- **Speicherregel:** Warm-Set plus größtes Bedarfsmodell ≤ ~115 GB, sonst droht ein Kernel-OOM.
+
+## Wer schreibt was
+
+| Datei | Schreiber | Regel |
+|---|---|---|
+| `/etc/llama-swap/config.yaml` | MC2 (Modelle, Rollen, Aufräumen, Hirn-Umstellung), Radar („Übernehmen"), `deploy.sh`, `restore.sh` | Die lebende Datei ist die Wahrheit. MC2 schreibt nur unter `llamaswap.config_sperre()` (Thread-Sperre plus `flock` auf `.mc2-config.lock`) und atomar. `deploy.sh` überschreibt nur, wenn sich `deploy/llama-swap.config.yaml` im selben Deploy geändert hat. Jede Änderung lädt llama-swap neu und entlädt alle Modelle. |
+| `~/.hermes/config.yaml` | Hermes; MC2 nur bei der Hirn-Umstellung; `autoupdate.sh` und `restore.sh` beim Rückweg; `self-repair.sh` | MC2 ändert nur `model.default`/`model.model`, atomar, vorher `config.yaml.bak-hirn-`; bei einem Lesefehler schreibt es nichts. |
+| `mc2-steward.service.d/warmset.conf` | `deploy.sh`; das Radar beim Übernehmen eines neuen Hirns | Das Radar tauscht den Namen in `MC_WARMSET` und startet den Steward neu. |
+| `/srv/models/mc2-waechter.json` | nur der Steward | MC2 liest und führt Knöpfe aus; der nächste Takt sieht das Ergebnis. Der Ordner folgt `MC_DATEN_DIR`. |
+| `/srv/models/mc2-quittiert.json` | nur MC2 (Knopf „Ausblenden bis zum nächsten Lauf") | Der Steward liest; ein ausgeblendeter Werkzeugfehler-Hinweis kommt wieder, wenn der nächste Lauf des Jobs erneut Fehler hat. |
+| `/srv/models/mc2-radar.json` (+ `mc2-radar-baseline.json`) | Radar-Lauf und MC2 | jede Änderung unter `flock`, atomar |
+| `/srv/models/mc2-pins.json` | `autoupdate.sh` hält fest; MC2 gibt frei | Format: Baustein → `pinned`, `version`, `grund`, `datum` |
+| `/srv/models/mc2-announce.json` (Briefkasten, 200 Einträge) | nur MC2 | Steward und Gateway liefern per HTTP (`MC_ANNOUNCE_HTTP`), `notify.sh` per `POST /api/voice/announce` |
+| `/srv/models/mc2-reminders.json` | nur MC2 | Erinnerungs-Schleife und `/api/reminders` im selben Prozess |
+| `/srv/models/mc2-geheimnisse.json` | MC2 (Einstellungen) | Hugging-Face-Zugang, Rechte 0600 |
+| `/srv/models/mc2-discover.json` | MC2, Radar | Cache der Hugging-Face-Entdeckung (12 h) |
+| `/srv/models/mc2-deploy.log` | `deploy.sh` | eine Zeile je Deploy, auch gescheiterte |
+| `~/mc2-notify.log` | `notify.sh` (anhängen), `morgenmeldung.sh` (über 3 MB auf 2 MB kürzen) | Quelle des Update-Verlaufs; der Wortlaut „QUEUED für Morgen-Digest" muss bleiben |
+| `~/.hermes/night-queue.txt` | `notify.sh` (anhängen), `morgenmeldung.sh` (übernehmen, senden) | nicht gesendeter Stapel bleibt als `.senden` liegen |
+
+## Meldeweg
+
+`deploy/notify.sh` ist der eine Meldeweg: Die Meldung geht in Lucys Briefkasten (`POST /api/voice/announce`) und an
+Telegram. Zwischen 00:00 und 06:59 sammelt `notify.sh` alles Nicht-Dringende in der Nacht-Warteschlange;
+`morgenmeldung.sh` (Timer 07:00) schickt es als eine Nachricht. Dringend ist `-d`, ein Betreff mit „Alarm" oder
+„Notfall" oder ein Text, der mit „KRITISCH" beginnt. Lucy-Desktop fragt den Briefkasten ab
+(`/api/voice/announcements`) und spricht neue Einträge.
+
+Telegram hat zwei Wege: zuerst `hermes send --to telegram`; scheitert das oder fehlt Hermes (die Homelab-Instanz hat
+keins), geht die Meldung direkt an die Telegram-Bot-API (seit 24.09., live bewiesen 15:41). Die Zugangsdaten liest
+`notify.sh` aus der Datei in `MC_TELEGRAM_ENV` (Standard `~/.hermes/.env`: `TELEGRAM_BOT_TOKEN`,
+`TELEGRAM_HOME_CHANNEL`, optional `TELEGRAM_HOME_CHANNEL_THREAD_ID`) und gibt das Token über stdin an `curl`, damit
+es nicht in der Prozessliste steht. Erst wenn beide Wege scheitern, bleiben Protokoll und `wall`
+(`MC_NOTIFY_OHNE_WALL=1` schaltet `wall` ab). Einzelheiten und Betreffzeilen: [BETRIEB.md](BETRIEB.md).
+
+## Schnittstellen
+
+In der Rolle `box` 62 Routen unter `/api`: 60 des Box-Warts (seit 24.09., vorher 95) und 2 für die
+Partner-Instanz. In der Rolle `homelab` gibt es nur `/api/health` und die Partner-Routen.
+
+| Gruppe | Routen |
+|---|---|
+| Cockpit (`routers/boxwart.py`) | `GET /start`, `GET /hinweise`, `POST /hinweise/{id}/aktion/{aktion}`, `GET /modelle/nutzung`, `GET /updates/verlauf`, `POST /updates/festgehalten/{baustein}/freigeben`, `GET /modelle/aufraeumen`, `POST /modelle/aufraeumen/loeschen` |
+| Radar (`routers/radar.py`) | `GET /radar`, `POST /radar/suche`, `POST /radar/{id}/uebernehmen`, `POST /radar/{id}/verwerfen` |
+| Modelle (`routers/models.py`) | `GET /models`, `GET /discover`, `POST /models/register`, `GET /hf/search`, `GET /hf/quants`, `POST /models/install`, `GET /jobs`, `POST /jobs/{id}/cancel`, `POST /models/{id}/role`, `POST /models/unload`, `POST /models/{id}/unload`, `POST /models/{id}/load`, `DELETE /models/{id}` |
+| Wartung (`routers/maintenance.py`) | `GET /maintenance/updates`, `GET /maintenance/update-details`, `POST` `check-updates`, `os-update`, `engine-update`, `swap-update`, `hermes-update`, `update-all`, `restart`; `GET /maintenance/logs`; `GET`/`POST /maintenance/geheimnisse` |
+| System (`routers/system.py`) | `GET /system/status`, `GET /system/services`, `POST /system/backup`, `GET /system/backups`, `POST /system/restart`, `GET /system/token-stats` |
+| Lucy und Sprache (`routers/voice.py`) | `POST /alarm`, `POST /voice/announce`, `GET /voice/announcements`, `POST /voice/stt`, `POST /voice/turn`, `POST /voice/chat`, `GET /lucy/stimme/health`, `POST /lucy/stimme/tts`, `POST /lucy/stimme/tts/stream` |
+| Sonstiges | `GET /health`, `GET /stream` (Live-Strom, SSE), `GET /routing`, `GET`/`POST /reminders`, `DELETE /reminders/{id}`, `GET /zeitmaschine`, `POST /zeitmaschine/restore` |
+| Partner (`routers/partner.py`) | `GET /partner` (Lebenszeichen), `/partner/{pfad}` (Durchreiche, alle Methoden) |
+
+Dazu `/v1/*` (Weiterleitung an den Gateway), `/hermes-ui/` und die Auslieferung der Oberfläche. Unbekannte
+`/api`-Pfade liefern einen Fehler (bei `GET` 404) statt der Startseite. Die MCP-Server in `mcp/` sprechen dieselben
+Routen.
+
+**Herkunftsprüfung** (`backend/services/herkunft.py`, statt Anmeldung): Schreibende Aufrufe (`POST`, `PUT`, `PATCH`,
+`DELETE`) auf `/api/` mit dem `Origin` einer fremden Webseite lehnt MC2 mit 403 ab. Erlaubt bleiben Aufrufe ohne
+`Origin` (Skripte, `curl`), `Origin: null` bzw. `file://` (Lucy-Desktop), dieselbe Adresse wie die Oberfläche und die
+Entwicklungs-Ports 5173, 5180, 5181. `/v1` ist nicht betroffen.
+
+## Ausblick: der Homelab-Teil (Phasen 3 und 4)
+
+Stand der Recherche vom 24.09.2026: Community-Script-Container aktualisiert man im Container mit `update`, ohne
+Rückfragen mit `PHS_SILENT=1`; die installierte Version steht in `/root/.`. Die Proxmox-API kann keine Befehle
+in Containern ausführen und gibt die Liste der Host-Updates nur mit Schreibrecht heraus. Deshalb: ein Lese-Schlüssel,
+ein Proxmox-Webhook für Host-Pakete und ein kleiner Ausführer auf dem Host mit festen Aktionen. Container mit
+Bind-Mount (z. B. PBS) lassen sich nicht snapshotten, dort gilt „Backup statt Snapshot". Arcane meldet Image-Updates
+über eine eigene API mit Schlüssel. Ein Exit-Code 0 beweist kein gelungenes Update; geprüft wird unabhängig
+(HTTP-Probe, Dienststatus, Version). Fahrplan: [wissen/OFFENE-FAEDEN.md](wissen/OFFENE-FAEDEN.md).
diff --git a/docs/BACKUP.md b/docs/BACKUP.md
deleted file mode 100644
index d8ccfb4..0000000
--- a/docs/BACKUP.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Backup & Restore
-
-Sichert den **nicht wiederherstellbaren Zustand** der AI-Box. Code kommt aus Git,
-Modelle sind neu ladbar — gesichert wird nur, was sonst weg wäre.
-
-## Was im Backup ist
-- **Gedächtnis:** `/srv/models/mem0/` (Chroma-Vektoren + `history.db`)
-- **Hermes:** `~/.hermes/config.yaml`, `~/.hermes/.env` (**Secrets!**), `~/.hermes/plugins/`
-- **Engine:** `/etc/llama-swap/config.yaml`
-
-Nicht enthalten (bewusst): GGUF-Modelle, MC2-Code (Git), venvs, systemd-Units (aus `deploy.sh`).
-
-Jedes Backup ist ein Tarball `mc2-state-.tar.gz` unter `/srv/models/mc2-backups/`,
-`chmod 600` (enthält `.env`). Es werden die letzten **14** behalten.
-
-## Off-Box-Spiegel (C12) — zweite Kopie WEG von der Box
-Nach jedem lokalen Backup spiegelt `backup.sh` die Tarballs per `rsync` auf ein **zweites Gerät**
-(Default: **Proxmox-Host** `root@192.168.178.108:/var/lib/vz/mc2-backups`). Stirbt die NVMe der
-Box, liegen die Backups noch auf dem Proxmox. Die Retention (14) wird per `--delete` mitgezogen,
-`chmod 600` bleibt erhalten. Der Off-Box-Sync ist **best-effort**: schlägt er fehl, gilt das
-lokale Backup trotzdem als erfolgreich (Warnung im Log).
-
-- **Auth:** eigener SSH-Key `~/.ssh/mc2_offsite` (nur für dieses Backup), im Proxmox in
- `root/.ssh/authorized_keys` **gehärtet** eingetragen: `from=""`, kein Port-/Agent-/
- X11-Forwarding, kein PTY → der Key kann nur rsync-Backup, keinen Voll-Root-Fernzugang.
-- **Ziel/Key überschreibbar:** `MC_BACKUP_OFFSITE` (leer = Off-Box aus) und `MC_BACKUP_OFFSITE_KEY`.
-
-## Backup erstellen
-- **Automatisch:** systemd-Timer `mc2-backup.timer`, täglich ~03:30. Status:
- `systemctl --user list-timers mc2-backup.timer`
-- **Manuell (Box):** `bash ~/mission-control-v2/deploy/backup.sh`
-- **UI:** Wartungs-Drawer → „Snapshot erstellen"
-
-## Wiederherstellen (Restore)
-Restore läuft **nur per CLI auf der Box** (bewusst — er stoppt Dienste und überschreibt Configs).
-Vor dem Zurückspielen macht das Skript automatisch ein Sicherheits-Backup des aktuellen Zustands.
-
-```bash
-cd ~/mission-control-v2
-bash deploy/restore.sh --list # vorhandene Backups anzeigen
-bash deploy/restore.sh --dry-run latest # zeigen, was passieren würde
-bash deploy/restore.sh latest # neuestes wiederherstellen (mit Rückfrage)
-bash deploy/restore.sh mc2-state-YYYYMMDD-HHMMSS.tar.gz # bestimmtes Backup
-```
-
-Ablauf: Sicherheits-Backup → Dienste stoppen (`mem0-service`, `mission-control-2`,
-`hermes-gateway`) → Dateien zurückspielen (mem0 wird **ersetzt**, Configs überschrieben) →
-Dienste starten → Health-Check.
-
-### Wenn die Box-Platte tot ist (Off-Box-Restore)
-`restore.sh` kennt den Off-Box-Spiegel: fehlt ein Backup lokal, holt es sich das Skript
-automatisch vom Proxmox. Kein manuelles Kopieren nötig.
-
-```bash
-bash deploy/restore.sh --list # zeigt lokal UND Off-Box (Proxmox)
-bash deploy/restore.sh --pull-offsite # ganzen Off-Box-Bestand nach lokal spiegeln
-bash deploy/restore.sh latest # zieht das jüngste — vom Proxmox, falls lokal leer
-```
-
-## Erledigt
-- **Off-Box-Spiegel (C12):** rsync auf den Proxmox-Host, live E2E verifiziert (2026-07-03).
- Box ist Bare Metal (kein Proxmox-Gast → kein vzdump), daher aktiver Push statt vzdump-Pull.
diff --git a/docs/BETRIEB.md b/docs/BETRIEB.md
new file mode 100644
index 0000000..0529d65
--- /dev/null
+++ b/docs/BETRIEB.md
@@ -0,0 +1,234 @@
+# 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](BEDIENUNG.md), die Update-Kette in [UPDATES.md](UPDATES.md), das Modell-Radar in [RADAR.md](RADAR.md)._
+
+## Handgriffe (SSH auf die Box)
+
+```bash
+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 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).
+- **Testen:** `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.
+- **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".
+
+## Dienste schlafen legen und wecken
+
+- Schlafen legen: `systemctl --user disable --now ` (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 `.
+- Dauerhaft wecken: `systemctl --user enable --now `; 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
+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):
+
+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-` (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).
+5. Cron-Skripte `deploy/jobs/*.sh` und `*.py` nach `~/.hermes/scripts/`.
+6. Skills `deploy/skills/*` nach `~/.hermes/skills//`, 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` 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.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-.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 ` als eigene
+ systemd-Unit (`mc2-restore-`), weil `restore.sh` MC2 selbst stoppt.
+- **Per SSH:**
+
+```bash
+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](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 ` 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](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](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 |
diff --git a/docs/DISASTER_RECOVERY.md b/docs/DISASTER_RECOVERY.md
deleted file mode 100644
index de56a06..0000000
--- a/docs/DISASTER_RECOVERY.md
+++ /dev/null
@@ -1,325 +0,0 @@
-# Konzept: Bare-Metal-Wiederaufbau + First-Run-Wizard (VOLLSTÄNDIG)
-
-> **Zweck:** Plan für den „hard crash"-Fall — die Box (`tobisniceaiarbeitstier`, Ubuntu 26.04,
-> AMD Ryzen AI MAX+ 395 / gfx1151, 122 GB RAM) muss von **null** wiederherstellbar sein.
-> **Anspruch:** *ALLES* ist erfasst — Engine, Hermes-Konfig 1:1, Voice/Klonstimme,
-> Memory, Browser, MCP, Skills, Secrets. Pro Komponente entscheidet der Nutzer im Wizard:
-> **1:1 zurück** · **neu/Default** · **weglassen**.
->
-> Dieses Dokument ist die **Spezifikation für eine künftige Implementierungs-Session** — es baut
-> noch nichts. Stand: 2026-06-28.
-
----
-
-## 1. Leitprinzip: 1:1 ODER modular — der Nutzer wählt
-
-Der Wizard behandelt jede Komponente als **eigene Kachel mit drei Modi**:
-
-| Modus | Bedeutung |
-|---|---|
-| 📦 **1:1 aus Backup** | Exakter alter Zustand wird zurückgespielt (Configs, Daten, Klonstimme). |
-| 🆕 **Neu / Default** | Frische Installation mit sinnvollen Defaults (z.B. entfesseltes Hermes-Profil). |
-| ⏭️ **Weglassen** | Komponente wird (vorerst) nicht installiert. |
-
-Ein „Alles 1:1"-Knopf wählt überall 📦 (wo ein Backup existiert), sonst 🆕. So bekommt der Nutzer
-entweder den exakten alten Stand oder kann gezielt entrümpeln.
-
----
-
-## 2. Was es schon gibt (wiederverwenden)
-
-| Asset | Datei | Deckt ab |
-|---|---|---|
-| Code-Deploy | `deploy/deploy.sh` | git pull + venvs + Units + Restart. **Setzt Engine/llama-swap/Dirs/venvs voraus.** |
-| Zustands-Backup | `deploy/backup.sh` + `mc2-backup.{service,timer}` | **Aktuell** (live): mem0, `~/.hermes/{config.yaml,.env,plugins}`, llama-swap-config. Retention 14. **Für echtes 1:1 zu erweitern** — fertiges Snippet in **Anhang B** (§5). |
-| Restore | `deploy/restore.sh` | Spielt Tarball zurück (mit Pre-Restore-Sicherung). |
-| Engine | `deploy/provision-engine.sh` | llama.cpp Vulkan/RADV-Build (root). |
-| Voice-Setup | `voice_service/install.sh` | venv + Piper-Binary + dt. Piper-Stimmen + Chatterbox (best-effort). |
-| Updates | `deploy/update-engine.sh`, `update-swap.sh` | Laufende Engine/Router-Updates. |
-| Postchecks | `deploy/stack-postcheck.sh`, `hermes-postcheck.sh` | Funktionsprüfung → Wizard-Verifikationsschritt. |
-
----
-
-## 3. VOLLSTÄNDIGER Komponenten-Katalog
-
-> **Scan-verifiziert (2026-06-28)** gegen `backend/config.py`, alle `backend/services/*` & `routers/*`,
-> `frontend/src/{nav.ts,views,components/voice}`, `voice_service/app.py`, `mem0_service/`, `deploy/*`.
-> Alle persistenten Schreibpfade, Dienste, Secrets und Env-Vars sind unten erfasst.
-
-Legende Restore-Quelle: 📦 = aus Backup-Tarball · ⬇️ = Re-Download/Install (Skript) · 🌐 = Git ·
-🔑 = Secret (Nutzer/Generieren) · 🆕 = im Wizard neu gewählt.
-„Im Backup?" = deckt der **aktuelle** `backup.sh` es ab.
-
-### A · OS & System (L0, root/sudo, einmalig)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| Ubuntu 26.04, User `hitonabi`, `enable-linger` | — | ⬇️ manuell | n/a |
-| System-Pakete: python3.14+venv, git, curl, jq, ttyd, uv | — | ⬇️ apt/curl | nein |
-| Vulkan-Stack: mesa-vulkan-drivers, libvulkan1, vulkan-tools | — | ⬇️ apt | nein |
-| Chrome-Libs (Browser): `agent-browser install --with-deps` | — | ⬇️ apt | nein |
-| Verzeichnis-Layout: `/srv/models/{,mem0,mc2-backups,drafts}`, `/etc/llama-swap/` | — | ⬇️ mkdir+chown | nein |
-
-### B · Inferenz-Engine + Router (L1, root)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| llama.cpp (Vulkan) → `llama-server` | `/opt/llamacpp-vulkan`, `/usr/local/bin/llama-server` | ⬇️ provision-engine.sh / update-engine.sh (ggml-org Release) | nein (re-build) |
-| **llama-swap** Binary (Router `:8080`) | `/usr/local/bin/llama-swap` | ⬇️ **bekannt:** `mostlygeek/llama-swap`-Release (Rezept in `update-swap.sh`) | nein (re-download) |
-| **llama-swap systemd-System-Unit** | `/etc/systemd/system/llama-swap.service` (+ `.d/` Drop-ins) | ⬇️ Bootstrap legt sie an — **kompletter Unit-Inhalt in Anhang A** (von der Box abgegriffen; Drop-ins via provision-engine.sh) | nein |
-| llama-swap-Config (Modelle/Rollen) | `/etc/llama-swap/config.yaml` | 📦 | **ja** |
-| Draft-Modelle (Spec-Decoding) | `/srv/models/drafts/` | ⬇️ Re-Download | nein |
-
-### C · MC2-App (L2, userspace)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| MC2-Code | `~/mission-control-v2` | 🌐 Git (Gitea) | n/a |
-| Backend-venv (Python 3.14) | `backend/.venv` | ⬇️ deploy.sh | nein (rebuild) |
-| Frontend (gebaut) | `frontend/dist` | 🌐 Git | n/a |
-| systemd-User-Dienst `mission-control-2` (`:9001`) | `~/.config/systemd/user/` | ⬇️ deploy.sh | nein |
-
-### D · 3D-Avatar — **ausgebaut (28.08.2026)**
-
-MC2 hat keinen Avatar mehr. `frontend/public/avatar.vrm` (24,5 MB) lag im Auslieferungsordner,
-wurde aber von keiner Zeile des Frontends referenziert — der Renderer `Avatar3D.tsx` war schon
-vorher verschwunden. Beides ist beim v3-Umbau (Etappe P0) entfernt worden; damit fällt auch die
-`.gitignore`-Sonderregel und der Direkt-Deploy-Schritt weg. **Nichts wiederherzustellen.**
-
-### E · Voice-Sidecar (STT + TTS + Klonstimme)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| Voice-venv (Python 3.12) | `~/.voice/venv` | ⬇️ install.sh | nein (rebuild) |
-| STT (faster-whisper Modell) | `~/.voice/` (Cache) | ⬇️ install.sh / 1. Start | nein |
-| Piper-Binary + dt. Stimmen (thorsten/kerstin) | `~/.voice/piper`, `~/.voice/voices` | ⬇️ install.sh | nein |
-| Chatterbox (Premium-TTS, CPU-torch) | venv | ⬇️ install.sh (best-effort) | nein |
-| **Klonstimme / Voice-Referenz-Audio** (Nutzer) | `~/.voice/refs/ref.wav` (`VOICE_REFS_DIR`, `/api/voice/reference`) | 📦 | **nein → Anhang B** |
-| ElevenLabs-Key | `~/.hermes/.env` | 🔑 | ja |
-| Stimm-/Lautstärke-Wahl | Browser-`localStorage` (pro Gerät) | 🆕 client | n/a |
-| Dienst `voice-service` (`:8650`) | systemd-User | ⬇️ deploy.sh | nein |
-
-### F · Mem0 (Langzeitgedächtnis)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| Mem0-venv (Python 3.12, uv) | `~/.mem0/venv` | ⬇️ deploy.sh | nein (rebuild) |
-| **Gedächtnis-Daten (Chroma + history.db)** | `/srv/models/mem0/` | 📦 | **ja** |
-| Hermes-Memory-Plugin | `~/.hermes/plugins/mc2-memory/` | 📦/🌐 | ja |
-| Dienst `mem0-service` (`:8765`) | systemd-User | ⬇️ deploy.sh | nein |
-
-### G · Hermes-Agent (das Herz)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| Hermes-Code | `~/.hermes/hermes-agent` | 🌐 Git (NousResearch) | nein (re-clone) |
-| Bundled Node v22 | `~/.hermes/node/bin` | ⬇️ (kommt mit Hermes) | nein |
-| Hermes-venv | `~/.hermes/hermes-agent/venv` | ⬇️ rebuild | nein |
-| **`config.yaml` 1:1** (Toolsets, MCP, Engine, Browser, Personalities, alles) | `~/.hermes/config.yaml` | 📦 | **ja** |
-| **`.env` (Secrets: TELEGRAM_BOT_TOKEN, API_SERVER_KEY, ElevenLabs …)** | `~/.hermes/.env` | 📦/🔑 | **ja** |
-| Plugins | `~/.hermes/plugins/` | 📦 | ja |
-| **Skills (eigene)** | `~/.hermes/skills/` (45M; `.hub`-Cache re-downloadbar) | 📦 | **nein → Anhang B (ohne .hub)** |
-| Sessions/History (optional) | `~/.hermes/sessions/` (856K) | 📦 | **nein → Anhang B** |
-| Checkpoints (optional) | `~/.hermes/checkpoints/` (existiert nicht) | ⏭️ skip | nein |
-| **Token-/Ersparnis-Statistik** | `~/.hermes/token_stats.json` | 📦 | **nein → Anhang B** |
-| Dienst `hermes-gateway` (`:8642`) | systemd-User | ⬇️ | nein |
-| Desktop-Gateway `hermes-builtin-ui` (`:9119`) | systemd-User | ⬇️ deploy.sh | nein |
-| Desktop-Gateway-Token-Drop-in | `~/.config/systemd/user/hermes-builtin-ui.service.d/session-token.conf` | 🔑 neu erzeugen (Wert auch in `~/.hermes/desktop-gateway-token`, chmod 600) | **nein** |
-| Desktop-Gateway-Token-Kopie | `~/.hermes/desktop-gateway-token` (chmod 600) | 🔑 | **nein** |
-
-### H · MCP-Server (4)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| `mission-control-memory`, `-stack` (MC2-venv) | `~/mission-control-v2/mcp/*.py` | 🌐 Git | über config.yaml |
-| `hermes-pc-control`, `hermes-web-fetch` (Hermes-venv) | dito | 🌐 Git | über config.yaml |
-| MCP-Verdrahtung | `~/.hermes/config.yaml → mcp_servers` | 📦 | ja |
-
-### I · Browser-Stack
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| agent-browser (npm global) | `~/.local/...`, symlink `~/.hermes/node/bin` | ⬇️ npm i -g | nein |
-| Chrome (engine) + System-Libs | `~/.agent-browser/browsers/` + apt-Libs | ⬇️ install --with-deps | nein |
-| lightpanda (optional, leicht) | `~/.local/bin/lightpanda` | ⬇️ Download | nein |
-| Browser-Verdrahtung (engine=chrome, toolset) | `~/.hermes/config.yaml` | 📦 | ja |
-
-### J · Modelle (GGUF — der große Brocken)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| GGUF-Modelle (Brain, fast, heavy, coder, vision, embedding …) | `/srv/models/` | ⬇️ Re-Download aus llama-swap-Manifest | **nein (zu groß, bewusst)** |
-
-### K · Extern (anderer Rechner)
-| Komponente | Ort | Quelle | Im Backup? |
-|---|---|---|---|
-| PC-Executor (Windows) | `client/hermes-pc/` → Scheduled Task | 🌐 Git + Task | n/a (anderer Host) |
-| Hermes Desktop (Windows-App) | `%LOCALAPPDATA%\hermes` + `connection.json` in `%APPDATA%\Hermes\` | ⬇️ Hermes-Setup.exe + Remote-URL/Token neu eintragen | n/a (anderer Host) |
-
----
-
-## 4. Ziel-Architektur
-
-### 4.1 `deploy/bootstrap.sh` — orchestrierter From-Zero-Lauf
-- **Idempotent & resumierbar** (Schritt-Marker in `~/.mc2-bootstrap.state`).
-- **Getrennt nach sudo-Bedarf**: `bootstrap-root.sh` (L0+L1, bewusst mit sudo) + `bootstrap.sh`
- (L2+, sudo-frei = Kern ist `deploy.sh`). Passt zum Nordstern „Runtime ohne sudo".
-- **Mündet in den Wizard**: startet MC2 im First-Run-Modus, gibt Wizard-URL aus.
-
-Phasen: `0 Vorflug → 1[sudo] System+Dirs → 2[sudo] Engine+llama-swap → 3 Code(MC2+Hermes+Node)
-→ 4 venvs(backend/mem0/voice/hermes) → 5 Browser → 6 deploy.sh(Units/enable/restart)
-→ 7 Restore(optional) → 8 Wizard hoch + postcheck`.
-
-### 4.2 First-Run-Wizard (browserbasiert, von MC2 serviert)
-MC2 erkennt unkonfigurierten Zustand → Frontend-Route `/setup` statt Dashboard. Schritte:
-
-1. **Systemcheck** — Live-Ampel je Komponente aus §3 (`GET /api/setup/status` + `…/system/services`).
-2. **Restore-Quelle wählen** — Backup-Tarball erkennen → globaler Modus „Alles 1:1" / „selektiv" / „frisch".
-3. **Komponenten-Auswahl (Kernstück)** — pro Katalog-Eintrag aus §3 eine Kachel mit
- 📦/🆕/⏭️ (siehe §1). Zeigt Größe + ob Backup-Daten vorhanden.
-4. **Netzwerk & Identität** — Box-IP (→ `HERMES_TERMINAL_URL`, `PC_EXECUTOR_URL`), Hostname.
-5. **Secrets** 🔑 — `TELEGRAM_BOT_TOKEN`, erlaubte User-ID, `API_SERVER_KEY` (oder generieren),
- ElevenLabs-Key → `~/.hermes/.env` (chmod 600). Bei 📦 vorbefüllt aus Backup.
-6. **Hermes-Profil** — Brain-Alias + Toolset-Profil (Default = entfesselt: vision/tts/memory/browser
- an, image_gen/video aus — siehe [[project-hermes-setup]]). Bei 📦 = exakte alte `config.yaml`.
-7. **Voice** — Stimme/Klonstimme
- (📦 Referenz-Audio zurück, oder neu aufnehmen/hochladen).
-8. **Modelle** — aus llama-swap-Manifest automatisch nachladen (`POST /api/models/install`,
- Fortschritt `GET /api/jobs`) ODER geführte Discover-Neuauswahl. Reihenfolge: Brain → heavy → Rest.
-9. **Externe Checkliste** — PC-Executor (Windows-Task), Hermes Desktop (App + Token) als Haken.
-10. **Verifikation & Abschluss** — `stack-postcheck.sh` + `hermes-postcheck.sh` → grün/rot-Liste → Dashboard.
-
-**Technik:** neuer Router `backend/routers/setup.py`
-(`GET /api/setup/status`, `POST /api/setup/{secrets,network,hermes,components,finish}`).
-First-Run-Gate: MC2 prüft beim Boot Marker `~/.mc2-setup-done` bzw. Pflicht-Secrets → leitet auf `/setup`.
-
----
-
-## 5. Backup-Scope für echtes 1:1 ERWEITERN (umzusetzen — Snippet in Anhang B)
-
-Der **aktuelle** `backup.sh` (live auf der Box, unverändert) reicht für „1:1" nicht. Für die Bau-Session
-liegt das **fertige Erweiterungs-Snippet in Anhang B** — es ergänzt den Tarball um:
-
-- **Voice-Klonstimme** → `~/.voice/refs/` (`ref.wav`)
-- **Token-/Ersparnis-Statistik** → `~/.hermes/token_stats.json`
-- **Hermes-Skills** → `~/.hermes/skills/` (re-downloadbarer `.hub`-Cache per `tar --exclude` ausgelassen)
-- **Hermes-Sessions/History** → `~/.hermes/sessions/`
-
-Restore soll skills/sessions **mergen** (frisch geladenen `.hub` nicht überschreiben) und `voice-service`
-mit neu starten.
-
-**Offen bleibt:** nichts — der letzte offene Punkt (eigene Avatare) ist mit dem Avatar-Ausbau erledigt (§3·D).
-
-**Bewusst NICHT im Backup (re-downloadbar/rebuildbar):** Piper-Stimmen (install.sh), `.hub`-Skill-Cache,
-`/srv/models/mc2-discover.json` (Cache), `/srv/models/mc2-memory.db` (Legacy-Migration), alle venvs, GGUF-Modelle.
-
-→ Aufgabe der Bau-Session: `backup.sh` + `restore.sh` um diese Pfade erweitern (mit klarer
-„opt-in für große/optionale Teile"-Logik), und den MANIFEST-Inhalt entsprechend.
-
----
-
-## 6. Secrets-Strategie
-- Single Source: `~/.hermes/.env` (chmod 600), im Tarball (selbst 600).
-- Rebuild ohne Backup → Wizard-Schritt 5 erzeugt sie. `API_SERVER_KEY` generierbar; Telegram/ElevenLabs liefert Nutzer.
-- Nie ins Git, nie in Logs, nie in die MC2-DB. **Off-Box-Spiegelung des Tarballs noch offen** ([[mc2-backup-restore]]).
-
-## 7. Modell-Strategie
-- **A (empfohlen):** `/etc/llama-swap/config.yaml` (im Backup) listet alle Modelle → Wizard leitet Repos/Quants ab und lädt automatisch (`/api/models/install`). „Ein Klick, lädt über Nacht."
-- **B:** geführte Discover-Neuauswahl je Rolle. Reihenfolge Brain → heavy → Rest, danach `warmup.sh`.
-
----
-
-## 8. Implementierungs-Reihenfolge (neue Session)
-1. ✅ **Box-Verifikation erledigt (2026-06-28, nur gelesen — nichts verändert):** llama-swap.service-Inhalt
- in **Anhang A**; skills/sessions/refs/token_stats existieren (Pfade in §3 verifiziert); Backup-Erweiterung
- als fertiges Snippet in **Anhang B**. **Keine offenen Box-Fragen mehr** außer §10·3–6. → mit Schritt 2 starten.
-2. `backup.sh`/`restore.sh` um die 1:1-Lücken erweitern (§5).
-3. `deploy/bootstrap.sh` + `bootstrap-root.sh` (Phasen, State-Marker); llama-swap-Install skripten.
-4. `backend/routers/setup.py` + First-Run-Gate.
-5. Frontend `/setup`-Wizard (Schritte 1–10), Komponenten-Auswahl als Kernstück; bestehende Views
- (Cockpit/AgentView/Sprechen) wiederverwenden.
-6. Modell-Restore-aus-Manifest.
-7. **Abnahme in frischer VM** (§9).
-
-Vorschlag: 2–4 zuerst (Skelett lauffähig), Wizard danach. Branch + PR.
-
-## 9. Abnahmekriterien
-- Frisches Ubuntu 26.04 → `bootstrap-root.sh` + `bootstrap.sh` → laufender Stack, kein Spezialwissen.
-- Postchecks grün; Telegram, Voice (inkl. Klonstimme bei 📦), Browser funktionieren.
-- „Alles 1:1" stellt mem0, Hermes-config.yaml, Secrets, Klonstimme, Skills exakt wieder her.
-- Selektiver Modus: einzelne Komponenten ⏭️ überspringbar, Stack läuft trotzdem.
-- Idempotenz: zweiter Lauf = No-op.
-
-## 10. Offene Entscheidungen (vor dem Bau)
-1. ~~llama-swap systemd-Unit-Inhalt~~ → **geklärt: kompletter Unit in Anhang A** (in der Bau-Session anlegen).
-2. ~~Voice-Referenz-Audio-Ort~~ → **geklärt: `~/.voice/refs/`** (Backup-Snippet in Anhang B, in der Bau-Session umsetzen).
-3. ~~**Eigene Avatare**~~ — entfallen: Avatar am 28.08.2026 ausgebaut (§3·D).
-4. **Off-Box-Backup-Ziel** (NAS/2. Platte/Cloud) — [[mc2-backup-restore]].
-5. **Python 3.14** auf frischem Ubuntu beschaffen (deadsnakes?).
-6. **Bootstrap-sudo-Modell**: getrenntes `bootstrap-root.sh` (empfohlen) vs. interaktives sudo.
-
-## 11. Referenzen
-- `backend/config.py`, [[project-mc2-architecture]], [[project-stack-state]]
-- [[project-hermes-setup]], `docs/HERMES_SETUP.md` (entfesseltes Profil, Browser, PC-Executor)
-- [[voice-sprechen-feature]] (Voice + 3D-Avatar), [[mem0-memory-architecture]], [[mc2-backup-restore]]
-- `deploy/{deploy,backup,restore,provision-engine,stack-postcheck,warmup}.sh`, `voice_service/install.sh`
-
----
-
-## Anhang A — `llama-swap.service` (1:1 von der Box abgegriffen, 2026-06-28)
-
-Base-Unit nach `/etc/systemd/system/llama-swap.service` (root). User/GFX sind boxspezifisch
-(hitonabi, gfx1151 → HSA 11.5.1) — auf anderer Hardware anpassen. Die `.d/`-Drop-ins
-(`vulkan.conf`, `warmup.conf`) legt `provision-engine.sh` an.
-
-```ini
-[Unit]
-Description=llama-swap (lokaler LLM Router)
-After=network-online.target
-Wants=network-online.target
-
-[Service]
-Type=simple
-User=hitonabi
-Environment=HSA_OVERRIDE_GFX_VERSION=11.5.1
-Environment=PATH=/usr/local/bin:/usr/bin:/bin
-ExecStart=/usr/local/bin/llama-swap --config /etc/llama-swap/config.yaml --listen 0.0.0.0:8080 --watch-config
-Restart=on-failure
-RestartSec=3
-
-[Install]
-WantedBy=multi-user.target
-```
-```ini
-# /etc/systemd/system/llama-swap.service.d/vulkan.conf
-[Service]
-Environment=LD_LIBRARY_PATH=/opt/llamacpp-vulkan
-```
-```ini
-# /etc/systemd/system/llama-swap.service.d/warmup.conf
-[Service]
-ExecStartPost=-/usr/local/bin/llama-swap-warmup.sh
-```
-
-**Erstinstall-Reihenfolge:** `bash deploy/update-swap.sh` (Binary) → Unit kopieren →
-`sudo bash deploy/provision-engine.sh` (Engine+Drop-ins) → `sudo systemctl enable --now llama-swap`.
-
----
-
-## Anhang B — Backup-Scope-Erweiterung für echtes 1:1 (fertiges Snippet)
-
-In `deploy/backup.sh` ergänzen (Variablen oben: `VOICE="${VOICE_HOME:-$HOME/.voice}"`,
-Stage zusätzlich `"$STAGE/voice"`):
-
-```bash
-# 1:1-Erweiterung (scan-verifiziert 2026-06-28):
-[ -f "$HERMES/token_stats.json" ] && cp -a "$HERMES/token_stats.json" "$STAGE/hermes/" || true
-[ -d "$HERMES/skills" ] && cp -a "$HERMES/skills" "$STAGE/hermes/skills" || true
-[ -d "$HERMES/sessions" ] && cp -a "$HERMES/sessions" "$STAGE/hermes/sessions" || true
-[ -d "$VOICE/refs" ] && cp -a "$VOICE/refs" "$STAGE/voice/refs" || true
-```
-tar-Aufruf um den re-downloadbaren Skill-Cache erleichtern:
-```bash
-tar --exclude='./hermes/skills/.hub' -czf "$OUT" -C "$STAGE" .
-```
-In `deploy/restore.sh` spiegelbildlich (skills/sessions **mergen**, nicht ersetzen) und
-`voice-service` mit neustarten:
-```bash
-VOICE="${VOICE_HOME:-$HOME/.voice}"
-SERVICES="mem0-service voice-service mission-control-2 hermes-gateway"
-[ -f "$STAGE/hermes/token_stats.json" ] && cp -a "$STAGE/hermes/token_stats.json" "$HERMES/"
-[ -d "$STAGE/hermes/skills" ] && { mkdir -p "$HERMES/skills"; cp -a "$STAGE/hermes/skills/." "$HERMES/skills/"; }
-[ -d "$STAGE/hermes/sessions" ] && { mkdir -p "$HERMES/sessions"; cp -a "$STAGE/hermes/sessions/." "$HERMES/sessions/"; }
-[ -d "$STAGE/voice/refs" ] && { mkdir -p "$VOICE/refs"; cp -a "$STAGE/voice/refs/." "$VOICE/refs/"; }
-```
diff --git a/docs/RADAR.md b/docs/RADAR.md
new file mode 100644
index 0000000..ce81af6
--- /dev/null
+++ b/docs/RADAR.md
@@ -0,0 +1,104 @@
+# Radar — Modell-Radar, Stack-Radar, Prüfstand
+
+_Stand 24.09.2026, Code in `main` = `75611be`. Für Techniker und Agenten._
+
+Es gibt zwei Radare mit getrennten Aufgaben:
+
+- **Modell-Radar** (Box-Wart, `mc2-radar.timer` um 00:30): sucht und testet neue Modelle für Hirn und Coder selbst.
+ Getauscht wird nur per Knopf „Übernehmen".
+- **Stack-Radar** (Hermes-Cron „KI und Stack Radar", Sa 08:00): Wochenbericht über den Zustand der Box und über
+ Neuigkeiten draußen (Releases, Entwurfsmodelle). Er testet und ändert nichts.
+
+## Modell-Radar
+
+Code: `backend/services/radar.py`, Nachtlauf `backend/radar_lauf.py`, Messungen `deploy/bench/pruefstand.py`,
+Merkliste `deploy/radar-watchlist.json`. Zustand: `/srv/models/mc2-radar.json`, Baseline
+`/srv/models/mc2-radar-baseline.json`, Downloads `/srv/models/radar//`. Protokoll:
+`journalctl --user -u mc2-radar`.
+
+### Leitplanken (User-Entscheid 23.09.)
+
+- Zwei Rollen: Hirn (Alias `hermes`) und Coder (Alias `coder`), jede mit Bild-Zwilling (`vision` bzw. `coder-bild`).
+- Tests nur nachts 00:30–02:30, höchstens ein neuer Kandidat pro Woche. Um 03:00 braucht der NerdQuiz-Nachtlauf das
+ Hirn.
+- Nur was neben das Warm-Set passt: 27 GB Warm-Set plus Kandidat mit KV-Cache ≤ 115 GB, gerechnet mit dem Kontext
+ aus dem Betrieb (131 072; passt das nicht, stufenweise kleiner, nie unter 32 768). Ab 90 % des Budgets heißt es
+ „passt knapp".
+- Pflicht: GGUF plus Bild-Projektor (mmproj), mindestens 20B Parameter; als Hirn höchstens 12B aktive Parameter
+ (dichte Modelle nie als Hirn). Die installierte Engine muss die Architektur kennen, und die Platte darf nach dem
+ Download nicht über 80 % liegen.
+- Durchgefallene werden gelöscht, Bestandene bleiben liegen. Getauscht wird erst mit „Übernehmen".
+
+### Ablauf einer Nacht
+
+1. Um 00:30 startet `mc2-radar.service` (`Persistent=true`, holt einen verpassten Lauf nach).
+2. **Suche**, höchstens einmal am Tag: zuerst die Merkliste in ihrer Reihenfolge, dann die Hugging-Face-Entdeckung
+ (höchstens 3 Funde je Rolle). Jeder Fund wird bewertet: Dateien, Größe, Engine-Unterstützung, Speicher. Der Knopf
+ „Jetzt suchen" macht dasselbe sofort (läuft synchron und kann Minuten dauern).
+3. **Offene Urteile nachholen:** Kandidaten mit Status „getestet", bei denen die Vergleichsmessung fehlte.
+4. **Test**, wenn ein Kandidat dran ist:
+ 1. Download nach `/srv/models/radar//`.
+ 2. Baseline des heutigen Modells der Rolle über llama-swap (gecacht, höchstens monatlich neu gemessen).
+ 3. In llama-swap bleibt nur das Warm-Set; ein Aufpasser entlädt Modelle, die nachts nachgeladen werden (etwa den
+ Coder).
+ 4. Draft-Varianten kurz messen: ohne Draft, eingebauter MTP-Kopf, Draft des heutigen Modells (nur bei gleicher
+ Architektur und genug Speicher). Ein Draft aus der Merkliste wird allein genommen.
+ 5. Mit der schnellsten Variante den Prüfstand fahren; der Kandidat läuft als eigener `llama-server` auf `:5899`.
+ 6. Bild-Probe über einen Zwilling ohne Draft, dann das Urteil.
+5. **Frist:** Die Messungen prüfen das Fensterende 02:30 selbst. 5 Minuten danach zieht die Notbremse
+ (Kandidaten-Server und Download stoppen, der Prozess endet hart). `RuntimeMaxSec=2h10min` beendet die Unit
+ spätestens um 02:40 samt `llama-server`.
+6. **Bestanden:** Meldung „[Modell-Radar] … hat den Nachttest bestanden"; nachts landet sie in der Morgenmeldung.
+
+Status eines Kandidaten: neu → wartet → getestet → bestanden oder durchgefallen → uebernommen oder verworfen.
+Höchstens 3 Versuche je Kandidat; ein Abbruch, für den der Kandidat nichts kann, zählt nicht als Versuch.
+
+### Prüfstand (`deploy/bench/pruefstand.py`)
+
+- Der Kandidat läuft als eigener `llama-server` auf `127.0.0.1:5899`; der Live-Stack bleibt unberührt.
+- **Hirn:** Tempo kurz und bei 13k Kontext (Prefill, Decode, Draft-Akzeptanz), Werkzeug-Aufrufe zwischen ~100
+ Werkzeugen mit ~12k Kontext, Deutsch- und JSON-Probe.
+- **Coder:** Tempo, Werkzeug-Aufrufe eines Coding-Agenten, 10 kleine Programmieraufgaben mit Unit-Tests in einem
+ Temp-Ordner mit Zeitlimit.
+- **Bild:** ein im Code gezeichnetes Bild (Formen, Farben, Text), einmal direkt, einmal mitten in einer
+ Werkzeug-Aufgabe.
+- **Urteil:** bestanden = keine Verschlechterung bei den Pflichtwerten UND mindestens ein echter Vorteil.
+- **Handbetrieb:** `deploy/bench/pruefstand-hirn.py` misst Kandidaten mit festen Pfaden gegen die Live-Modelle,
+ optional mit einem Werkzeug-Test durch den echten Hermes (Provider `pruefstand` in der Hermes-Config).
+
+### Übernehmen und Verwerfen (Seite „Modelle")
+
+**Übernehmen** geht nur bei Status „bestanden" und nicht während eines Nachtlaufs:
+
+1. Der Ordner wandert von `/srv/models/radar/` nach `/srv/models/`.
+2. Eintrag in llama-swap mit dem getesteten Draft und den Betriebs-Flags der Rolle, ohne Projektor. Dazu der
+ Bild-Zwilling `-Bild` in der Gruppe `bild` (ttl 900). Der alte Zwilling fliegt aus der Config, seine
+ Dateien bleiben.
+3. **Hirn:** Alias `hermes`, Gruppe `brains`, ttl 0, `model.default` in der Hermes-Config; Hermes startet dafür kurz
+ neu. Der Alias `fast` wandert mit, `MC_WARMSET` im Steward-Drop-in wird umgestellt und der Steward neu gestartet.
+ **Coder:** Rolle `coder`; `heavy` wandert mit, die ttl des alten Coders wird übernommen.
+4. Das alte Modell bleibt auf der Platte (Aufräumen-Panel).
+
+**Verwerfen:** Die heruntergeladenen Dateien werden gelöscht, und das Radar testet dieses Modell nie wieder.
+
+Ein Tausch schreibt die llama-swap-Config heute noch mehrmals (offener Punkt in
+[wissen/OFFENE-FAEDEN.md](wissen/OFFENE-FAEDEN.md)).
+
+### Merkliste
+
+`deploy/radar-watchlist.json`, Felder je Eintrag: `name`, `rolle` (`hirn` oder `coder`), `repo`, `quant` (Standard
+Q4_K_M), `eng` (passt nur knapp), `notiz`, `ueberspringen` (Grund, dann kein Test), optional `draft` und `flags`.
+Merkliste und Hugging-Face-Entdeckung zusammen ergeben die Warteschlange; Merkliste zuerst.
+
+## Stack-Radar (Hermes-Cron „KI und Stack Radar", Sa 08:00)
+
+- `deploy/jobs/stack-radar.sh` sammelt Fakten und meldet selbst über `notify.sh` mit Betreff „[Stack-Radar]".
+- `deploy/jobs/stack-ist.sh` prüft Ergebnisse statt Lebenszeichen: Lösen die Rollen-Aliase auf? Lief der letzte
+ Timer gut? Ist die Sicherung jünger als zwei Tage?
+- `deploy/jobs/stack-upstream.py` schaut nach draußen: Releases, gemergte PRs, neue Entwurfsmodelle und Modelle der
+ Familien, die die Box fährt; verglichen mit dem letzten Lauf (`~/.hermes/state/stack-upstream.json`). Liste:
+ `deploy/trend-radar-watchlist.json`.
+- Das Hirn (`fast`) schreibt aus den Fakten einen kurzen Bericht; es darf nichts dazuerfinden. Antwortet es nicht,
+ gehen die roten Rohbefunde trotzdem raus.
+- Grundsatz: „Fakten sammelt ein Skript, Prosa schreibt das Modell." Mehr in
+ [deploy/jobs/README.md](../deploy/jobs/README.md).
diff --git a/docs/RUNBOOK.md b/docs/RUNBOOK.md
deleted file mode 100644
index 25c5a99..0000000
--- a/docs/RUNBOOK.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# RUNBOOK — Die Box in 1 Seite (für Menschen, ohne KI-Hilfe)
-
-**Grundsatz:** Die Box wartet sich selbst. Du bekommst Telegram-Nachrichten und antwortest
-höchstens „mach". Dieses Blatt ist NUR für den Fall, dass etwas klemmt.
-
-## Was die Telegram-Meldungen bedeuten
-
-| Meldung | Bedeutung | Dein Handgriff |
-|---|---|---|
-| „… aktualisiert … grün" | Update eingespielt, alles geprüft | keiner |
-| „… zurückgerollt … GEPINNT" | Update war schlecht, alte Version läuft wieder | keiner (läuft stabil weiter) |
-| „KRITISCH: …" | Update UND Rollback kaputt | siehe „Box tot?" unten |
-| „🛰️ Evolution-Radar …" | monatlicher Chancen-Report | lesen; bei Interesse „mach" antworten |
-| „[Werkstatt] … Vorschlag liegt bereit" | Box hat einen Fix vorbereitet | Branch auf Gitea ansehen → Ampel grün? → selbst auf main mergen → `deploy.sh` |
-
-## Box tot / Weboberfläche weg?
-
-1. **Strom/Netz prüfen**, dann Box **einmal neu starten** (Power-Knopf). Alles startet von selbst
- (systemd, reboot-fest). 2–3 Minuten warten, dann `http://192.168.178.151:9001` aufrufen.
-2. Immer noch tot → per SSH (PC, PowerShell): `ssh hitonabi@192.168.178.151`
- dann: `bash ~/mission-control-v2/deploy/restore.sh` (nimmt automatisch das letzte Backup,
- liegt in `/srv/models/mc2-backups/`, 14 Tage Vorrat, täglich 03:30 Uhr).
-3. Totalschaden (neue Platte/Hardware) → `docs/DISASTER_RECOVERY.md` (Bootstrap von Null).
-
-## Lucy (am PC)
-
-- Start: Desktop-Verknüpfung **„Lucy"** (startet den eingefrorenen Produktiv-Build).
-- Hängt? `F:\Coding Stuff\lucy\lucy-desktop\Lucy-Neustart.bat` doppelklicken.
-- Lucy ist EINGEFROREN — Änderungen macht nur die Werkstatt (Telegram-Vorschlag abwarten).
-
-## Automatik-Fahrplan (läuft ohne dich)
-
-- **Nachts:** 03:15 Traum (Wissens-Vault) · 03:30 Backup · 03:50 PBS-Backup ·
- 04:30 Chef-Gutachter (Morgenlage) · 07:15 Selbsttest · 08:00 Daily-Briefing
-- **So 04:30** Auto-Update (Router→Engine→Hermes) mit Rollback+Pin-Fangnetz (dein Ok 10.07.;
- manuell geht's jederzeit über den Wartungs-Drawer)
-- **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; 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?
-
-Ein Update hat den Selbsttest gerissen; die Box bleibt bewusst auf der alten Version. Das ist
-ein STABILER Dauerzustand, kein Fehler. Pin ansehen / lösen (per SSH):
-
- cat /srv/models/mc2-pins.json
- jq 'del(.hermes)' /srv/models/mc2-pins.json > /tmp/p && mv /tmp/p /srv/models/mc2-pins.json
- # (statt .hermes: .engine oder .swap) — nächster So-Lauf versucht das Update erneut
-
-## Wann Gemini rufen (der Notfall- und Review-Partner)
-
-Seit dem Claude-Abo-Ende ist **Gemini (in der Antigravity-App am PC)** dein externer Helfer.
-Du brauchst ihn NUR in zwei Fällen — den Alltag macht die Box selbst:
-
-1. **Notfall:** Die Box ist kaputt UND die Schritte unter „Box tot?" (oben) haben nicht
- geholfen — oder Lucy/Telegram melden wiederholt „KRITISCH".
-2. **Außen-Review:** Du willst einen Fremd-Blick auf die Arbeit der Box (z. B. alle paar
- Monate oder vor einem großen Umbau).
-
-**So rufst du ihn:** Antigravity öffnen → Projektordner `F:\Coding Stuff\mission-control-2`
-→ als erste Nachricht schreiben: **„Lies docs/GEMINI_BRIEFING.md und dann [dein Problem]."**
-Für ein Review stattdessen: „Lies docs/GEMINI_BRIEFING.md und führe das Review aus
-docs/ANTIGRAVITY_REVIEW.md durch."
-
-**Grenzen (stehen auch in seinem Briefing):** Gemini schlägt vor, DU klickst/entscheidest.
-Er darf Security-Sachen nur melden, nie ändern. Wenn er etwas über die Box behauptet,
-darf er es nur nach echtem Test behaupten — im Zweifel nachfragen „hast du das gemessen?".
-
-## Einmalige sudo-Session — ✅ erledigt (02.07.2026)
-
-Sudo-Freischaltung für Engine/Router-Updates, unattended-upgrades und v1-Aufräumen sind
-durch (`/etc/sudoers.d/mc2-autonomie` liegt). Nichts mehr zu tun.
-
-## Nützliche Handgriffe (SSH)
-
- curl -s http://127.0.0.1:9001/api/health # Gesamtzustand (brain ready?)
- bash ~/mission-control-v2/deploy/autoupdate.sh # Update-Lauf sofort statt Sonntag
- bash ~/mission-control-v2/deploy/notify.sh "test" # Meldeweg testen (muss auf Telegram ankommen)
- tail ~/mc2-notify.log # was wurde zuletzt gemeldet
diff --git a/docs/UPDATES.md b/docs/UPDATES.md
new file mode 100644
index 0000000..401d669
--- /dev/null
+++ b/docs/UPDATES.md
@@ -0,0 +1,109 @@
+# Updates — die Sonntags-Kette, Festhalten, Freigeben
+
+_Stand 24.09.2026, Code in `main` = `75611be`. Für Techniker und Agenten; für den User: Seite „Updates" in
+[BEDIENUNG.md](BEDIENUNG.md)._
+
+Die Box aktualisiert ihre Fremd-Software jeden Sonntag selbst: erst llama-swap, dann den Motor (llama.cpp), dann
+Hermes. Jeder Baustein wird danach geprüft; ist die Prüfung rot, rollt die Box zurück und hält den Baustein fest, bis
+ihn jemand freigibt. Sicherheitsupdates des Betriebssystems laufen getrennt über unattended-upgrades. Modelle wechseln
+nie automatisch (Modell-Radar, Knopf „Übernehmen").
+
+## Ablauf
+
+```mermaid
+flowchart TD
+ T["mc2-autoupdate.timer
So 04:30 (+≤10 min)"] --> S["jobs/sonntags-update.sh"]
+ S --> A["autoupdate.sh"]
+ A --> R["1 · llama-swap
update-swap.sh"]
+ R --> E["2 · Motor
update-engine.sh"]
+ E --> H["3 · Hermes
Job über MC2"]
+ H --> W["Wochenbericht
[Box-Update]"]
+ W --> N{"Neustart nötig?
nur So 04–07 Uhr"}
+```
+
+1. `mc2-autoupdate.timer` (`Persistent=true`, bis 10 min Zufallsverzug) startet `mc2-autoupdate.service`
+ (einmaliger Lauf nach `mc2-backup.service`, Zeitlimit 3 h). Die Unit ruft `deploy/jobs/sonntags-update.sh`, das
+ `deploy/autoupdate.sh` startet und nur dann selbst meldet, wenn `autoupdate.sh` mit Fehler endet (letzte 15
+ Zeilen). Der Hermes-Cron „Updates am Sonntag" ist seit 24.09. pausiert.
+2. `autoupdate.sh` bricht mit Meldung ab, wenn MC2 (`/api/health`) nicht antwortet.
+3. **llama-swap und Motor:** Ein festgehaltener Baustein wird übersprungen. Sonst liefert
+ `GET /api/maintenance/update-details?kind=swap` bzw. `kind=engine` die installierte und die neueste Version. Gibt es
+ Neues, läuft `sudo -n bash deploy/update-swap.sh` bzw. `update-engine.sh` (fehlt die sudo-Freigabe, wartet der
+ Baustein mit Hinweis). Die Skripte sichern die alte Version (`/usr/local/bin/llama-swap.bak`,
+ `/opt/llamacpp-vulkan.bak`), stoppen llama-swap, tauschen, starten und prüfen mit `stack-postcheck.sh`.
+ Ergebnis 0 = eingespielt, 1 = zurückgerollt (Baustein wird festgehalten, Meldung), 2 = Update und Rückweg
+ gescheitert (Meldung „KRITISCH", dringend).
+4. **Hermes:** Ein festgehaltener Hermes wird übersprungen. Sonst sagt `update-details?kind=hermes`, wie viele
+ Commits Hermes zurückliegt. `autoupdate.sh` startet `POST /api/maintenance/hermes-update` und wartet bis zu
+ 20 Minuten. Der Job: Sicherung → Dashboard stoppen → `hermes update --yes --no-gateway-restart` → `hermes doctor` →
+ Dashboard-Oberfläche mit Basis `/hermes-ui/` bauen → `hermes-gateway` und `hermes-builtin-ui` neu starten →
+ `hermes-postcheck.sh`.
+ - Grün: Meldung.
+ - Rot oder Zeitlimit: erst `self-repair.sh` (kommentiert eindeutige, nicht sicherheitsrelevante Config-Schlüssel
+ aus, an denen die neue Version scheitert; der Gehirn-Check muss danach grün sein).
+ - Hilft das nicht: Rückweg — `git reset --hard` auf den alten Commit in `~/.hermes/hermes-agent`, `config.yaml` und
+ `.env` aus der letzten Sicherung, Neustart, Gehirn-Check. Grün: Hermes wird festgehalten, Meldung. Sonst
+ „KRITISCH" (dringend).
+5. **Wochenbericht** „Commander, die Wochenpflege der Box ist durch" mit einer Zeile je Baustein.
+6. **Neustart**, wenn Ubuntu ihn verlangt (`/var/run/reboot-required`), nur sonntags 04:00–06:59; außerhalb gibt es
+ nur eine Ankündigung. Vorher prüft das Skript: Linger an, keine laufenden Jobs, `mission-control-2`,
+ `mc2-gateway` und `mc2-steward` im Autostart; sonst Meldung statt Neustart. `MC_AUTOUPDATE_REBOOT=0` schaltet den
+ Neustart ab, `MC_AUTOUPDATE_REBOOT_JETZT=1` erzwingt ihn außerhalb des Fensters.
+
+Nachts landen alle Meldungen außer „KRITISCH" in der Morgenmeldung um 07:00.
+
+## Prüfungen nach dem Update
+
+- **`stack-postcheck.sh`** (nach llama-swap, Motor und Betriebssystem): llama-swap aktiv; `/v1/models` antwortet
+ (bis 120 s); das Hirn liefert eine echte Antwort (1 Token); das Embedding-Modell liefert Vektoren; MC2 meldet den
+ Motor erreichbar; Gateway gesund; Steward aktiv.
+- **`hermes-postcheck.sh`** (nach Hermes): keine Config-Warnungen im Gateway-Log der letzten 3 Minuten; Werkzeug-Test
+ durch den echten Agenten (`echo postcheck-ok`, bis 3 Versuche); Sprach-Test über `/api/voice/chat` (bis 3
+ Versuche); Browser-Werkzeug `agent-browser` lauffähig (einen toten Link setzt das Skript selbst neu).
+
+## Festhalten und Freigeben
+
+- Rot mit grünem Rückweg ergibt einen Eintrag in `/srv/models/mc2-pins.json`:
+ `{"": {"pinned": true, "version": …, "grund": …, "datum": …}}` mit den Bausteinen `swap`, `engine`,
+ `hermes`. Künftige Sonntage überspringen ihn.
+- Der Wächter zeigt jeden festgehaltenen Baustein als gelben Hinweis „… bekommt keine Updates mehr" mit Knopf
+ „Freigeben"; die Updates-Seite zeigt ihn ebenso. Freigeben löscht den Eintrag
+ (`POST /api/updates/festgehalten/{baustein}/freigeben`); der nächste Sonntag versucht das Update erneut.
+- Warum sichtbar: Vom 06. bis 17.09. hielt die Box Motor und Hermes fest, ohne dass es jemand merkte, elf Tage ohne
+ Updates.
+
+## Von Hand
+
+- **Seite „Updates":** „Nach Neuem suchen" (`apt-get update`), je Baustein „Aktualisieren", „Alles jetzt
+ aktualisieren" (mit Rückfrage). Es läuft immer nur ein Wartungs-Job; ein zweiter Klick startet kein zweites Update.
+- **„Alles jetzt aktualisieren"** kettet in einem Job, was ansteht: Motor → llama-swap → Hermes → Betriebssystem
+ (`apt-get upgrade`, danach `stack-postcheck.sh`). Scheitert ein Teil, stoppt die Kette.
+- **Zeitlimits der Jobs:** Suche 15 min, Betriebssystem 90 min, Motor 60 min, llama-swap 30 min, Hermes 45 min, alles
+ zusammen 3 h. „Abbrechen" beendet die ganze Prozessgruppe.
+- **Per SSH:** `bash ~/mission-control-v2/deploy/autoupdate.sh` (neu gestartet wird trotzdem nur im Wartungsfenster).
+- Kann eine Update-Prüfung nicht prüfen (Netz, API, apt), zeigt die Oberfläche „Prüfung unklar" statt „aktuell".
+ Nach jedem Update prüft sie sofort neu.
+- Update-Jobs leben im MC2-Prozess; ein Neustart von MC2 bricht sie ab. Der Deploy wartet deshalb.
+
+## Update-Verlauf
+
+`backend/services/update_verlauf.py` baut den Verlauf der Updates-Seite aus `~/mc2-notify.log`. Es liest die Zeilen
+`OK telegram`, `OK telegram direkt` (Zweitweg über die Bot-API), `QUEUED für Morgen-Digest` und `FALLBACK (…)`.
+Meldungen mit weniger als 45 Minuten Abstand gehören zu einem Lauf; die Morgenmeldung zählt nicht als eigener Lauf.
+Der Wortlaut der Meldungen von `autoupdate.sh` und der Protokolleinträge muss deshalb bleiben: Eine Umformulierung
+bricht den Verlauf ohne Fehlermeldung.
+
+## Betriebssystem
+
+Sicherheitsupdates spielt `unattended-upgrades` ein. Wartet danach ein Kernel oder libc auf den Neustart, startet der
+Sonntagslauf die Box im Wartungsfenster neu. Weitere Pakete: Knopf „Aktualisieren" beim Baustein Betriebssystem.
+
+## Fallen
+
+- llama.cpp hat `--no-mmap` gestrichen (seit b10936); die Config nutzt `--load-mode none`. Vor einem Engine-Sprung
+ die Config-Zeilen mit dem neuen `llama-server` prüfen.
+- `hermes update` meldet Exit 1 trotz Erfolg, deshalb `--no-gateway-restart`.
+- Ein Timer mit `Persistent=true` holt verpasste Läufe beim Einschalten sofort nach (24.09.: Neustart um 14:51).
+- Der Updater läuft nicht mehr als Hermes-Cron (20.09.: Hermes startete sich beim eigenen Update neu).
+
+Einzelheiten: [wissen/FALLEN.md](wissen/FALLEN.md).
diff --git a/docs/WIEDERAUFBAU.md b/docs/WIEDERAUFBAU.md
new file mode 100644
index 0000000..8d68cd8
--- /dev/null
+++ b/docs/WIEDERAUFBAU.md
@@ -0,0 +1,108 @@
+# Wiederaufbau — die KI-Box von null
+
+_Stand 24.09.2026. Für den Totalschaden (neue Platte, neue Hardware). Für kleinere Störungen gilt
+[BETRIEB.md](BETRIEB.md), Abschnitt „Notfall"._
+
+Die Reihenfolge stammt aus dem Konzept vom 28.06.2026, aktualisiert auf den Stand vom 24.09.; auf einer frischen Box
+geprobt wurde sie nie. Das dort geplante Bootstrap-Skript mit Einrichtungs-Assistent wurde nie gebaut; der Volltext
+steht in der Git-Historie (`docs/DISASTER_RECOVERY.md`, letzter Stand 28.08.2026).
+
+## Was woher zurückkommt
+
+| Teil | Quelle |
+|---|---|
+| Code des Box-Warts | Gitea, `main` |
+| Hermes: `config.yaml`, `.env`, Plugins, `cron/`, `state/`, Gedächtnis (`memories/`), `SOUL.md`, Skills, Cron-Skripte | Sicherung (Tarball) |
+| llama-swap-Config, Box-Wart-Zustand (`/srv/models/mc2-*.json`) | Sicherung |
+| Units und Drop-ins, auch die nicht im Repo liegenden | Sicherung, Ordner `systemd/` (zum Nachschlagen), dazu `deploy/` im Repo |
+| Lucys Stimmreferenz | Sicherung, `lucy-stimme/ref.wav` |
+| Versionen, die zusammen liefen | Sicherung, `known-good/` |
+| Modelle | neu laden; die Pfade stehen in der llama-swap-Config |
+| Engine, llama-swap, Hermes, Python-Umgebungen | neu installieren |
+
+## Schritte
+
+1. **Sicherung besorgen.** Die Tarballs liegen auch auf dem Proxmox-Host unter `/var/lib/vz/mc2-backups`. Der
+ Spiegel-Schlüssel `~/.ssh/mc2_offsite` steckt nicht in der Sicherung: Den neuesten Tarball von Hand holen (z. B.
+ vom PC per `scp`) oder den Schlüssel neu einrichten (Security-Config, nur mit User-Ja).
+2. **Grundsystem:** Ubuntu 26.04, Benutzer `hitonabi`, Zeitzone `Europe/Berlin`,
+ `sudo loginctl enable-linger hitonabi` (ohne Linger starten die User-Dienste nach einem Neustart nicht). Pakete:
+ Python 3.14 mit venv (Bezugsquelle offen, prüfen), git, curl, jq, rsync, ffmpeg (Sprachnachricht der Daily News),
+ ttyd (Konsole). Die Vulkan-Treiber installiert Schritt 5.
+3. **Ordner:** `/srv/models` und `/etc/llama-swap` anlegen und `hitonabi` geben
+ (`sudo chown -R hitonabi:hitonabi /srv/models /etc/llama-swap`); MC2 schreibt die llama-swap-Config selbst.
+4. **Code und Python-Umgebung:**
+ `git clone ssh://gitea@192.168.178.153:2222/Hitonabi/mission-control-v2.git ~/mission-control-v2` (der
+ SSH-Schlüssel der Box muss in Gitea hinterlegt sein), dann `python3.14 -m venv backend/.venv` und
+ `backend/.venv/bin/pip install -r backend/requirements.txt -r backend/requirements-dev.txt`. Was nachweislich
+ zusammen lief: `known-good/pip-backend.txt` aus der Sicherung.
+5. **Engine und llama-swap** (root): `sudo bash deploy/update-swap.sh` (Binary nach `/usr/local/bin/llama-swap`),
+ Unit aus Anhang A nach `/etc/systemd/system/llama-swap.service`, `sudo bash deploy/provision-engine.sh`
+ (Vulkan-Treiber, llama.cpp-Build nach `/opt/llamacpp-vulkan`, Drop-ins `vulkan.conf` und `warmup.conf`,
+ `/usr/local/bin/llama-swap-warmup.sh`), dann `sudo systemctl enable --now llama-swap`. Das dritte Drop-in
+ `warmset.conf` liegt nur in der Sicherung (`systemd/llama-swap.service.d/`).
+6. **Hermes** neu installieren (Git-Install nach `~/.hermes/hermes-agent`; welcher Stand lief, steht in
+ `known-good/versions.txt`). Den Dienst `hermes-gateway` legt Hermes selbst an; `hermes-builtin-ui.service` samt
+ Drop-ins aus `systemd/user/` der Sicherung übernehmen.
+7. **Zustand zurückspielen:** Tarball nach `/srv/models/mc2-backups/` legen, dann
+ `bash deploy/restore.sh --yes `. Auf einer leeren Box kommen auch Gedächtnis, `SOUL.md`, Skills,
+ Cron-Skripte und `mc2-*.json` zurück, weil sie fehlen.
+8. **Lucys Stimme:** `~/.lucy-stimme/` (pocket-tts mit `pocket_server.py`) neu einrichten; das Programm stammt aus dem
+ Lucy-Repo, die Referenz `ref.wav` aus der Sicherung. Offen: Die Einrichtungsschritte sind nirgends beschrieben.
+9. **Deploy:** `bash deploy/deploy.sh` spielt alle Repo-Units, Drop-ins, Cron-Skripte, Skills und Plugins aus,
+ aktiviert Dienste und Timer und prüft nach. Das Plugin `mc2-web-lesen` ist nach dem Restore schon in der
+ Hermes-Config aktiv; sonst einmalig `hermes plugins enable mc2-web-lesen` und
+ `hermes config set web.extract_backend mc2-lesen`.
+10. **Modelle laden:** Die Pfade stehen in der zurückgespielten llama-swap-Config (`-m`, `--mmproj`,
+ `--spec-draft-model`); `known-good/models.txt` listet die Dateien mit Größe. Zuerst das Hirn, dann den Coder, dann
+ die Drafts. Die Bild-Zwillinge nutzen dieselben Gewichte, brauchen also nur ihren Projektor. Laden über die
+ Oberfläche („Modelle selbst suchen") oder mit
+ `backend/.venv/bin/hf download --local-dir /srv/models/`.
+11. **Prüfen:** `bash deploy/stack-postcheck.sh`, `bash deploy/hermes-postcheck.sh`, dann
+ `http://192.168.178.151:9001` öffnen: Alle Warnlampen sollen grün sein.
+12. **Spracherkennung** (schläft, nur bei Bedarf): `bash voice_service/install.sh` legt `~/.voice/venv` an; aktivieren
+ mit `systemctl --user enable --now voice-service`.
+
+## Anhang A — `llama-swap.service`
+
+Von der Box abgegriffen am 28.06.2026, seitdem nicht neu verglichen. Benutzer und `HSA_OVERRIDE_GFX_VERSION` sind
+boxspezifisch. Nach `/etc/systemd/system/llama-swap.service` (root):
+
+```ini
+[Unit]
+Description=llama-swap (lokaler LLM Router)
+After=network-online.target
+Wants=network-online.target
+
+[Service]
+Type=simple
+User=hitonabi
+Environment=HSA_OVERRIDE_GFX_VERSION=11.5.1
+Environment=PATH=/usr/local/bin:/usr/bin:/bin
+ExecStart=/usr/local/bin/llama-swap --config /etc/llama-swap/config.yaml --listen 0.0.0.0:8080 --watch-config
+Restart=on-failure
+RestartSec=3
+
+[Install]
+WantedBy=multi-user.target
+```
+
+Drop-ins, die `deploy/provision-engine.sh` anlegt:
+
+```ini
+# /etc/systemd/system/llama-swap.service.d/vulkan.conf
+[Service]
+Environment=LD_LIBRARY_PATH=/opt/llamacpp-vulkan
+```
+
+```ini
+# /etc/systemd/system/llama-swap.service.d/warmup.conf
+[Service]
+ExecStartPost=-/usr/local/bin/llama-swap-warmup.sh
+```
+
+Das Drop-in `warmset.conf` (laut Prüfbericht vom 24.09. `MC_WARMUP_MODELS=fast`) steht in keinem Skript; es kommt
+aus der Sicherung.
+
+**Erstinstallation in dieser Reihenfolge:** `sudo bash deploy/update-swap.sh` (Binary) → Unit anlegen →
+`sudo bash deploy/provision-engine.sh` (Engine und Drop-ins) → `sudo systemctl enable --now llama-swap`.