Die VM schreibt laufend (Docker, Rippy; Thin-Platte zu 99,9 % belegt) – ein stehender Snapshot wüchse im Thin-Pool bis zum nächsten Update mit. Bei den Containern bleibt der letzte Snapshot wie bisher als Rückweg stehen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
458 lines
35 KiB
Markdown
458 lines
35 KiB
Markdown
# 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 # welche Stände wann live gingen
|
||
cat /srv/models/mc2-stand.json # welcher Stand gerade live ist (seit 24.09.)
|
||
cat /srv/models/mc2-einstellungen.json # Update-Zeitfenster und Radar-Schalter der Oberfläche
|
||
sudo journalctl -u llama-swap -n 100 # Motor (System-Dienst)
|
||
```
|
||
|
||
## Meldungen
|
||
|
||
- **Ein Weg:** `bash ~/mission-control-v2/deploy/notify.sh [-d] [-s "[Betreff]"] "Text"` legt die Meldung in Lucys
|
||
Briefkasten und schickt sie an Telegram. Protokoll: `~/mc2-notify.log`, je Meldung eine Zeile mit `OK telegram`,
|
||
`OK telegram direkt`, `QUEUED für Morgen-Digest` oder `FALLBACK (…)`. Den Wortlaut nicht ändern:
|
||
`backend/services/update_verlauf.py` liest ihn.
|
||
- **Zwei Wege zu Telegram (seit 24.09.):** zuerst `hermes send`. Scheitert das oder fehlt Hermes, geht die Meldung
|
||
direkt an die Telegram-Bot-API; die Zugangsdaten (`TELEGRAM_BOT_TOKEN`, `TELEGRAM_HOME_CHANNEL`, optional
|
||
`TELEGRAM_HOME_CHANNEL_THREAD_ID`) liest `notify.sh` aus der Datei in `MC_TELEGRAM_ENV` (Standard `~/.hermes/.env`).
|
||
Das Token steht dabei nicht in der Prozessliste. Live bewiesen am 24.09. um 15:41.
|
||
- **Nachtruhe:** 00:00–06:59 landet alles Nicht-Dringende in `~/.hermes/night-queue.txt`. Dringend ist `-d`, ein
|
||
Betreff mit „Alarm" oder „Notfall" oder ein Text, der mit „KRITISCH" beginnt.
|
||
- **Morgenmeldung:** `mc2-morgenmeldung.timer` (07:00) startet `deploy/morgenmeldung.sh`. Es schickt eine Nachricht
|
||
„Guten Morgen, Commander. Heute Nacht gab es N Meldungen" mit höchstens 3500 Zeichen. Drei Versuche im Abstand von
|
||
60 s; scheitert Telegram, bleibt der Stapel als `night-queue.txt.senden` liegen und kommt mit der nächsten
|
||
Morgenmeldung. Zuletzt Gesendetes: `night-queue.txt.zuletzt-gesendet`. Das Skript kürzt außerdem
|
||
`~/mc2-notify.log` ab 3 MB auf die letzten 2 MB.
|
||
- **Scheitern beide Wege,** steht die Meldung mit `FALLBACK` im Protokoll und geht per `wall` an die
|
||
Box-Konsolen (`MC_NOTIFY_OHNE_WALL=1` schaltet `wall` ab). Seit 24.09. steht im `FALLBACK`-Eintrag auch, warum der
|
||
Zweitweg scheiterte: `FALLBACK (telegram fehlgeschlagen: <Ausgabe von hermes send>; Zweitweg: <Grund>): <Text>`,
|
||
etwa „Zugangsdatei … fehlt oder ist nicht lesbar“ oder „Telegram lehnt ab, HTTP-Fehler“ (ohne Klammern, damit
|
||
`update_verlauf.py` den Eintrag weiter trennen kann).
|
||
- **Testen:** Einstellungen → Meldungen → „Test senden“ (je Instanz; `POST /api/einstellungen/telegram-test` bzw.
|
||
`/api/homelab/einstellungen/telegram-test`). Der Knopf ruft `notify.sh -d -s "[Test]" …` mit
|
||
`MC_NOTIFY_NO_ANNOUNCE=1` (Lucy spricht den Test nicht) und liest das Ergebnis samt Grund über eine Kennung aus dem
|
||
Melde-Log (`services/einstellungen.py`). Höchstens ein Test alle 20 s. Von Hand:
|
||
`bash ~/mission-control-v2/deploy/notify.sh -s "[Test]" "Testmeldung"`; nachts landet sie in der Warteschlange,
|
||
mit `-d` kommt sie sofort.
|
||
|
||
| Betreff | Absender | Inhalt |
|
||
|---|---|---|
|
||
| `[Box-Update]` | `autoupdate.sh`, `jobs/sonntags-update.sh` | Ergebnis je Baustein, Wochenbericht, Neustart-Ankündigung; beginnt der Text mit „KRITISCH", ist es dringend |
|
||
| `[Box-Problem]` | Wächter | neuer roter Hinweis; nach 6 h erneut mit „Immer noch:" |
|
||
| `[Box wieder ok]` | Wächter | ein gemeldeter roter Hinweis ist erledigt |
|
||
| `[Homelab-Problem]` / `[Homelab wieder ok]` | Wächter der Homelab-Instanz | wie oben, sobald diese Instanz läuft |
|
||
| `[Homelab-Update]` / `[Alarm] Homelab-Update` | „Jetzt updaten“ und „Alle aktualisieren“ im Homelab | Ergebnis je Lauf, dringend bei Rot; bei „Alle aktualisieren“ (seit 24.09.) nur Fehler einzeln, am Ende eine Sammelmeldung, dringend bei Abbruch |
|
||
| `[Modell-Radar]` | `backend/radar_lauf.py` | ein Kandidat hat den Nachttest bestanden |
|
||
| `[Sicherung]` | `backend/services/probe_wiederherstellung.py` | die monatliche Probe-Wiederherstellung war rot (normale Dringlichkeit) |
|
||
| `[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`) | „<Name> antwortet nicht" | – |
|
||
| Sicherung (seit 24.09.) | – | `pbs-backup` scheitert; Probe-Wiederherstellung rot, älter als 40 Tage oder noch nie gelaufen (sobald ihr Timer eingerichtet ist) |
|
||
| Proxmox-Host (nur Rolle `homelab`, seit 24.09.) | – | 10 Minuten lang über 95 % RAM oder über 90 °C CPU (aus den Messwerten, mindestens 8 Minutenpunkte) |
|
||
| Abgestürzte Prüfung | – | „Eine Prüfung des Wächters lief nicht" |
|
||
|
||
In der Rolle `homelab` prüft der Wächter Platte, Partner, den Ausführer, die Weboberflächen der freigegebenen
|
||
Gäste (einen Gast mitten in seinem Update-Lauf nicht: Das Ergebnis meldet der Lauf selbst) und seit 24.09. RAM und
|
||
CPU-Temperatur des Proxmox-Hosts (gelb, Schwellen über `MC_WAECHTER_HOST_RAM` und `MC_WAECHTER_HOST_TEMP` in
|
||
`/etc/mc2/homelab.env`) und meldet mit „[Homelab-Problem]". Im selben Takt stößt er das wöchentliche Suchen an (siehe „Homelab-Teil im Betrieb“); scheitert
|
||
es für einen Gast zweimal hintereinander, gibt es einen gelben Hinweis „<App>: Die Suche nach Updates scheitert“.
|
||
|
||
- **Selbstreparatur:** Nur ein abgestürzter Dienst (`ActiveState=failed`) wird neu gestartet, höchstens 2× je Stunde
|
||
und Hinweis. Ein gestoppter Dienst (`inactive`) wird nur gemeldet. Ein schlafender Dienst (`inactive` und
|
||
`disabled`) ist kein Befund. Bei Timer-Läufen schläft der Timer, nicht der Dienst dahinter (der ist `static`):
|
||
Ist `mc2-radar.timer` abgeschaltet (Einstellungen → Radar aus), ist ein alter Fehlschlag von `mc2-radar` kein
|
||
Befund mehr.
|
||
- **Während eines Updates** (ein Prozess `autoupdate.sh`, `update-engine.sh`, `update-swap.sh` oder `hermes … update`
|
||
läuft) prüft er Dienste und Kern nicht und repariert nichts. Die Oberfläche zeigt dann „Update läuft".
|
||
- **Meldungen:** Rote Hinweise gehen an Telegram und in den Briefkasten, bei Fortbestand alle 6 h erneut; nachts gilt
|
||
die Nachtruhe. Gelbe Hinweise stehen nur in der Oberfläche.
|
||
- **Knöpfe am Hinweis:** „Neu starten" bzw. „Starten", „Protokoll", „Jetzt erneut laufen lassen" (Timer),
|
||
„Erneut ausführen" (`hermes cron run`), „Freigeben" (Pin), „Ausblenden bis zum nächsten Lauf" (Werkzeugfehler
|
||
eines Jobs; MC2 merkt sich den Lauf in `/srv/models/mc2-quittiert.json`, hat der nächste Lauf wieder Fehler,
|
||
erscheint der Hinweis erneut).
|
||
- Der Wächter ist der einzige Schreiber von `/srv/models/mc2-waechter.json`. Ist sein letzter Takt älter als
|
||
5 Minuten, zeigt die Startseite „Wächter schweigt".
|
||
- **Hirn (seit 24.09.):** Geprüft wird gezielt das Modell mit der Rolle `hermes` und sein Zustand in llama-swap
|
||
(`/running`), nicht mehr „irgendein Modell läuft". Lädt es gerade (`starting`), ist das kein Befund — höchstens
|
||
10 Minuten lang (`MC_WAECHTER_HIRN_LADEN_S`), danach heißt der Hinweis „Lucys Hirn lädt nicht fertig".
|
||
|
||
## Einstellungen der Oberfläche (Zeitfenster, Radar-Schalter)
|
||
|
||
Seit 24.09.2026, Logik in `backend/services/einstellungen.py`, Schnittstellen unter `/api/einstellungen`.
|
||
|
||
- **Eine Datei:** `/srv/models/mc2-einstellungen.json` (`update_fenster: {tag: 1–7, uhrzeit: "HH:MM"}`,
|
||
`radar: {an}`). Nur MC2 schreibt sie; `deploy.sh` und `autoupdate.sh` lesen sie. Fehlt sie, gilt So 04:30 und
|
||
Radar an. Sie steckt in jeder Sicherung (`mc2-*.json`).
|
||
- **Update-Zeitfenster:** Speichern schreibt das Drop-in
|
||
`~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf` (`OnCalendar=` leer, dann der neue Plan). Ablauf:
|
||
Timer stoppen → Drop-in → `daemon-reload` → Stempel `~/.local/share/systemd/timers/stamp-mc2-autoupdate.timer`
|
||
auf jetzt → Timer starten. Grund: Der Timer hat `Persistent=true`. Ein laufender Timer rechnet beim Reload mit
|
||
seinem letzten Lauf und dem neuen Plan, ein frisch gestarteter mit dem Stempel. Beides hätte einen schon vorbei
|
||
gewesenen Termin sofort nachgeholt (so am 24.09. mittags passiert). Scheitert ein Schritt, kommt das alte Drop-in
|
||
zurück, und der Timer läuft wieder. Während `mc2-autoupdate.service` läuft, lehnt MC2 das Ändern ab.
|
||
- **Neustart-Fenster:** `deploy/wartungsfenster.sh` (von `autoupdate.sh` eingebunden) erlaubt den Neustart nur in
|
||
den drei Stunden ab der vollen Stunde des Beginns: So 04:30 → So 04:00–06:59, Sa 23:30 → Sa 23:00 – So 01:59.
|
||
Es liest das Fenster mit `jq` aus der Einstellungsdatei; `MC_WARTUNGSFENSTER="<Tag> <HH:MM>"` und
|
||
`MC_FENSTER_JETZT` sind Test-Schalter. `MC_AUTOUPDATE_REBOOT_JETZT=1` erzwingt den Neustart wie bisher.
|
||
- **Radar-Schalter:** Aus = `systemctl --user disable --now mc2-radar.timer` (ein laufender Nachttest endet noch).
|
||
An = `enable`, Stempel `stamp-mc2-radar.timer` auf jetzt, `start` — kein Nachholen, also tagsüber kein Laden.
|
||
- **Deploy:** Das Drop-in fasst `deploy.sh` nie an. Steht das Radar auf aus, lässt der Deploy den Timer aus
|
||
(`disable --now`) statt ihn wie früher einzuschalten; steht es auf an und läuft der Timer nicht, startet ihn der
|
||
Deploy mit Stempel, also ohne Nachholen.
|
||
- **Wächter:** Ein ausgeschaltetes Radar schläft (Timer `inactive` und `disabled`) und ist kein Befund; die
|
||
Oberfläche zeigt unter Einstellungen „Schläft“.
|
||
- **Prüfen auf der Box:**
|
||
`systemctl --user cat mc2-autoupdate.timer`, `systemctl --user list-timers mc2-autoupdate.timer mc2-radar.timer`,
|
||
`systemctl --user is-enabled mc2-radar.timer`.
|
||
|
||
## Software-Stand
|
||
|
||
- **Stand-Datei:** Nach dem Umschalten schreibt `deploy.sh` (nach der Nachprüfung) `/srv/models/mc2-stand.json`:
|
||
`commit` (kurz), `betreff`, `commit_datum`, `deploy_zeit`. `deploy/homelab/ausrollen.sh` schreibt dasselbe nach
|
||
erfolgreichem `einrichten.sh` in den Container (`/var/lib/mc2/mc2-stand.json`, Eigentümer `mc2`). Beide nutzen
|
||
`deploy/stand-schreiben.py` (nur Standardbibliothek, atomar). Scheitert nur das Schreiben, gilt der Deploy trotzdem.
|
||
- **Anzeige:** `/api/instanz` liefert `stand` mit, `/api/partner/instanz` den der anderen Instanz; Einstellungen →
|
||
Software-Stand zeigt beide und einen Hinweis, wenn sie abweichen. Ohne Stand-Datei liest MC2 den Stand aus git
|
||
(`quelle: "git"`, ohne Deploy-Zeit), sonst `unbekannt`.
|
||
|
||
## Dienste schlafen legen und wecken
|
||
|
||
- Schlafen legen: `systemctl --user disable --now <unit>` (seit 24.09.: `box-console`, `voice-service`).
|
||
- Wecken bis zum nächsten Neustart der Box: Knopf „Wecken" unter „Dienste und Protokolle" oder
|
||
`systemctl --user start <unit>`.
|
||
- Dauerhaft wecken: `systemctl --user enable --now <unit>`; für einen Neuaufbau die Unit zusätzlich in `AKTIV` in
|
||
`deploy/deploy.sh` eintragen.
|
||
|
||
## Deploy
|
||
|
||
Voraussetzung: Der Stand liegt in `main` auf Gitea (Branch, Prüftor grün, Merge). Dann auf der Box:
|
||
|
||
```bash
|
||
bash ~/mission-control-v2/deploy/deploy.sh
|
||
```
|
||
|
||
**Stufe 1** (die bisherige Fassung des Skripts): Sperre gegen einen zweiten Deploy (`flock` auf
|
||
`$XDG_RUNTIME_DIR/mc2-deploy.lock`). Läuft ein Update-Auftrag (Gruppe `maintenance` in `/api/jobs`), bricht der
|
||
Deploy ab — das Update führt Skripte aus diesem Checkout aus. Downloads laufen weiter: Aufträge sind eigene
|
||
systemd-Einheiten und überleben den Neustart von MC2. Dann den alten Stand merken, `git fetch` und
|
||
`git merge --ff-only origin/main` und die neue Fassung als Stufe 2 starten.
|
||
|
||
**Stufe 2** (die neue Fassung):
|
||
|
||
1. `pip install` aus `backend/requirements.txt` und `backend/requirements-dev.txt`.
|
||
2. Prüftor `deploy/pruefen.sh`.
|
||
3. llama-swap-Config nur, wenn sich `deploy/llama-swap.config.yaml` in diesem Deploy geändert hat: Sicherung
|
||
`/etc/llama-swap/config.yaml.bak-<Zeit>` (die letzten 5 bleiben), dann ersetzen. llama-swap lädt dank
|
||
`--watch-config` selbst neu. Weicht die lebende Datei nur ab, gibt es einen Hinweis und sonst nichts.
|
||
4. Alle Repo-Units nach `~/.config/systemd/user/`, dazu die Drop-ins `mc2-steward.service.d/warmset.conf` und
|
||
`mission-control-2.service.d/override.conf`; `daemon-reload`; `enable` für die Units in `AKTIV`; Timer starten
|
||
(den Update-Timer nur, wenn er noch nicht läuft). Das Drop-in `mc2-autoupdate.timer.d/zeitfenster.conf` gehört
|
||
der Oberfläche und bleibt unangetastet. Den Radar-Timer schaltet der Deploy nach dem Schalter in
|
||
`mc2-einstellungen.json`: aus = `disable --now`, an = `enable` und, falls er nicht läuft, Start mit Stempel.
|
||
5. Cron-Skripte `deploy/jobs/*.sh` und `*.py` nach `~/.hermes/scripts/`.
|
||
6. Skills `deploy/skills/*` nach `~/.hermes/skills/<name_mit_unterstrich>/`, abgelöste Skills nach
|
||
`~/.hermes/skills-archiv/`. Plugins `deploy/hermes-plugins/*` nach `~/.hermes/plugins/`; aktiviert werden sie
|
||
einmalig von Hand, Hermes startet der Deploy nicht neu.
|
||
7. Neustart von `mc2-gateway`, `mission-control-2` und `mc2-steward`, dann bis zu 60 s Nachprüfung: `/api/health`,
|
||
`/gw/health`, Steward aktiv.
|
||
|
||
Erfolg: eine Zeile in `/srv/models/mc2-deploy.log`, die Stand-Datei `/srv/models/mc2-stand.json` und „Deploy <commit>
|
||
ist live". Danach (Schritt 8) zieht der Deploy den
|
||
Homelab-Teil mit, sobald `box-partner.sh` einen Partner eingerichtet hat: `deploy/homelab/ausrollen.sh` mit der IP aus
|
||
`partner.conf`. Scheitert das, bleibt die Box live und es kommt „[Alarm] Deploy"; `MC_DEPLOY_OHNE_HOMELAB=1` lässt
|
||
den Schritt aus. Scheitert ein Schritt:
|
||
`git reset --hard` auf den alten Stand, llama-swap-Config zurück (falls ersetzt), Dienste neu, Zeile `GESCHEITERT` im
|
||
Log und die dringende Meldung „[Alarm] Deploy".
|
||
|
||
Schalter: `MC_DEPLOY_TROTZDEM=1` (trotz laufendem Update-Auftrag), `MC_DEPLOY_OHNE_TESTS=1` (Prüftor überspringen, nur im
|
||
Notfall), `MC_DEPLOY_SKIP_SWAP_CONFIG=1` (llama-swap-Config nie anfassen).
|
||
|
||
Nicht Teil des Deploys: das Frontend bauen (`frontend/dist` kommt fertig aus Git), die Root-Kopie von `warmup.sh`,
|
||
Neustarts von llama-swap und Hermes.
|
||
|
||
**Prüftor** `deploy/pruefen.sh` (am PC vor dem Push, auf der Box im Deploy): Shell-Syntax (`bash -n` für
|
||
`deploy/*.sh` und `deploy/jobs/*.sh`), Python-Syntax aller versionierten `.py` außerhalb von `frontend/`,
|
||
`ruff check .` (nur wo ruff installiert ist; `requirements-dev.txt` bringt nur pytest mit), Import von `app`,
|
||
`gateway_app`, `steward` und `radar_lauf`, dann `pytest backend/tests`. Die Frontend-Prüfungen (`npm run lint`,
|
||
`npm test`, `npm run build`) laufen nur am PC.
|
||
|
||
**Probelauf auf der Box** `deploy/probelauf-box.sh` (am PC, vor dem Merge nach `main`): schickt den lokalen HEAD
|
||
als Abzug nach `/tmp` auf der Box und lässt dort das Prüftor mit dem Python des Box-Checkouts laufen. Ändert auf
|
||
der Box sonst nichts. Grund: Unter Linux zeigen sich Wettläufe, die am Windows-PC durchgehen (24.09.).
|
||
|
||
## Homelab-Teil einrichten (Phase 3/4)
|
||
|
||
Jeder Schritt braucht das OK des Users (Container anlegen, Ausführer als root auf dem Host, Telegram-Zugang in
|
||
den Container). Alles läuft am PC in Git-Bash, im Repo; SSH-Zugang zu `pve` (Schlüssel `id_lucy_infra`).
|
||
|
||
1. `bash deploy/homelab/container-anlegen.sh` — unprivilegierter Debian-13-Container (nächste freie ID, 1 Kern,
|
||
1 GB RAM, 4 GB, DHCP, Autostart, Etikett `mc2`), SSH-Schlüssel wie bei allen Gästen. Gibt die IP aus. Diese
|
||
Adresse danach in der Fritzbox fest zuordnen (Container 107: 192.168.178.31, fest seit 25.09.): Partner-Adresse
|
||
der Box, Ausführer-Konfiguration und Deploy-Schritt 8 hängen an ihr.
|
||
2. `bash deploy/homelab/ausrollen.sh <ip>` — Code von HEAD in `/opt/mc2`, `einrichten.sh` (Nutzer `mc2`, Python-
|
||
Umgebung, Units `mc2-homelab`, `mc2-homelab-steward`, `mc2-homelab-morgenmeldung.timer`). Auch jedes spätere
|
||
Update des Homelab-Teils geht so (erst Prüftor und Probelauf auf der Box).
|
||
3. Telegram-Zugang (nur mit OK): `TELEGRAM_BOT_TOKEN` und `TELEGRAM_HOME_CHANNEL` in `/etc/mc2/telegram.env`
|
||
(Eigentümer `root:mc2`, 0640).
|
||
4. `bash deploy/homelab/ausfuehrer-einrichten.sh <ip>` — Ausführer, Unit und Konfiguration (0600) auf den Host.
|
||
5. `bash deploy/homelab/box-partner.sh <ip>` — Drop-ins `partner.conf` für `mission-control-2` und `mc2-steward`
|
||
auf der Box; ab dann prüfen sich beide Instanzen gegenseitig.
|
||
|
||
Prüfen: `curl http://<ip>:9001/api/homelab/ziele` (nach etwa einer Minute stehen die Geräte darin),
|
||
`systemctl status mc2-ausfuehrer` auf dem Host, Seite „Homelab“ der Oberfläche.
|
||
|
||
Ein neuer Stand des Ausführers (`deploy/homelab/ausfuehrer.py`) kommt nicht mit dem Deploy; dafür Schritt 4 erneut
|
||
laufen lassen. Achtung: `ausfuehrer-einrichten.sh` schreibt `/etc/mc2-ausfuehrer.json` neu — ein von Hand gesetztes
|
||
`sicherung_speicher` danach wieder eintragen und `systemctl restart mc2-ausfuehrer`.
|
||
|
||
## Homelab-Teil im Betrieb
|
||
|
||
- **Sicherung statt Snapshot** (Gäste, bei denen kein Snapshot geht; heute der PBS, CT 105, wegen seines
|
||
Bind-Mounts): Vor dem Update sichert der Ausführer den Container per `vzdump` auf den ersten lokalen Speicher, der
|
||
Sicherungen annimmt — auf dem Proxmox-PC `local` (`/var/lib/vz/dump`, liegt auf der Systemplatte des Hosts). Nie
|
||
auf `pbs-qnap`. Anderer Speicher: `"sicherung_speicher": "<Name>"` in `/etc/mc2-ausfuehrer.json`, dann
|
||
`systemctl restart mc2-ausfuehrer`. Nimmt kein lokaler Speicher Sicherungen an, sagt es die Karte („Rückweg“); die
|
||
Lösung ist Sache des Users (Proxmox → Rechenzentrum → Speicher → `local` → Inhalt „VZDump-Sicherung“). Vorher prüft
|
||
er den Platz (frei > belegt × 1,2), sonst beginnt das Update nicht.
|
||
- **Eigene Sicherungen erkennen:** Notiz `mc2-sicherung: vor einem Update durch den Homelab Orchestrator (<Gast>)`.
|
||
Nach einem grünen Lauf bleibt nur die neueste je Gast. Ansehen auf dem Host:
|
||
`pvesh get /nodes/pve/storage/local/content --content backup --output-format json-pretty`. Eine Sicherung von Hand
|
||
zurückspielen: `pct shutdown <vmid> && pct restore <vmid> <volid> --force 1 --storage local-lvm && pct start <vmid>`
|
||
(der Bind-Mount und seine Daten bleiben, wie sie sind).
|
||
- **Wartezeit nach Skriptänderung:** Ist `ct/<app>.sh` bei community-scripts jünger als `MC_HOMELAB_KARENZ_H` Stunden
|
||
(Standard 48), zeigt die Karte „Update bereit“ ohne Knopf und nennt, ab wann es geht. Ändern oder abschalten (`0`):
|
||
`MC_HOMELAB_KARENZ_H=…` in `/etc/mc2/homelab.env` im Container, dann `systemctl restart mc2-homelab`.
|
||
- **Arcane-Schlüssel (seit 24.09. über die Oberfläche):** in Arcane unter Einstellungen → API-Schlüssel anlegen, dann in
|
||
der Oberfläche unter Einstellungen (Karte Homelab) eintragen. Der Homelab-Teil fragt Arcane erst, ob der Schlüssel
|
||
gilt (Umgebungen und Images lesen); nur dann speichert er ihn in `/var/lib/mc2/arcane.key` (0600, Eigentümer `mc2`),
|
||
und die Übersicht sieht die Docker-Images ohne Neustart. Lehnt Arcane ab (etwa „HTTP 401“) oder antwortet nicht,
|
||
wird nichts gespeichert. Der Schlüssel erscheint danach nirgends mehr (Antwort, Protokoll, Journal). Löschen:
|
||
derselbe Knopf in der Oberfläche oder `rm /var/lib/mc2/arcane.key`. `MC_ARCANE_KEY` in `/etc/mc2/homelab.env` geht
|
||
weiter vor; solange es gesetzt ist, lehnt die Oberfläche das Eintragen ab und sagt warum.
|
||
- **Docker-Updates echt statt Probelauf:** Schalter in den Einstellungen, gespeichert in
|
||
`/var/lib/mc2/homelab-einstellungen.json` (`{"arcane": {"echt": true}}`). Setzt `/etc/mc2/homelab.env`
|
||
`MC_ARCANE_ECHT`, gewinnt die Umgebung (`1` = echt, sonst Probelauf), und der Schalter sagt es.
|
||
- **„Alle aktualisieren“ (seit 24.09.):** spielt alle Updates mit Knopf nacheinander ein — die Gäste nach VMID, dann
|
||
NPMplus, dann AdGuard, zuletzt die Pakete des Proxmox-Hosts (ohne Neustart). Ist ein Schritt rot (zurückgerollt oder
|
||
gescheitert), bleibt der Rest stehen, und es kommt eine dringende Meldung; sonst am Ende eine Sammelmeldung.
|
||
Solange er läuft, lehnen die einzelnen Knöpfe „Jetzt updaten“ ab. Stand:
|
||
`curl -s http://192.168.178.31:9001/api/homelab/sammellauf` bzw. `/var/lib/mc2/homelab-sammellauf.json`. Startet
|
||
`mc2-homelab` mitten im Lauf neu (auch durch einen Deploy), gilt er als abgebrochen („unterbrochen (Neustart)“, mit
|
||
dringender Meldung); der Schritt, der gerade lief, steht auf „fehler“ — den Stand des Geräts in der Übersicht prüfen.
|
||
- **Protokoll (seit 24.09.):** `curl -s 'http://192.168.178.31:9001/api/homelab/protokoll?grenze=50' | jq` zeigt
|
||
Aufträge, Läufe, Sammelläufe, Hinweise, Meldungen und das wöchentliche Suchen, neueste zuerst; `&berichte=1` auch die
|
||
Berichte des Ausführers. Die Quellen bleiben die Dateien in `/var/lib/mc2` (`ausfuehrer-auftraege.json` hebt jetzt
|
||
die letzten 500 erledigten Aufträge auf, `ausfuehrer-berichte.json` die Eingänge der letzten 150 Berichte) und das
|
||
Melde-Log `/var/lib/mc2/notify.log`.
|
||
- **Wöchentliches Suchen:** Der Steward legt für jeden freigegebenen, laufenden Container, dessen Paketlisten älter als
|
||
7 Tage sind, den Auftrag `suchen` an (nur `apt-get update` bzw. `apk update` im Gast, es wird nichts installiert):
|
||
nachts 02:00–05:00, höchstens einmal je Gast und Tag, nicht während eines Updates; war die Instanz nachts aus, gleich
|
||
nach dem Start. Stand in `/var/lib/mc2/homelab-pflege.json` (Nacht, je Gast: letzter Tag, Fehlschläge, letzter
|
||
Fehler). Schreibt nur der Steward; zum Zurücksetzen die Datei löschen und `systemctl restart mc2-homelab-steward`.
|
||
|
||
## Messwerte (Monitoring, seit 24.09.)
|
||
|
||
Jede Minute ein Punkt je Gerät, gelesen als letzte Stunde, letzter Tag oder letzte Woche (Aufbau in
|
||
[ARCHITEKTUR.md](ARCHITEKTUR.md), Abschnitt „Monitoring“).
|
||
|
||
- **Wo:** Box `/srv/models/mc2-messwerte/box-JJJJ-MM-TT.jsonl` (schreibt `mc2-steward`). Homelab
|
||
`/var/lib/mc2/mc2-messwerte/pve-…`, `ct-<vmid>-…`, `vm-<vmid>-…` (schreibt `mc2-homelab`, was der Ausführer jede Minute
|
||
schickt; Eigentümer `mc2`). Je Tag (Berliner Zeit) eine Datei, eine JSON-Zeile je Minute.
|
||
- **Wie groß:** eine Zeile hat rund 140 Bytes (Box, Gäste) bzw. 175 Bytes (Proxmox-Host), am Tag 1440 Zeilen. Box:
|
||
rund 0,2 MB je Tag, höchstens rund 2 MB. Homelab mit Host und 7 Gästen: rund 1,7 MB je Tag, höchstens rund 15 MB;
|
||
jeder weitere Gast rund 0,2 MB je Tag.
|
||
- **Wie lange:** Das erste Schreiben eines neuen Tages löscht die Tagesdateien, deren Tag mehr als 8 Tage zurückliegt;
|
||
es bleiben höchstens 9 je Gerät (heute und die 8 Tage davor). Nicht in der Sicherung (`backup.sh` nimmt nur
|
||
`mc2-*.json`); das Aufräumen der Modell-Platte bietet den Ordner nie zum Löschen an. Den Ordner von Hand zu löschen
|
||
ist harmlos: Er entsteht mit dem nächsten Punkt neu, der Verlauf beginnt von vorn.
|
||
- **Lücken:** Läuft der Steward, die Box oder der Ausführer nicht, bleiben die Minuten leer (`null`) und werden nicht
|
||
aufgefüllt. Nach einem Neustart des Homelab-Teils fehlt für eine Minute die Netz-Rate; nach dem Neustart eines Gasts
|
||
oder des Hosts ebenso (die Zähler beginnen von vorn).
|
||
- **Ansehen:**
|
||
|
||
```bash
|
||
tail -n 3 /srv/models/mc2-messwerte/box-$(date +%F).jsonl # Box: die letzten Minuten
|
||
curl -s 'http://127.0.0.1:9001/api/messwerte?zeitraum=1h' | jq '.aktuell' # Box: letzter Punkt
|
||
curl -s 'http://192.168.178.31:9001/api/homelab/messwerte?zeitraum=1h' | jq '.geraete[] | {id, aktuell}'
|
||
python3 /usr/local/lib/mc2/ausfuehrer.py --messwerte # auf pve: ein Punkt, nur lesend (CPU über eine Sekunde)
|
||
journalctl -u mc2-ausfuehrer -n 50 | grep Messwerte # auf pve: steht hier etwas, gingen Punkte nicht durch
|
||
```
|
||
|
||
- **Ausführer:** Ein neuer Stand kommt nicht mit dem Deploy, sondern mit `bash deploy/homelab/ausfuehrer-einrichten.sh
|
||
<ip>` (danach ein von Hand gesetztes `sicherung_speicher` wieder eintragen, siehe oben). Ein alter Ausführer schickt
|
||
keine Messwerte; dann bleibt der Homelab-Verlauf leer, sonst ändert sich nichts.
|
||
- **Schalter:** `MC_MESSWERTE_ENABLED=0` im Steward der Box schaltet das Schreiben ab; `MC_MESSWERTE_PROBE_S` (Standard
|
||
5) ist der Abstand der Proben für GPU-Last und Temperaturen. Ein Trocken- oder Probelauf (`MC_WAECHTER_TROCKEN=1`,
|
||
`MC_PROBELAUF=1`) schreibt nie mit.
|
||
|
||
## Sicherung
|
||
|
||
- **Wann:** `mc2-backup.timer` täglich 03:30 (+≤5 min); außerdem vor jedem Hermes-Update, vor jedem Zurückspielen und
|
||
per Knopf „Jetzt sichern". Von Hand: `bash ~/mission-control-v2/deploy/backup.sh`.
|
||
- **Wohin:** `/srv/models/mc2-backups/mc2-state-<Zeit>.tar.gz`, Rechte 600 (enthält `~/.hermes/.env`), die letzten 14
|
||
bleiben. Danach Spiegel per `rsync --delete` auf den Proxmox-Host (`/var/lib/vz/mc2-backups`, eigener Schlüssel
|
||
`~/.ssh/mc2_offsite`; Ziel und Schlüssel über `MC_BACKUP_OFFSITE` und `MC_BACKUP_OFFSITE_KEY`). Scheitert der
|
||
Spiegel, gilt die lokale Sicherung trotzdem.
|
||
- **Inhalt:**
|
||
- aus `~/.hermes`: `config.yaml`, `.env`, `plugins/`, `cron/`, `state/`; seit 24.09. auch `memories/` (Lucys
|
||
Gedächtnis), `SOUL.md`, `skills/` und `scripts/`; dazu Reste der früheren Desktop-Anbindung (`agent-hooks/`,
|
||
`shell-hooks-allowlist.json`, `desktop-gateway-token`, `pc-paths.yaml`, Drop-in `session-token.conf`);
|
||
- `/etc/llama-swap/config.yaml`;
|
||
- der Box-Wart-Zustand `/srv/models/mc2-*.json`;
|
||
- die Units aus `~/.config/systemd/user/` und `/etc/systemd/system/llama-swap.service.d/` (nur zum Nachschlagen,
|
||
`restore.sh` spielt sie nicht zurück);
|
||
- Lucys Stimmreferenz `~/.lucy-stimme/app/ref.wav`;
|
||
- `known-good/`: `pip freeze` je venv, Versionen (OS, Kernel, MC2- und Hermes-Commit, llama.cpp, llama-swap) und
|
||
die Liste der Modelldateien.
|
||
- Eine Sicherung ist seit 24.09. rund 12 MB groß.
|
||
- **Nicht enthalten:** Modelle (neu ladbar), Code (Git), venvs, `~/.ssh` (auch nicht der Spiegel-Schlüssel).
|
||
- **Zweite Schicht: PBS** (`pbs-backup.timer`, täglich 03:50; Units und Skript seit 24.09. im Repo):
|
||
`deploy/pbs-backup.sh` sichert `~/.hermes` ganz (auch Sitzungen und Protokolle, die der Tarball weglässt),
|
||
`~/wissens-vault` (optional) und `/etc/llama-swap` als pxar-Archive auf den Proxmox Backup Server
|
||
(`192.168.178.156:8007`, Container 105, Datastore `qnap` = NFS-Freigabe auf dem QNAP, Backup-ID `aibox`). Der PBS
|
||
dedupliziert (ein Lauf dauert inkrementell rund 30 s) und hebt 7 Tage, 4 Wochen und 3 Monate auf (Prune-Job auf dem
|
||
PBS). Zugang `~/.config/pbs-backup/env` (Benutzer `aibox@pbs`, Rolle DatastoreBackup, Rechte 600) und der Client
|
||
`~/bin/proxmox-backup-client` liegen nur auf der Box, nie im Repo. Die Sicherung lief vom 09.07. bis 20.08. täglich
|
||
grün; am 21.08. brach sie ab (ihr erster Quellordner `/srv/models/mem0`, das abgelöste Gedächtnis, fehlte) und wurde
|
||
im KISS-Umbau abgeschaltet. Das neue Skript kennt mem0 nicht mehr. `deploy.sh` spielt die Units aus, schaltet sie
|
||
aber weder ein noch aus. Scheitert ein Lauf, zeigt der Wächter gelb.
|
||
- **Außerdem:** Der PBS sichert die Proxmox-Container, das QNAP macht Snapshots; beides läuft auf den anderen Geräten
|
||
und ist hier nicht geprüft.
|
||
|
||
**PBS-Sicherung** — an seit 24.09. (User-Ja; erster Lauf 21:20, 116 s, 65 % wiederverwendet). Der Deploy hält
|
||
den Timer an (`AKTIV`). Von Hand prüfen oder neu einrichten:
|
||
|
||
```bash
|
||
export XDG_RUNTIME_DIR=/run/user/$(id -u)
|
||
systemctl --user cat pbs-backup.service | grep ExecStart # muss auf deploy/pbs-backup.sh zeigen
|
||
systemctl --user start pbs-backup.service # Probelauf; kehrt nach dem Lauf zurück (~30 s)
|
||
journalctl --user -u pbs-backup.service -n 20 --no-pager # erwartet: „Duration: …“ und „End Time: …“, kein „Error“
|
||
touch ~/.local/share/systemd/timers/stamp-pbs-backup.timer # sonst holt der erste Start einen alten Lauf gleich nach
|
||
systemctl --user enable --now pbs-backup.timer
|
||
systemctl --user list-timers pbs-backup.timer # nächster Lauf 03:50
|
||
```
|
||
|
||
Ausschalten: `systemctl --user disable --now pbs-backup.timer`. Die alte Fassung `~/bin/pbs-backup.sh` wird danach
|
||
nicht mehr gebraucht; der Client daneben schon.
|
||
|
||
## Probe-Wiederherstellung (monatlich, seit 24.09.)
|
||
|
||
- **Wann:** `mc2-probe-wiederherstellung.timer`, am ersten Montag im Monat um 05:15 — nie sonntags (Updates ab 04:30),
|
||
lange nach der Sicherung um 03:30. `Persistent=true` holt einen verpassten Lauf nach. Von Hand:
|
||
`systemctl --user start mc2-probe-wiederherstellung.service` oder Knopf „Jetzt prüfen" am Hinweis.
|
||
- **Was:** `backend/services/probe_wiederherstellung.py` packt die jüngste Sicherung aus `/srv/models/mc2-backups` in
|
||
einen eigenen Tmp-Ordner `/var/tmp/mc2-probe-*` aus, prüft und löscht ihn wieder. Lebende Dateien fasst sie nie
|
||
an. `.env` und die Token-Dateien packt sie nicht aus, sie prüft nur, dass sie in der Sicherung stehen.
|
||
- **Geprüft:** Die jüngste Sicherung ist höchstens 48 Stunden alt und lässt sich vollständig lesen. Lucys Gedächtnis
|
||
(`memories/`) und `SOUL.md` sind da und stimmen mit dem lebenden Stand überein, soweit er vor der Sicherung schon so
|
||
dastand. Skills, Cron-Skripte und Hermes-Cron-Jobs sind da, `config.yaml` ist lesbar, `.env` vorhanden, die
|
||
llama-swap-Config hat Modelle, jede `mc2-*.json` des Box-Wart-Zustands ist lesbar, die systemd-Units samt
|
||
llama-swap-Drop-ins sind drin.
|
||
- **Ergebnis:** `/srv/models/mc2-probe-wiederherstellung.json` (Zeit, `gruen`/`rot`, Sicherung, Geprüftes, Fehler)
|
||
und `journalctl --user -u mc2-probe-wiederherstellung`. Bei Rot: Meldung „[Sicherung]" in normaler Dringlichkeit
|
||
(nachts in die Morgenmeldung) und ein gelber Hinweis des Wächters. Gelb auch, wenn die letzte Probe älter als
|
||
40 Tage ist.
|
||
|
||
## Zurückspielen
|
||
|
||
- **Per Oberfläche:** Updates → Sicherungen → „Zurückspielen". MC2 startet `restore.sh --yes <Datei>` als eigene
|
||
systemd-Unit (`mc2-restore-<Zeit>`), weil `restore.sh` MC2 selbst stoppt.
|
||
- **Per SSH:**
|
||
|
||
```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 <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](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`, darunter `mc2-einstellungen.json` und `mc2-stand.json`), Sicherungen (`mc2-backups/`), Radar-Downloads (`radar/`), Messwerte (`mc2-messwerte/`) |
|
||
| `~/.config/systemd/user/mc2-autoupdate.timer.d/zeitfenster.conf` | Update-Zeitfenster aus der Oberfläche (nur MC2 schreibt es) |
|
||
| `/etc/llama-swap/config.yaml` | lebende llama-swap-Config (+ `.bak-*`) |
|
||
| `/opt/llamacpp-vulkan/`, `/usr/local/bin/llama-server` | Motor (llama.cpp Vulkan) |
|
||
| `/usr/local/bin/llama-swap`, `/usr/local/bin/llama-swap-warmup.sh` | Router und Vorwärm-Skript (Root-Kopie) |
|
||
| `~/.hermes/` | Hermes: Code (`hermes-agent/`), `config.yaml`, `.env`, `SOUL.md`, `memories/`, `skills/`, `scripts/`, `cron/`, `logs/` |
|
||
| `~/.lucy-stimme/` | Lucys Stimme (pocket-tts), Referenz `app/ref.wav` |
|
||
| `~/.voice/` | Umgebung der Spracherkennung (`voice_service/install.sh`) |
|
||
| `~/projekte/` | Spiegel der Gitea-Repos (`projekte-sync`) |
|
||
| `~/mc2-notify.log`, `~/.hermes/night-queue.txt` | Meldeprotokoll, Nacht-Warteschlange |
|