doku: Phase 2b nachgezogen, tote Doku-Verweise im Code, Morgenmeldung verweist auf den echten Stapel
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8eb2fec2ea
commit
97ba6420e2
@@ -1,7 +1,6 @@
|
||||
"""
|
||||
Hermes-Agent-Status (Control-Plane-Read). MC betreibt Hermes NICHT — es zeigt nur
|
||||
Status + verlinkt das standalone hermes-webui. Voller Zugriff + Tools/MCP werden in
|
||||
Hermes' eigener Config verdrahtet (siehe docs/HERMES_SETUP.md).
|
||||
Hermes-Agent: Status und Hirn-Umstellung. MC betreibt Hermes NICHT — Werkzeuge und MCP werden in
|
||||
Hermes' eigener Config verdrahtet (siehe docs/ARCHITEKTUR.md, „Wer schreibt was").
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
Voll-Zustands-Backup (Hermes-Configs/Secrets + llama-swap config).
|
||||
Delegiert an deploy/backup.sh (eine Quelle der Wahrheit, identisch zum systemd-Timer);
|
||||
Restore läuft bewusst nur per CLI (deploy/restore.sh) — siehe docs/BACKUP.md.
|
||||
Restore läuft bewusst nur per CLI (deploy/restore.sh) — siehe docs/BETRIEB.md (Sicherung).
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
|
||||
@@ -309,7 +309,7 @@ def register_model(model_path: str, role: str | None = None, ctx: int = 8192,
|
||||
if "--cache-reuse" not in cmd and "--mmproj" not in cmd:
|
||||
cmd += " --cache-reuse 256 -cram 16384"
|
||||
# IDE-Coding profitiert von Nebenläufigkeit; sonst Default 1 Slot = voller Kontext/Anfrage
|
||||
# (--parallel teilt den Kontext HART auf die Slots auf, s. docs/OPTIMIZATION_PLAN.md §9.4 V6).
|
||||
# (--parallel teilt den Kontext HART auf die Slots auf, s. docs/archiv/2026-06-30-optimierungsplan.md §9.4 V6).
|
||||
if role_lower == "coder" and "--parallel" not in cmd:
|
||||
cmd += " --parallel 2"
|
||||
# Vocab-kompatiblen Draft automatisch anhängen — klassisch (DRAFTS_DIR) ODER MTP-Kopf neben
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Unit]
|
||||
Description=MC2 Zustands-Backup (Hermes-Configs/Secrets + llama-swap config)
|
||||
Documentation=file:%h/mission-control-v2/docs/BACKUP.md
|
||||
Documentation=file:%h/mission-control-v2/docs/BETRIEB.md
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
@@ -35,7 +35,7 @@ ANZAHL="$(grep -c '^- ' "$ARBEIT" || true)"
|
||||
TEXT="$(head -c "$MAX_ZEICHEN" "$ARBEIT")"
|
||||
if [ "$(wc -c < "$ARBEIT")" -gt "$MAX_ZEICHEN" ]; then
|
||||
TEXT="$TEXT
|
||||
… gekürzt. Alle Meldungen stehen im Cockpit unter Meldungen."
|
||||
… gekürzt. Den vollen Stapel hat die Box unter ~/.hermes/night-queue.txt.zuletzt-gesendet."
|
||||
fi
|
||||
NACHRICHT="Guten Morgen, Commander. Heute Nacht gab es $ANZAHL $WORT:
|
||||
$TEXT"
|
||||
|
||||
+20
-1
@@ -50,7 +50,7 @@ Client an MC2 vorbei direkt auf `:8080`. Nur den Radar-Kandidaten startet der Ra
|
||||
|
||||
| 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 |
|
||||
| `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; startet Update- und Download-Aufträge als eigene systemd-Einheiten `mc2-job-<id>` (`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/` |
|
||||
@@ -90,6 +90,24 @@ Fremde Dienste, die der Box-Wart nur steuert oder überwacht: `llama-swap` (Syst
|
||||
- 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.
|
||||
|
||||
## Aufträge (seit 24.09., Phase 2b)
|
||||
|
||||
- **Eigene Einheiten:** `services/jobengine.py` startet jeden Auftrag (Update, Modell-Download) per `systemd-run`
|
||||
als Einheit `mc2-job-<id>` des Nutzer-Managers (als root: des System-Managers). `RuntimeMaxSec` ist das
|
||||
Zeitlimit, „Abbrechen" stoppt die Einheit samt Kindern. Ein Neustart von MC2 (Deploy, Absturz) würgt den
|
||||
Auftrag nicht mehr ab.
|
||||
- **Akten:** `<Datenordner>/mc2-jobs/<id>.json` (Zustand), `.log` (Ausgabe), `.exit` (Exit-Code, atomar von einer
|
||||
Bash-Hülle geschrieben). MC2 liest die Akten beim Start (`wiederaufnehmen()` im Lebenszyklus der App) und
|
||||
beobachtet laufende Aufträge weiter; endet eine Einheit ohne Exit-Code, gilt der Auftrag als gescheitert bzw.
|
||||
abgebrochen oder als Zeitlimit. Beendete Aufträge verschwinden nach einem Tag bzw. ab 40 Stück.
|
||||
- **Geheimnisse** (z. B. `HF_TOKEN`) gehen über eine nur für den Nutzer lesbare Umgebungsdatei `<id>.env`, die der
|
||||
Auftrag beim Start liest und löscht — nicht über Befehlszeile oder Einheit (auf der Box nachgeprüft).
|
||||
- **Nacharbeiten** sind benannt (`@jobengine.nacharbeit`): `wartung:nach_update` (Zwischenspeicher leeren) und
|
||||
`modell:rolle` (Rolle nach dem Download setzen). Sie stehen mit ihren Daten in der Akte, laufen also auch nach
|
||||
einem Neustart, und zwar vor dem Endzustand: Wer „done" sieht, sieht auch ihre Wirkung.
|
||||
- **Ohne systemd** (PC, Tests, `MC_JOBS_ART=prozess`) läuft der Auftrag als Kindprozess und überlebt keinen
|
||||
Neustart. Ein Probelauf daneben (`MC_PROBELAUF=1`) nimmt keine Aufträge auf.
|
||||
|
||||
## Modelle und Modell-Rollen
|
||||
|
||||
- **Rollen-Aliase statt Namen:** Clients fragen `hermes`/`fast` (Hirn), `coder`/`heavy` (Coder), `vision` und
|
||||
@@ -117,6 +135,7 @@ Fremde Dienste, die der Box-Wart nur steuert oder überwacht: `llama-swap` (Syst
|
||||
| `/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-jobs/` | nur MC2 (Akten) und die Hülle des Auftrags (`.log`, `.exit`) | Akten atomar; Protokoll und Exit-Code schreibt der Auftrag selbst, MC2 hängt nur `[mc]`-Zeilen an. |
|
||||
| `/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 |
|
||||
|
||||
+9
-3
@@ -105,8 +105,10 @@ 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.
|
||||
`$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):
|
||||
|
||||
@@ -129,7 +131,7 @@ Erfolg: eine Zeile in `/srv/models/mc2-deploy.log` und „Deploy <commit> ist li
|
||||
`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
|
||||
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`,
|
||||
@@ -141,6 +143,10 @@ Neustarts von llama-swap und Hermes.
|
||||
`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.).
|
||||
|
||||
## Sicherung
|
||||
|
||||
- **Wann:** `mc2-backup.timer` täglich 03:30 (+≤5 min); außerdem vor jedem Hermes-Update, vor jedem Zurückspielen und
|
||||
|
||||
@@ -14,8 +14,13 @@ und Symptom; Erledigtes streichen (die Git-Historie behält es)._
|
||||
die letzten 5). Vorher `diff /etc/llama-swap/config.yaml deploy/llama-swap.config.yaml` und den lebenden Stand ins
|
||||
Repo holen. `MC_DEPLOY_SKIP_SWAP_CONFIG=1` lässt die Config ganz in Ruhe. Bis 24.09. überschrieb jeder Deploy sie
|
||||
bei jeder Abweichung und startete den Motor neu.
|
||||
- **Ein Neustart von MC2 bricht laufende Update- und Download-Jobs ab (24.09.).** Sie leben im MC2-Prozess.
|
||||
`deploy.sh` verschiebt den Deploy deshalb, solange ein Job läuft (`MC_DEPLOY_TROTZDEM=1` erzwingt).
|
||||
- **Aufträge überleben einen Neustart von MC2, aber keinen der Box (seit 24.09., Phase 2b).** Jeder Auftrag
|
||||
läuft als eigene systemd-Einheit `mc2-job-<id>`. Ein Deploy wartet trotzdem, solange ein Update-Auftrag
|
||||
(Gruppe `maintenance`) läuft, weil der Skripte aus dem Checkout ausführt; Downloads laufen weiter
|
||||
(`MC_DEPLOY_TROTZDEM=1` erzwingt). Bis 24.09. waren es Kindprozesse von MC2, jeder Neustart brach sie ab.
|
||||
- **Am PC grün heißt nicht auf der Box grün (24.09.).** Ein Test mit Wettlauf lief unter Windows durch und
|
||||
scheiterte im Deploy-Prüftor auf der Box (der Rückweg griff). Vor dem Merge nach `main`:
|
||||
`bash deploy/probelauf-box.sh` lässt das Prüftor mit dem lokalen HEAD auf der Box laufen.
|
||||
- **`deploy.sh` schaltet alles in `AKTIV` wieder ein.** Wer einen Dienst oder Timer dauerhaft aus haben will, nimmt
|
||||
ihn dort heraus, sonst dreht der nächste Deploy den User-Entscheid zurück (mit `mc2-autoupdate` schon passiert).
|
||||
Schlafende Units (`box-console`, `voice-service`) stehen nur in `UNITS`.
|
||||
|
||||
@@ -28,16 +28,11 @@ Hintergrund zur Homelab-Technik: [ARCHITEKTUR.md](../ARCHITEKTUR.md), Abschnitt
|
||||
1. **Ein Modelltausch schreibt die llama-swap-Config mehrfach.** „Übernehmen" im Radar trägt das Modell unter einer
|
||||
Sperre ein; Hirn-Umstellung, Aliase `fast`/`heavy` und ttl folgen als eigene Schreibvorgänge. Jeder lädt
|
||||
llama-swap neu und entlädt alle Modelle. Ziel: ein Schreibvorgang je Tausch.
|
||||
2. **Jobs überleben noch keinen MC2-Neustart.** Update- und Download-Jobs sind Kindprozesse von MC2; `deploy.sh`
|
||||
verschiebt deshalb. Verschwindet der Hermes-Job, wartet `autoupdate.sh` 20 Minuten und geht dann in
|
||||
Selbstreparatur und Rückweg. Lösung in Phase 2 (Worker).
|
||||
3. **Session-Token des Hermes-Dashboards (nur mit User-Ja).** Das Drop-in
|
||||
2. **Session-Token des Hermes-Dashboards (nur mit User-Ja).** Das Drop-in
|
||||
`hermes-builtin-ui.service.d/session-token.conf` aus der früheren Desktop-Anbindung ist weiter gesetzt; `backup.sh`
|
||||
und `restore.sh` sichern es samt Kopie `desktop-gateway-token`. Entfernen ist Security-Config.
|
||||
4. **Rote Wächter-Hinweise warten nachts bis 07:00.** Der Wächter meldet mit Betreff „[Box-Problem]" ohne `-d`; zwischen
|
||||
3. **Rote Wächter-Hinweise warten nachts bis 07:00.** Der Wächter meldet mit Betreff „[Box-Problem]" ohne `-d`; zwischen
|
||||
00:00 und 06:59 landet das in der Morgenmeldung. Klären, ob Rot sofort raus soll.
|
||||
5. **Die gekürzte Morgenmeldung verweist auf „Cockpit unter Meldungen".** Diesen Bereich gibt es nicht. Der volle
|
||||
Stapel liegt in `~/.hermes/night-queue.txt.zuletzt-gesendet`, jede Meldung zusätzlich in Lucys Briefkasten.
|
||||
6. **Code verweist auf verschobene Doku:** `deploy/mc2-backup.service` (`Documentation=` auf `docs/BACKUP.md`),
|
||||
`backend/services/backup.py` (`docs/BACKUP.md`), `backend/services/maintenance.py` (`docs/BEDIENUNG.md`,
|
||||
sudoers-Hinweis), `backend/services/agent.py` (`docs/HERMES_SETUP.md`), `backend/services/llamaswap.py`
|
||||
|
||||
Reference in New Issue
Block a user