doku: Historisches ins Archiv, Ueberfluessiges geloescht

- 19 Dateien nach docs/archiv/ mit Datumspraefix (JJJJ-MM-TT-): SAVEPOINT, Autonomie-,
  Optimierungs- und TTS-Plan, Review 02.07., ZeroClaw-Auftrag und -Ergebnis, Hermes-Setup,
  Gemini-Briefing, Antigravity-Review-Prompt, Zielbild, Uebergabe Drei Welten,
  Umbauplan Abloesung, Hermes-Werkzeuge, Raphael, die drei Dateien aus docs/aufgaben
  und der Skill-Text gitea-workflow.
- Die alte Liste OFFENE-FAEDEN (Stand 04.09.) ebenfalls ins Archiv; sie enthaelt die
  Lucy-Faeden, die sonst verloren gingen. Die neue Liste folgt im naechsten Schritt.
- Geloescht (kein eigenes Wissen, Git-Historie reicht): docs/memory/* (4 Kopien der
  Claude-Notizen vom Juni), STATUS, CUTOVER, AUDIT_KICKOFF, CLAUDE_CODE_BRIEF,
  UPGRADE und skills/orchestrator.md (Quelle war der Skill selbst).
- Formatfehler im Archiv behoben: uebrig gebliebene </content>-Tags im Optimierungsplan
  und im ZeroClaw-Auftrag; toter Link auf GEDAECHTNIS-BEREICHE.md zeigt jetzt auf die
  Git-Historie (geloescht am 07.08., c3851f8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-24 15:31:00 +02:00
co-authored by Claude Opus 5.5
parent 4cd856bd34
commit 59631601b9
30 changed files with 1 additions and 799 deletions
+149
View File
@@ -0,0 +1,149 @@
# Lucy TTS — Optimierungs- & Strategieplan
> Ziel: **Lucys Stimme läuft 100 % lokal & on-device** (kein Box-Zwang, keine Cloud).
> Primärengine: **Kyutai pocket-tts 2.1.0** (CPU). Strategische Alternative: **F5-TTS** (GPU/ONNX).
> Stand: 2026-06-30. Resume-fähig im Stil von `docs/STATUS.md`.
## Leitentscheidung: Hardware
- **pocket-tts ist CPU-gebunden** — Kyutai bestätigt: *kein* GPU-Speedup (Batch 1, 100M Params).
→ **RDNA2 vs. RDNA4 ist für pocket irrelevant.** Lucy läuft dort, wo der beste CPU steht.
- **GPU zählt nur für F5-TTS** (non-autoregressiv, große Matmuls). Dort gewinnt **RDNA4 (9070 XT) + DirectML**
deutlich gegen RDNA2 → falls F5 die Lucy-Stimme wird, läuft sie auf der RDNA4-Maschine.
- **Konsequenz:** `oute n_gpu_layers=999` und „pocket auf ROCm/Vulkan" werden **eingestellt**.
---
## Phase A — Sofort-Wins (risikoarm, pocket_server.py)
**A1 — Voice → safetensors exportieren (einmalig)**
- Statt `get_state_for_audio_prompt(ref)` bei jedem Boot: einmal `export_model_state(...)` → `lucy_voice.safetensors`.
- Server lädt beim Start nur noch die safetensors (liest kvcache, keine Klon-Rechnung) → schnellerer Start.
- Fallback behalten: wenn safetensors fehlt → aus `ref.mp3` klonen + direkt exportieren.
**A2 — Referenz säubern**
- Kyutai: Sample-Qualität wird *mitreproduziert*. Sauber entrauschte/normalisierte `ref` → weniger Artefakte.
- Schritt in `_prep_ref()` ergänzen (Denoise/Highpass/Lautheit), Ergebnis cachen.
**A3 — temp-Sweep gegen Kollaps**
- Hypothese: `temp=0.9` treibt die best-of-N-Regenerationen. Niedriger testen (0.7–0.85).
- Akzeptanz: gleiche/bessere Natürlichkeit bei **messbar weniger Regenerationen** (= weniger Latenz).
*Gate A:* A1–A3 live, Kollaps-Rate & TTFB protokolliert.
---
## Phase B — Benchmark-Harness (datenbasiert tunen)
**B1 — `bench_lucy.py`** (lokal, CPU)
- Misst je Konfig: **RTF**, **TTFB**, **Kollaps-/Regenerations-Rate**, Whisper-Rücktranskription (Verständlichkeit).
- Sweep-Achsen: `lsd_decode_steps` (6/8/10/12), `temp`, `noise_clamp`, `quantize` on/off, `frames_after_eos`.
- Feste Testsätze (kurz/mittel/lang, wie in `ptts_test.py`).
**B2 — CPU-Parallelität**
- pocket nutzt nur **2 Kerne** → mehrere **Satz-Worker parallel** statt globalem `LOCK`.
- Messen: Wall-Clock langer Antworten bei N Workern (1/2/3/4) vs. Qualität/Last.
*Gate B:* dokumentierte Best-Config (RTF + Kollaps-Rate) als neue Defaults in `pocket_server.py`.
---
## Phase C — Runtime-Eval (lokal schneller + Python-3.14-frei)
**C1 — ONNX-Pfade testen**
- Kandidaten: **PocketTTS.cpp** (Single-File C++/ONNX, CLI+HTTP+FFI) und **sherpa-onnx** (Windows, viele Bindings).
- Ziel: torch-CPU schlagen **und** das Python-3.14-Packaging-Problem umgehen.
- Vergleich gegen Phase-B-Baseline (gleicher Benchmark).
**C2 — Server-Vertrag prüfen**
- Fertige **OpenAI-kompatible Streaming-Server** (teddybear082 / ai-joe-git) gegen den aktuellen Custom-Proxy halten.
- Nur übernehmen, wenn Stimm-Wächter (F0 + Fingerabdruck) erhalten/abbildbar bleiben.
*Gate C:* Entscheidung „torch-CPU behalten" vs. „auf ONNX-Runtime wechseln" (mit Zahlen).
---
## Phase D — Strategische Weiche: pocket vs. F5
**D1 — F5 fair gegen pocket messen**
- `lucy-f5/` (F5-TTS DE, ONNX + DirectML, **RDNA4/9070 XT**) ist **non-autoregressiv → strukturell kein
Kollaps/Männerstimme/Wiederholung** (genau pockets Schmerz).
- Gleicher Benchmark wie Phase B: RTF, TTFB, Natürlichkeit, Stabilität.
**D2 — Entscheidung**
- **pocket gewinnt** (gut genug stabil, CPU, „nur lokal"-Ideal): pocket = Lucy-Stimme, F5 verworfen/geparkt.
- **F5 gewinnt** (Stabilität schlägt den Latenz-Overhead der Wächter): F5 = Lucy-Stimme auf RDNA4,
**pocket bleibt schneller CPU-Fallback** (z. B. wenn keine GPU verfügbar).
**Beobachtungsposten (extern):** distilliertes **`german`** (statt `german_24l`) ist noch nicht released
(Kyutai fixt Distillations-Datenqualität). Sobald da → größter Einzel-Win (Tempo + Stabilität),
dann `german_24l → german` swappen. Release-Feed im Blick behalten.
---
## Reihenfolge & Quick-Start
1. **A1 + A2 + A3** (heute) — sofort spürbar, kein Risiko.
2. **B1 + B2** — Zahlen sammeln, Defaults härten.
3. **C1/C2** — Runtime-Wechsel nur wenn Benchmark es trägt.
4. **D1/D2** — finale Stimm-Architektur entscheiden.
## Mess-Ergebnisse & finale Defaults (30.06., 9700X, german_24l)
Alles auf der lokalen Maschine gemessen (Logs: `sweep_b2.log`, `ttfb_test.log`, `sweep_b2_result.json`).
**B2-Sweep (6-Satz-Antwort, ~21s Audio):**
| Konfig | Wall | TTFB | RTF |
|---|---|---|---|
| seriell (1×alle Kerne) | 15,8s | **3,6s** | 0,74 |
| 2w×3t | 12,9s | 6,2s | 0,62 |
| 3w×2t | 10,3s | 6,8s | 0,50 |
| 4w×2t | 9,7s | 8,2s | **0,44** |
Erkenntnis: pocket ist **speicherbandbreiten-gebunden**. Der Pool verbessert nur die Gesamt-Wall-Clock
(Batch), verschlechtert aber die **TTFB** deutlich. Seriell liefert RTF 0,74 < 1 → generiert schneller
als Echtzeit → Streaming spielt **lückenlos** und startet am schnellsten. **Für Lucys Live-Stimme
gewinnt seriell.** Pool bleibt Opt-in für Batch (`/tts` ganze Datei): Sweet Spot **4w×2t** / **3w×2t**.
**B3 (FP-Drift-Gate überspringt kurze Audios) + kurzer erster Chunk:**
Der MFCC-Fingerabdruck ist auf <2s Audio unzuverlässig (sim ~0,84 < 0,94) → löste 3× Fehlalarm-
Regenerierung aus. B3 prüft den Drift erst ab `LUCY_FP_MIN_S=2.0`s stimmhafter Dauer; der F0-
Männerstimmen-Wächter bleibt immer aktiv. Effekt (Drift-Warnungen pro Lauf: ~6 → 1):
| | TTFB | Wall |
|---|---|---|
| kurzer 1. Chunk, ohne B3 | 4,71s | 19,9s |
| gebündelt (alt) | 3,74s | 15,8s |
| **kurzer 1. Chunk, mit B3** | **1,31s** | 16,6s |
→ Lucy spricht nach **1,3s** statt 3,7s, Wall ~gleich, weiter lückenlos.
**Finale Defaults in `pocket_server.py`:**
`LUCY_WORKERS=0` (seriell) · `LUCY_FAST_FIRST=1` (kurzer 1. Chunk) · `LUCY_FP_MIN_S=2.0` (B3) ·
`LUCY_REF_CLEAN=1` (A2) · Voice aus `lucy_voice.safetensors` (A1). Pool-Opt-in für Batch:
`LUCY_WORKERS=4 LUCY_WORKER_THREADS=2`.
**Offen / nächster Hebel:** distilliertes `german`-Modell (statt `german_24l`) abwarten — größter
Qualität/Tempo-Sprung. Optional: TTFB weiter drücken über kürzeres erstes Wort / `lsd`-Tuning nur
für den ersten Chunk.
## Umlaute (ae/oe/ue) — Fix (30.06.)
Symptom: Lucy spricht manchmal „u-e" statt „ü". Ursache: das LLM (Hermes/Qwen) gibt gelegentlich
ASCII-Ersatzschreibweisen (ueber/schoen/maerz) aus; pocket liest sie wörtlich. (ß vs ss ist
akustisch identisch -> ignoriert.)
**Wurzel-Fix (empfohlen, auf der Box im Hermes-System-Prompt/Persona ergänzen):**
> „Schreibe ausschließlich korrektes Deutsch mit echten Umlauten (ä, ö, ü) und ß. Verwende niemals
> die Ersatzschreibweisen ae, oe, ue oder ss anstelle von Umlauten."
**Schutznetz (in `pocket_server.py`, Default an `LUCY_UMLAUT_FIX=1`):** `_fix_umlauts()` wandelt NUR
bekannte deutsche Umlaut-Ganzwörter zurück (Ganzwort + gängige Flexionsendungen, case-erhaltend).
Verifiziert (`umlaut_test.py`): konvertiert über/für/größe/natürlich/mögliche/Gespräche; lässt
neue/aktuell/Steuer/Quelle/Feuer/Frauen/genau/blaue unverändert. Grenzen: reine Wortliste, deckt
nicht jedes seltene Wort — erweiterbar via `LUCY_UMLAUT_EXTRA="wort1,wort2"`. Der Wurzel-Fix bleibt
die zuverlässige Lösung.
## Referenzen
- pocket-tts README (GPU-kein-Speedup, export-voice, Sprachen): github.com/kyutai-labs/pocket-tts
- Multilingual-Ankündigung (DE = `german_24l`, undistilliert): kyutai.org/blog/2026-05-04-pocket-tts-multilingual
- Tech-Report / Performance: kyutai.org/blog/2026-01-13-pocket-tts · deepwiki.com/kyutai-labs/pocket-tts
+299
View File
@@ -0,0 +1,299 @@
# Optimierungsplan MC2 — Rollen, Warm-Set & Durchsatz (Strix Halo)
> Audit-Ergebnis + Maßnahmenplan. **Erst Plan, dann Umsetzung nach Freigabe.** Alles reversibel
> (Config-Backups vor jeder Box-Änderung). Stand: 2026-06-30.
> Quellen: Code-Audit (`backend/`, `frontend/`) + **Live-Box-Verifikation per SSH** (`/running`, voller
> `config.yaml`, `free`, `du`, t/s-Probe) + `docs/AUDIT_KICKOFF.md` / `CLAUDE_CODE_BRIEF_lucy-brain-role.md`.
---
## 0. TL;DR (Priorität nach echtem Impact)
1. **✅ ERLEDIGT — Warm-Set korrigiert (W1/W2, 2026-06-30, live verifiziert):** `brains` jetzt = **gemma +
embedding + vision** (`swap:false, persist:true`, ~31 GB). **Wichtige Korrektur durch Live-Test:** das
ursprünglich vermutete OOM-Risiko existiert NICHT — llama-swap **swappt ganze Gruppen** statt sie zu
ko-laden (cross-group Load = Gruppe raus, neues Modell rein; kein Speicher-Überlauf). Der echte Punkt war
ein anderer: vorher pinnte `brains` auch `fast` (Chat-Lane-Hirn, kein Nutzen für Lucy → ~28 GB verschenkt),
und in der reinen `gemma+embed`-Variante hätte **Lucys Sehen ihr Hirn verdrängt**. Jetzt halten Hirn +
Gedächtnis + Sehen zusammen warm (verifiziert: gemma & vision ko-resident, 37 GB, kein Evict). **Reversibel.**
2. **MTP-Spec-Decoding für gemma:** 53 t/s → erwartet ~80–100 t/s (1,5–2×, 0 Qualitätsverlust). Drafter-GGUF
fehlt auf der Box **und MC2 kennt MTP-Drafter gar nicht** (nur klassisches `draft-simple`). **[mittel]**
3. **coder-Spec-Draft verifizieren:** `coder` (Qwen3-Coder-Next) hat `--spec-draft-model Qwen3-0.6B-Q8_0
--spec-type draft-simple` **aktiv** — ist dieser Draft wirklich vocab-kompatibel zu Qwen3-Coder-Next?
Wenn nein, bremst/bricht Spec still. **[Check]**
4. **Neues `scout`-Modell** (multimodaler Allrounder, Tools): HF-verifizierter Primärpick **GLM-4.6V-Flash (9B)**
— Q4 ~6 GB + mmproj, natives Tool-Calling, schlägt unser vision-Modell. Alt: Gemma-4-12B. (Qwen3.5-VL-MoE
verworfen — kein gepflegtes GGUF.) **[Recherche/Download]**
5. **gemma-ctx 128k → 64k:** *kleiner* Hebel (real nur ~2 GB, weil Gemmas KV winzig ist — s. §1.4),
trotzdem sinnvoll (freigegeben). Kein Funktions-Risiko für agentische Turns. **[risikoarm]**
---
## 1. IST-Zustand (live verifiziert per SSH, 2026-06-30)
### 1.1 Rollen-Taxonomie — Code ist konsistent ✅
Der Brain-Rolle-Umbau aus `CLAUDE_CODE_BRIEF_lucy-brain-role.md` ist **bereits umgesetzt** (Commit `dd99401`).
`hermes` (= Lucys Hirn) ist als kanonische Rolle in ALLEN Quellen synchron: `llamaswap.ROLE_IDS`,
`sources.ROLE_IDS`+`CATEGORIES`, `roles.py` (`_capability_suit`/`_pref`/`_reason`), Frontend `ModelBadges.ROLES`.
Die „hermes-Altlast/Inkonsistenz" aus dem Brief existiert nicht mehr.
### 1.2 Brain-Warm-Flow — Code ist fertig ✅, Box bestätigt ✅
`POST /api/models/{id}/role role=hermes` → `agent.set_agent_brain()`: Alias + `brains:{swap:false,persist:true}`
+ ttl 0 (altes Hirn raus/entspannt) + Hermes `model.default` + Gateway-Restart + Budget-Warnung. `brain_status()`
prüft per `/running`.
**Box bestätigt das Akzeptanzkriterium:** `gemma-4-26B-A4B-it` ist `ready`, `ttl:0`, Alias `hermes`, und in
`groups.brains` (`swap:false, persist:true`). **Lucy bleibt warm — kein Kalt-Nachladen.** ✅
### 1.3 Live-Config aller Rollen (`/etc/llama-swap/config.yaml`, `globalTTL: 0`)
| Rolle (alias) | Modell | Gewichte (du) | ctx | ttl | Besonderheiten |
|---|---|---|---|---|---|
| fast | Qwen3.6-35B-A3B | 22 GB | 65536 | 0 | `--parallel 2`, mmproj, `--cache-reuse 256 -cram 16384`, **kein Spec**, **in `brains`** |
| heavy | Qwen3.5-122B-A10B | 73 GB | 32768 | 600 | split-GGUF, `--cache-reuse 256 -cram 16384`, kein Spec |
| coder | Qwen3-Coder-Next | 46 GB | 131072 | 600 | `--parallel 2`, **Spec aktiv** (Qwen3-0.6B-Q8 / draft-simple) |
| coder-lite | Qwen3-Coder-30B-A3B | 18 GB | 131072 | 300 | `--cache-reuse 256 -cram 16384` |
| vision | Qwen3-VL-8B-Instruct | 6 GB | 32768 | 300 | mmproj, **in `brains` (gepinnt!)** |
| embed | Qwen3-Embedding-0.6B | 1 GB | 8192 | 0 | `--embedding --pooling last`, **in `brains`** |
| **hermes** (Hirn) | **gemma-4-26B-A4B-it** | 17 GB (+1,2 mmproj) | **131072** | 0 | mmproj, `--jinja`, **kein Spec**, **in `brains`** |
`groups.brains = {swap:false, persist:true, members:[embedding, vision, fast, gemma]}`.
### 1.4 Speicher-Realität (GTT = 124 GB, `amdgpu.gttsize=126976`)
**Wichtige Korrektur ggü. der reinen `fit.py`-Schätzung:** mit NUR gemma@131072 geladen meldet die Box
**25,9 GB used** → gemma resident ≈ **~22 GB** (≈17 Gewichte + 1,2 mmproj + nur **~4 GB KV**). Gemma-4 nutzt
starke Sliding-Window-Attention → KV ist viel kleiner, als `fit.py` (kalibriert an Hermes-14B) vorhersagt.
**Folge:** gemma-ctx-Reduktion spart real nur ~2 GB; der echte Druck kommt vom **Warm-Set**, nicht vom Hirn-ctx.
**llama-swap-Gruppen-Semantik (live verifiziert, korrigiert frühere Annahme):** Eine `swap:false`-Gruppe hält
NUR ihre EIGENEN Member ko-resident. Ein Modell in einer ANDEREN Gruppe (heavy/coder = je eigene implizite
Gruppe) zu laden **swappt die gesamte aktive Gruppe raus** und lädt das neue Modell allein. `persist:true`
verhindert nur das Idle-TTL-Entladen, NICHT das Gruppen-Swapping. **Folge:** es gibt **kein** OOM durch
Ko-Laden (heavy lädt allein, 79 GB < 124 ✓) — aber das Hirn ist bei cross-group Loads (heavy/coder) **nicht**
geschützt: es wird mitgeswappt und lädt danach kalt nach (~Sekunden). Beweis: heavy laden → `/running` zeigte
nur heavy (78,7 GB), gemma weg trotz persist.
**Konsequenz fürs Design (umgesetzt):** Lucys zusammengehöriges Set (Hirn + Gedächtnis + Sehen) MUSS in DERSELBEN
`swap:false`-Gruppe stehen, sonst verdrängt schon Lucys eigenes Sehen ihr Hirn. → `brains = gemma + embed +
vision` (~31 GB). heavy/coder/coder-lite/fast = on-demand (swappen die brains-Gruppe beim Laden raus — ok, das
sind separate Aktivitäten IDE/Delegation; Lucy lädt danach kurz nach).
### 1.5 Durchsatz (live gemessen)
gemma (Hirn): **~53 t/s** Generierung, ~173 t/s Prompt (warm, kurzer Prompt). Solide Basis für ein 26B-A4B
(4B aktiv) auf der bandbreitenlimitierten APU; MTP-Ziel ~80–100 t/s.
---
## 2. Verifikations-Status (war §2 „offen" — jetzt aufgelöst)
- **V1 (gemma in `brains:{swap:false}`?)** → **JA** ✅ (Akzeptanzkriterium erfüllt).
- **V2 (t/s)** → gemma 53 t/s gemessen ✅. fast/heavy/coder noch nicht gemessen (Laden würde Warm-Set stören).
- **V3 (Voll-Config)** → komplett gelesen (§1.3) ✅.
- **V4 (GTT/Belegung)** → GTT 124 GB, gemma-only 25,9 GB used ✅. Cross-group-Load swappt Gruppen (kein OOM,
aber Hirn ungeschützt) — live verifiziert (§1.4). Behoben durch W1/W2.
- **V5 (coder-Spec-Draft)** → **AUFGELÖST ✅**: Qwen3-0.6B-Q8 ↔ Qwen3-Coder-Next = gleicher `tokens_sha
facf459…`, n_vocab 151936, `compatible: True`. coder-Spec ist gültig & aktiv. (Bonus-Opportunität §9.2 F4.)
---
## 3. Maßnahmen je Rolle
### 3.1 ✅ Warm-Set / KO-Residenz — ERLEDIGT (2026-06-30, live verifiziert)
| # | Maßnahme | Status / Begründung |
|---|---|---|
| W1/W2 | **`brains:{swap:false,persist:true}` = gemma + embedding + vision** (~31 GB); fast raus (Chat-Lane-Hirn, kein Lucy-Nutzen, ~28 GB gespart) | ✅ angewendet via `PUT /api/groups` (Backup `config.yaml.bak-20260630-152911`). **Verifiziert:** gemma & vision ko-resident, kein Evict (37 GB used); gemma bleibt `ready`. |
| — | heavy/coder/coder-lite/fast = on-demand | Korrekt: kein OOM (Gruppen-Swap), Lucys Set bleibt zusammen warm. Trade-off: nach heavy-Delegation / IDE-Coding lädt Lucy kurz nach (~s). |
| Optional | fast wieder pinnen, falls Chat-Lane dauerwarm sein soll | +28 GB Pin, swappt aber bei jedem heavy/coder-Load eh raus → geringer Nutzen. Auf Wunsch nachrüstbar. |
### 3.2 `hermes` / Lucys Hirn — gemma-4-26B-A4B-it
| # | Maßnahme | Begründung / Zahlen | Risiko | Revert |
|---|---|---|---|---|
| H1 | **ctx 131072 → 65536** | Spart real nur ~2 GB (Gemma-KV winzig), aber konsistent mit `fast` ([[hermes-fast-context-blocker]]) und Agent-Turns brauchen selten >64k. | niedrig | ctx zurück |
| H2 | **MTP-Spec-Decoding** (s. §4) | 53 → ~80–100 t/s. Drafter ~0,4 B → Budget vernachlässigbar. | mittel | Spec-Flags raus |
| H3 | gemma sollte ggf. `--cache-reuse 256` bekommen (wie fast/heavy/coder) — fehlt aktuell | KV-Reuse über Turns → weniger Prompt-Reprocessing bei Agent-Ketten. | niedrig | Flag raus |
### 3.3 `fast` — Qwen3.6-35B-A3B (chat-Lane)
- ctx 65536, `--parallel 2`, **kein Spec** (gut — vermeidet den qwen2.5-Vocab-Bruch). **Belassen**, aber W2 (raus
aus dem harten Pin). Optional Qwen-Spec-Draft nur, wenn vocab-kompatibel zu Qwen3.6 (Check via `gguf_meta`).
### 3.4 `heavy` — Qwen3.5-122B-A10B
- 73 GB, ctx 32768, ttl 600, on-demand. **Belassen.** Profitiert direkt von W1/W2 (kann wieder laden). Kein Spec
(kein etablierter kompatibler Qwen3.5-Draft) — erst prüfen, sonst lassen.
### 3.5 `coder` / `coder-lite`
- **coder** (Qwen3-Coder-Next, 46 GB, ctx 131072): **Spec aktiv mit Qwen3-0.6B-Q8** → **V5: Vocab-Kompatibilität
verifizieren.** Falls inkompatibel → Draft entfernen (still kein Speed-Gewinn, evtl. Fehlerquelle).
- **coder-lite** (Qwen3-Coder-30B-A3B, 18 GB, ctx 131072): coding-Lane-Default, schnell (3B aktiv). **Belassen.**
Hinweis: Alias heißt `coder-lite` (Bindestrich) — die Lanes referenzieren `coder_lite`; sicherstellen, dass das
Routing (`router_logic.py`/`routing_policy.py`) auf den richtigen Alias zeigt (Konsistenz-Check, kein Box-Risiko).
### 3.6 `vision` — Qwen3-VL-8B-Instruct
- 6 GB, ctx 32768. **Belassen**, aber W2 (verdrängbar statt hart gepinnt). Sehen ist bursty → on-demand/warm-soft reicht.
### 3.7 `embed` — Qwen3-Embedding-0.6B
- 1 GB, ttl 0, **bleibt hart gepinnt** (W1). Unantastbar — Mem0/Gedächtnis hängt dran.
### 3.8 `scout` — VAKANT → §5
---
## 4. MTP-Speculative-Decoding für gemma (Backend+UI-Erweiterung)
**Problem:** MC2 kennt nur **klassische** Drafts. `spec_draft_flags()` schreibt `--spec-draft-model <d>
--spec-type draft-simple`; `find_compatible_draft()` scannt nur `DRAFTS_DIR` mit stumpfem
`gguf_meta.compatible()`. Ein **MTP-Kopf** (`gemma-4-26B-A4B-it-assistant`, Arch `gemma4_assistant`) wird nie
angeboten. Engine 9843 kann `--spec-type draft-mtp` ✓; alte `--draft-max/-min` sind **entfernt** →
`--spec-draft-n-max/-n-min`.
**Schritte:**
1. **Drafter beschaffen** (Box, fehlt noch) — ⚠️ **Brief-Korrektur (HF-verifiziert 2026-06-30):** der Drafter
heißt NICHT `…-assistant`. In `unsloth/gemma-4-26B-A4B-it-GGUF` liegt er als **`mtp-gemma-4-26B-A4B-it.gguf`**
(Repo-Root, **0,46 GB**) bzw. **`MTP/gemma-4-26B-A4B-it-Q8_0-MTP.gguf`** (0,46 GB; BF16/F16-Varianten 0,86 GB).
Eine Datei nach `/srv/models/gemma-4-26B-A4B-it-GGUF/` laden (Q8-MTP = kleinste, ~0,46 GB).
**Flags (laut unsloth MTP/README):** `--model-draft <mtp.gguf> --spec-type draft-mtp --spec-draft-n-max 4`
(kein `--spec-draft-n-min` nötig; neuere llama.cpp **auto-entdeckt** die Root-`mtp-*.gguf`). `-md` = Kurzform.
2. **Backend (`llamaswap.py`):** MTP-Pfad ergänzen — MTP-Drafter als gültigen, vocab-kompatiblen Draft erkennen
(Arch/Name `*-assistant*`); beim Aktivieren `-md <assistant.gguf> --spec-type draft-mtp
--spec-draft-n-max N --spec-draft-n-min M` schreiben (statt `--spec-draft-model`/`draft-simple`). `_parse_model`
um `draft-mtp`/`-md` erweitern (UI-Status). Flag-Namen mit `llama-server --help` (9843) gegenprüfen.
3. **Frontend:** Draft-Modal MTP-Drafter als empfohlene Option für gemma führen („MTP-Kopf, vocab-kompatibel ✓").
4. **Verifizieren:** t/s vor/nach (Basis 53 t/s) gegen die Box.
> Risiko mittel (neue Flag-Logik); voll reversibel.
---
## 5. Neues `scout`-Modell (Empfehlung)
Profil: multimodaler Allrounder, klein/MoE (schnell auf bandbreitenlimitierter Box), Tool-Calling,
KO-Residenz-freundlich, **distinkt** von Hirn (gemma-4) und vision (Qwen3-VL-8B).
**HF-verifiziert 2026-06-30** (Verfügbarkeit + Dateigrößen real geprüft, nicht geraten):
| Pick | Modell | Verifizierte Fakten | Hinweis |
|---|---|---|---|
| **Primär** | **GLM-4.6V-Flash (9B)** | GGUF da: `unsloth/GLM-4.6V-Flash-GGUF` (29 Quants, 12k+ dl), `lmstudio-community`, `MaziyarPanahi`. **Q4_K_M = 6,17 GB + mmproj 1,84 GB ≈ 8 GB.** Natives multimodales Function-Calling, 128k ctx. Benchmarks: **schlägt Qwen3-VL-8B** (= unser aktuelles vision-Modell) in fast allen Kategorien. | **9B dense** (nicht MoE), aber bei 9B/6 GB trotzdem schnell. **on-demand** (nicht pinnen). Könnte perspektivisch sogar `vision` ablösen. |
| Alt A | **Gemma-4-12B-it (dense, multimodal)** | GGUF breit verfügbar: `unsloth/gemma-4-12b-it-GGUF` (1,4 Mio dl), `google/…-qat`, `lmstudio`. | dense → auf Bandbreiten-Box etwas langsamer; Familien-Dopplung mit dem Hirn (auch Gemma-4). |
| ~~Alt B~~ | ~~Qwen3.5-VL-MoE~~ | **VERWORFEN:** kein gut gepflegtes GGUF — nur EIN Nischen-Repo (`jc-builds/Qwen3.5-9B-VLM-Q4_K_M`, kein Trusted-Author). Meine frühere „familien-treu"-Empfehlung war ungedeckt. | nicht nehmen. |
**Vorgehen:** GLM-4.6V-Flash (Q4_K_M ~6 GB + mmproj) via „Modelle finden"/`/api/models/install` laden → Rolle
`scout`, **on-demand** → Mini-Benchmark (t/s + Vision+Tool-Prompt). Quellen (tagesaktuell, 2026-06):
[VentureBeat: GLM-4.6V native tool-calling](https://venturebeat.com/ai/z-ai-debuts-open-source-glm-4-6v-a-native-tool-calling-vision-model-for) ·
[zai-org/GLM-4.6V-Flash (HF)](https://huggingface.co/zai-org/GLM-4.6V-Flash) ·
[GLM-4.6V Flash 9B Review/Benchmarks](https://binaryverseai.com/glm-4-6v-review-benchmarks-pricing-local-install/) ·
[SiliconFlow: schnellste OSS-Multimodal 2026](https://www.siliconflow.com/articles/en/fastest-open-source-multimodal-models).
---
## 6. KO-Residenz-Set (umgesetzt, live verifiziert)
**Lucys Warm-Set (`brains:{swap:false,persist:true}`):** gemma-Hirn + embedding + vision = **~31 GB.**
Diese drei MÜSSEN zusammen in einer Gruppe sein (sonst verdrängt Lucys Sehen ihr eigenes Hirn — Gruppen-Swap).
**Rein on-demand (swappen die brains-Gruppe beim Laden raus):** fast, heavy, coder, coder-lite, scout.
**Verifiziert:** gemma+vision ko-resident (37 GB, kein Evict); heavy-Load swappt die Gruppe (kein OOM, 79 GB).
**Hinweis `budget.reserved_gb`:** das Modul nimmt an, fast/vision seien verdrängbar persist-Member, die NEBEN
dem Hirn warm bleiben. Real swappt llama-swap aber die ganze Gruppe → die `reserved_gb`-Mathematik ist für
cross-group-Loads **zu konservativ** (rechnet Hirn+Rest gleichzeitig, was nie passiert). **Folge-Task (Code):**
`budget.reserved_gb` an die echte Gruppen-Swap-Semantik angleichen (nur das brains-Set zählt als resident,
on-demand-Modelle laufen allein). Kein Box-Risiko, nur genauere ctx-Empfehlungen.
---
## 7. Reihenfolge / Risiko / Revert
| Schritt | Aktion | Risiko | Revert |
|---|---|---|---|
| 0 | ✅ **Box-Backup** `config.yaml.bak-20260630-152911` | – | – |
| 1 | ✅ **W1+W2** brains = gemma+embed+vision (via `PUT /api/groups`), verifiziert | niedrig | `set_group` zurück |
| 2 | **H1** gemma ctx → 65536; **H3** `--cache-reuse 256` ergänzen | niedrig | ctx/Flag zurück |
| 3 | **V5** coder-Draft-Vocab prüfen; inaktive Spec entfernen | niedrig | – |
| 4 | **§4** MTP: Drafter laden → Backend/UI-Erweiterung → gemma-cmd → t/s-Vergleich | mittel | Spec-Flags raus |
| 5 | **§5** scout recherchieren/installieren/zuweisen (on-demand) | niedrig | Modell löschen |
---
## 8. Offene Entscheidungen (für dich)
1. **Warm-Set-Fix (W1/W2) jetzt umsetzen?** — behebt die heavy-OOM-Gefahr, mein klare Empfehlung als Erstes.
2. **fast/vision verdrängbar** via eigener Gruppe `swap:true` (sie swappen sich gegenseitig) **oder** schlicht
`persist:false`? (Detail des Umbaus.)
3. **MTP jetzt oder als eigener Block?** (Code-Erweiterung Backend+UI + Drafter-Download.)
4. **scout-Pick:** GLM-4.6V (Primär) oder familien-treu Qwen3.5-VL-MoE?
5. gemma-ctx **65536** ist gesetzt (deine Wahl) — ok so.
---
## 9. Gesamtbild: Engine- (llama.cpp) & Router- (llama-swap) Flags — verifiziert gegen Build 9843
> Der Brief deckte das nicht ab. Alle Aussagen hier gegen `llama-server --help` (9843) + Live-Config geprüft.
### 9.1 Cross-cutting (alle Chat-Modelle): `-ngl 999 -fa 1 --no-mmap -c <ctx> --jinja`
- `-ngl 999` ✅ korrekt (volle Offload-Last in GTT auf der APU).
- `-fa 1` → funktioniert, ist aber **Legacy-Form**. Aktuell: `-fa [on|off|auto]` (Default `auto`). Auf `-fa on`
normalisieren (oder weglassen → auto), sonst Risiko bei künftigem Build. **[niedrig]**
- `--no-mmap` ✅ bewusst (volle RAM-Residenz statt file-backed Pages; sinnvoll für warm gehaltene Modelle auf
Unified Memory). Behalten.
### 9.2 Pro-Modell-Befunde & Hebel
| # | Befund | Hebel | Prio |
|---|---|---|---|
| F1 | **gemma (Hirn) fehlt `--cache-reuse 256 -cram 16384`** — der Agent macht die meiste Multi-Turn-/Tool-Arbeit, nutzt aber nur den 8 GB-Default-Cache & **kein KV-Reuse über Turns** | ergänzen → System-Prompt + History-KV werden wiederverwendet, weniger Prompt-Reprocessing, schnellere Folge-Antworten | **hoch (Quick-Win)** |
| F2 | **`--parallel 2` (fast/coder) ↔ Kontext:** unified KV ist „enabled if slots **auto**" — mit explizitem `--parallel 2` evtl. AUS → harte ctx-Teilung (fast 32k/Anfrage, coder 65k/Anfrage). `-cram` SOLL unified erzwingen, Help mehrdeutig | **V6:** `n_ctx_per_seq` aus `/props` verifizieren (beim nächsten Load). Dann: `--parallel 1`/auto (volle ctx, wenn keine Nebenläufigkeit) **oder** explizit `-kvu` setzen | mittel |
| F3 | **KV-Quant `-ctk q8_0 -ctv q8_0`** — getestet an coder-lite | **EVALUIERT → VERWORFEN (2026-06-30):** kein Speicherdruck (Coder laufen allein, voller GTT), bei kurzem Kontext leichter Overhead (91→88 t/s), kein messbarer Gewinn. Voller-Präzisions-KV = beste Code-Treue. | erledigt |
| F4 | **coder-Spec** (Coder-Next) ✅ kompatibel & behalten. Draft auch zu coder-lite kompatibel; heavy INKOMPATIBEL (V7) | **coder-lite + Spec EVALUIERT → VERWORFEN:** 91→**69 t/s (−24 %!)** — Spec schadet dem schnellen 3B-MoE (Draft-Overhead > Gewinn, 54 % Akzeptanz). Bestätigt: Spec nur für große/dichte Modelle (coder), nicht für MoE (fast/coder-lite). heavy kann mangels Vocab-Match ohnehin nicht. | erledigt |
| F5 | **fast trägt `--mmproj`** (ist vision-fähig) — bewusst? +~1 GB | wenn die Chat-Lane nie Bilder bekommt: mmproj sparen | niedrig |
| F6 | `-b/-ub` (batch/ubatch), `-t` (threads) ungenutzt = Defaults | Prompt-Speed evtl. via `-ub` tunbar — **messen statt raten**, niedrige Prio | niedrig |
### 9.3 llama-swap (Router-Ebene)
- `globalTTL: 0` ✅ ok (Modelle haben überwiegend explizite ttl). `healthCheckTimeout: 300` ✅ reicht auch für
heavy (~60 s Load gemessen). Gruppen-Swap-Semantik verstanden (§1.4), brains gefixt (§3.1).
- **Systemischer Befund (Code↔Box-Drift):** MC2 `config._DEFAULT_CMD_TEMPLATE` =
`llama-server -m {model} --host … --port ${PORT} -c {ctx} -ngl 999 -fa 1 --no-mmap` — kennt **KEINE** der auf
der Box manuell ergänzten Optimierungen (`--cache-reuse`, `-cram`, `--parallel`, KV-Quant). **Folge: neu über
MC2 installierte Modelle bekommen diese Tunings NICHT automatisch** → die Box driftet von der Code-Quelle weg.
**Fix (Code):** sinnvolle Defaults ins Template / `register_model` (rollenabhängig), damit „Modelle finden"
schon optimiert registriert. Optional: llama-swap `macros` für wiederholte Flag-Blöcke (Wartbarkeit). **[mittel]**
### 9.4 Verifikationspunkte — aufgelöst (2026-06-30)
- **V6 ✅:** fast-Upstream `/props`: `total_slots:2`, **per-slot n_ctx 32768** → `--parallel 2` teilt den Kontext
HART (kein unified-Sharing trotz `-cram`). **Maßnahme F2 angewendet:** fast → `--parallel 1` = **per-slot
n_ctx 65536** (verifiziert). coder bleibt `--parallel 2` (IDE-Concurrency, 65k/Req).
- **V7 ✅:** Qwen3-0.6B-Draft (`tokens_sha facf459`) → **heavy INKOMPATIBEL** (`a5e1ccff`, kein Spec möglich),
**coder-lite KOMPATIBEL** (gleiche sha; aber MoE 3B-aktiv → Spec-Gewinn gering, vor Aktivierung benchmarken).
### Umsetzungs-Log (Box, 2026-06-30, Backups vorhanden)
- ✅ **W1/W2** brains = gemma+embed+vision (`config.yaml.bak-20260630-152911`).
- ✅ **gemma F1+H1+fa-on**: ctx 131072→65536, `-fa 1`→`-fa on`, `+ --cache-reuse 256 -cram 16384`
(`bak-20260630-154842`). Verifiziert: ready, ~52 t/s, 24,4 GB.
- ✅ **F2** fast `--parallel 2`→`1` (voller 65k-Kontext, verifiziert).
- ✅ **MTP für gemma** (`bak-20260630-155520`): Drafter `mtp-gemma-4-26B-A4B-it.gguf` (461 MB) geladen,
cmd `+ --model-draft … --spec-type draft-mtp --spec-draft-n-max 4`. **Verifiziert: 52 → 70,8 t/s (≈1,36×)**,
Draft-Akzeptanz ~50 %, kein Crash, ready.
- ✅ **scout** GLM-4.6V-Flash installiert (Q4 6,17 GB + mmproj 1,84 GB), role=scout, ttl 300, on-demand.
**Voll verifiziert:** lädt sauber (neue GLM-4.6V-Arch auf Engine 9843), 34,6 t/s; **Vision ✓** (Testbild
„blauer Kreis + Zahl 42" → korrekt erkannt: „Form: Kreis, Farbe: blau, Zahl: 42"); reasoniert korrekt.
**Thinking-Modell** → No-Think für schnelle Kurzantworten via `chat_template_kwargs:{enable_thinking:false}`
ODER `/nothink` im Prompt (beide verifiziert: sofort „Tokio" ohne Reasoning).
### Code-Änderungen (Dev-Repo F:\, **noch nicht deployt**)
- ✅ **MC2 MTP-Draft-Support** (Brief-Deliverable). Verifiziert: py_compile OK, Logik-Test gegen echte GGUF,
Frontend `tsc --noEmit` exit 0.
- `config.py`: `SPEC_DRAFT_N_MAX` (Default 4).
- `services/llamaswap.py`: `_is_mtp_draft`, `_spec_flags_for_draft`, `_sibling_mtp_drafters` (findet MTP-Köpfe
NEBEN dem Modell); `find_compatible_draft`/`spec_draft_flags`/`drafts_for`/`set_spec_draft` MTP-bewusst;
`_parse_model` erkennt `--model-draft`/`-md`. Backward-kompatibel (klassische Drafts unverändert).
- Frontend `api.ts` (`DraftInfo.mtp`), `SpecDraftModal.tsx` (MTP-Badge). → gemmas MTP-Drafter erscheint im
Spec-Modal automatisch als kompatibel + aktivierbar, schreibt die korrekten `draft-mtp`-Flags.
- ✅ **CMD-Template-Drift** (`register_model`): `--cache-reuse 256 -cram 16384` als Default für alle
Template-Modelle; `--parallel 2` nur noch für `coder` (kein ctx-Halbierungs-Footgun mehr); Spec-Auto-Attach
MTP-bewusst + für alle Rollen self-guarding. Verifiziert: py_compile OK.
- ✅ **`budget.reserved_gb`** an Gruppen-Swap-Semantik angeglichen (`_coresident_members` = `swap:false`-Set;
on-demand = läuft allein → reserviert 0, voller GTT; brains-Member = reserviert die übrigen Member).
Verifiziert gegen echte Config: hermes→16,2 GB, heavy/coder/scout→0 GB (ondemand-alone). Tote
`_persist_members` entfernt.
- ✅ **DEPLOYT (2026-06-30):** Commits `f655f09` (Code) + `9842249` (Frontend-`dist`) auf main; Box `git pull`
→ `restart mission-control-2`. Verifiziert: `/api/models/drafts` zeigt MTP-Draft (`mtp:true, compatible:true`),
gemma-Parse `spec_active:true spec_type:draft-mtp`, FastAPI serviert neues dist, API 200, gemma warm.
(Box-`config.yaml`-Tunings waren schon vorher live.)
---
## 10. Leitplanken (eingehalten)
- Features (Sehen/Hören/Sprechen/Embedding/Gedächtnis) + IDE-Lanes (chat/coding) bleiben funktionsfähig —
W1/W2 macht sie sogar robuster (kein OOM mehr).
- Vor jeder Box-Config-Änderung Backup; llama-swap reloadt per `-watch-config`.
- **Keine destruktiven Aktionen ohne Freigabe dieses Plans.**
@@ -0,0 +1,82 @@
# Brief: ZeroClaw-PoC als Lucys schlanker Agent-Runtime (Latenz-Fix an der Wurzel)
> Für eine **frische Claude-Code-Session**. Aufgabe: ZeroClaw (ultraleichter Rust-Agent) als
> risikoarmen Proof-of-Concept neben Hermes aufsetzen und gegen Hermes benchmarken (Prompt-Größe +
> Latenz). Hermes bleibt **unangetastet** parallel laufen — null Risiko für die laufende Lucy.
## Warum (die ganze Vorgeschichte in Kürze)
Lucy (Hermes-Agent, Hirn = gemma-4-26B-A4B) braucht **ewig** zum Antworten (Output top, aber 20–80 s/Turn).
Eine sehr lange Latenz-Jagd (2026-06-30) hat die Ursachen **definitiv** geklärt:
1. **mem0 nutzte `fast` (Qwen) als LLM** (`MEM0_LLM_MODEL=fast`) — das war noch von früher, als `fast` Lucys
Hirn WAR. Nach dem Umzug auf gemma blieb mem0 auf fast → jede Erinnerungs-Op lud fast → **verdrängte
gemmas Warm-Gruppe** → gemma-KV-Cache tot → 40 s Re-Prefill. (Halb-fertige Hirn-Migration.)
2. **gemma ist architektonisch langsam auf Vulkan/Strix-Halo.** Verifiziert am Box-GGUF:
`attention.key/value_length = 512` (head_dim 512!) vs. Qwen3.6 **256**, plus mixed sliding/full
attention → Flash-Attention auf RADV ineffizient → langsamer **Prefill** + **CPU-Spike** (teils
CPU-Fallback). gemma-GENERIERUNG ist ok (~93 t/s), gecachter Prompt **0,3 s** — nur **Cache-Misses**
(Prefill, ~11–27 s) sind tödlich.
3. **gemmas Thinking ist per Default AN** (~90 Extra-Tokens/Antwort). Abschaltbar NUR via
`chat_template_kwargs:{enable_thinking:false}` (verifiziert; `/no_think` & `reasoning_effort` wirken nicht).
4. **Hermes selbst ist Schwergewicht** — DER eigentliche Overhead: 20k-Token-Prompt = **79 Tool-Schemas**
(~17,5k) + **Skills-Manifest** (27 Skills, ~8,7k) + **3-Schichten-Memory mit Auto-Injektion**. Die
Auto-Injektion **variiert den Prompt jeden Turn** → bricht gemmas Cache → Re-Prefill.
**Verdikt:** Auch nach JEDEM Fix (Eviction behoben: mem0/aux→fast + fast ko-resident; Slot geschützt;
Thinking aus; Auto-Injektion aus; RADV ✓; FA ✓; single-slot cache-reuse) blieb gemma **6–80 s,
unzuverlässig** — der Prozess lief stabil (kein Crash/Eviction), aber gemmas Prefill kommt mit Hermes'
pro-Turn-wechselndem 20k-Prompt nicht klar. **gemma ist auf dieser HW+Agent fundamental ungeeignet für
verlässlich niedrige Latenz.** Einziger gemma-Vorteil: **deutlich besseres Deutsch** (Qwen leakt englische
Wörter, z.B. „biggest"; gemma = natürlich + echte Umlaute).
## Die These des PoC
**Hermes' Schwergewicht (Skills + ChromaDB + Auto-Injektion) baut den fetten, instabilen Prompt.**
Ein schlanker Agent (**ZeroClaw**: 3,4 MB Rust, SQLite-Memory statt ChromaDB, minimaler Overhead, „ruthless
about cutting") würde einen **kleinen, STABILEN** Prompt bauen → gemmas langsamer Prefill hat kaum was zu
kauen → **Lucy schnell mit gemma UND Qwen** → gemmas Deutsch gerettet + Lucy entschlackt. Wurzel-Fix statt
Modell-Pflaster.
## PoC-Aufgabe (risikoarm, Hermes bleibt parallel)
1. **ZeroClaw** auf die Box holen (Rust-Binary; Repos: github.com/zeroclaw-labs/zeroclaw bzw.
github.com/elev8tion/zeroclaw — beides prüfen, das gepflegtere/passende nehmen). Eigener Port, **NICHT**
:8642 (Hermes) anfassen.
2. **An euer MC2-Gateway** hängen (OpenAI-kompatibel, `http://127.0.0.1:9001/v1`). Erst mit Modell `fast`
(Qwen, schnell) testen, dann `hermes` (gemma) für den Deutsch-Vergleich.
3. **Nur Kern-Tools** zuerst: Memory (ZeroClaw-eigenes SQLite ODER per MCP an mc2-memory) + 1–2 Stack-Tools.
Eure bestehenden MCP-Server (`hermes-pc-control`, `mission-control-stack`, `mission-control-memory`,
`hermes-web-fetch`) kann ZeroClaw als MCP-Client mitnutzen.
4. **Benchmark gegen Hermes (Zahlen, nicht Gefühl):**
- **Prompt-Größe** (prompt_tokens) eines simplen Turns: ZeroClaw vs. Hermes (Hermes ≈ 20.000).
- **Latenz** mehrerer Folge-Turns (Cache-Verhalten): wird der Prompt klein+stabil → cached gemma → schnell?
- Messmethode wie in der Saga: `curl` an den Agent + `/v1/chat/completions`-`usage.prompt_tokens` +
llama-swap-POST-Dauer (`journalctl -u llama-swap`).
5. **Entscheidung:** Wird Lucy mit ZeroClaw schnell (idealerweise mit gemma) → voller Umzug planen
(Persona, Memory-Migration mem0/Chroma→SQLite, MCP-Tools, Telegram/Voice). Wenn nicht → **Fallback:
Lucys Hirn auf Qwen3.6-35B-A3B** (schnell+verlässlich) + harte Deutsch-Direktive im System-Prompt.
## Box-Fakten (für den PoC)
- **Box:** `ssh hitonabi@192.168.178.151` (key-based). Strix Halo, 122 GB, GTT ~124 GB, Vulkan/RADV.
- **MC2-Gateway:** `:9001/v1` (OpenAI-kompat). Aliase: `hermes`→gemma-4-26B (Lucys Hirn), `fast`→Qwen3.6-35B,
`heavy`→Qwen3.5-122B, `coder`/`coder-lite`, `vision`→Qwen3-VL-8B, `embed`→Qwen3-Embedding.
- **llama-swap:** `:8080` (Engine v9843, Vulkan/RADV, `--list-devices` zeigt nur die RADV-GPU — kein
llvmpipe-Fallback). gemma-cmd: `-c 65536 -fa on --cache-reuse 256 -cram 16384` + MTP-Draft.
- **Hermes:** `:8642` (NousResearch), Config `~/.hermes/config.yaml`, API-Key in `~/.hermes/.env`
(`API_SERVER_KEY`). 4 MCP-Server aktiv. **NICHT anfassen — bleibt Lucys Live-Agent bis ZeroClaw steht.**
- **mem0-Sidecar:** `:8765` (`~/.mem0/`, Chroma unter `/srv/models/mem0/chroma`), `MEM0_LLM_MODEL=fast`,
`MEM0_EMBED_MODEL=embed`. Systemd-User-Unit `~/.config/systemd/user/mem0-service.service`.
- **brains-Gruppe** (immer warm, ko-resident): gemma + fast + embed + vision.
## Modell-Kandidaten (falls Fallback/Vergleich)
| Modell | Profil | Speed (Strix Halo) | Deutsch |
|---|---|---|---|
| gemma-4-26B-A4B | head_dim 512, Thinking, multimodal | langsam (Prefill) | **exzellent** |
| **Qwen3.6-35B-A3B** (auf Box) | head_dim 256, GQA kv=2 | **~85–100 t/s** | gut, aber English-Leaks |
| Qwen3-30B-A3B-Instruct | gleiche Familie | 755 pp / 85 tg (RADV) | wie Qwen3.6 |
| LFM2-8B-A1B (Liquid) | 8B/1B aktiv, Hybrid Conv+MoE | **~170 t/s** | klein → unsicher Deutsch |
## Leitplanken
- **Hermes/Lucy bleibt live** — PoC läuft isoliert (eigener Port, eigene Memory-Datei). Null Risiko.
- Vor Box-Config-Änderungen Backup; llama-swap reloadt per `-watch-config`.
- Erst messen (Prompt-Größe + Latenz), dann über vollen Umzug entscheiden.
@@ -0,0 +1,118 @@
# ZeroClaw-PoC — Ergebnis & Verdikt (2026-06-30)
> Durchführung des Plans aus `docs/ZEROCLAW_POC_BRIEF.md`. Hermes blieb die ganze Zeit
> **unangetastet** live (eigener Config-Dir, eigene SQLite-Memory, kein eigener Daemon-Port nötig –
> PoC lief als kurzlebiger CLI-Prozess). Null Risiko für die laufende Lucy.
## Setup (reproduzierbar, alles auf der Box unter `~/zeroclaw-poc/`)
- **Binary:** ZeroClaw **v0.8.2** (`zeroclaw-labs/zeroclaw`, 32k ⭐, gepflegt – die andere Repo
`elev8tion/zeroclaw` ist ein 23-Commit-Mini-Fork). Prebuilt `x86_64-unknown-linux-gnu`, SHA256
gegen `SHA256SUMS` verifiziert (`6b9f7e9d…`). Kein Rust-Toolchain auf der Box nötig.
- **Config:** isoliert via `--config-dir ~/zeroclaw-poc/config`. Provider = nativer `openai`
gegen das **MC2-Gateway** (`uri = http://127.0.0.1:9001/v1`, ZeroClaw hängt `/chat/completions`
selbst an; **base-URL, nicht der volle Pfad!**). Gateway braucht **keine Auth** (HTTP 200 offen).
- **Agent:** `[agents.lucy]`, `model_provider = openai.default`, `risk_profile = default`
(supervised), Memory-Backend = **sqlite**. Modellwahl pro Turn via `--model fast|hermes`.
- Stolpersteine gelöst: quickstart braucht TTY → headless via `config set --no-interactive`;
Secrets (`api_key`) brauchen `--no-interactive` + Wert; `risk_profiles.<key>` ist Map →
per `config set` nicht adressierbar, Block direkt in `config.toml` angehängt.
## Messungen (4 Folge-Turns, je frischer CLI-Prozess, identischer 13k-Prefix)
| Turn | FAST (Qwen3.6-35B) | HERMES (gemma-4-26B) | input_tokens |
|---|---|---|---|
| 1 | 429 ms | **937 ms** | ~13.059 |
| 2 | 534 ms | **493 ms** | ~13.056 |
| 3 | 337 ms | **340 ms** | ~13.060 |
| 4 | 465 ms | **465 ms** | ~13.061 |
`hermes`-Alias → verifiziert echtes `gemma-4-26B-A4B-it-…Q4_K_M.gguf` (kein Fallback auf fast);
gemma ist warm in der brains-Gruppe (llama-swap `/running`: gemma + Qwen3.6 + embed alle `ready`).
## Kernbefunde
1. **Prompt-Größe:** ZeroClaw baut **~13.055–13.061 Tokens** pro simplem Turn — vs. Hermes **≈ 20.000**.
~35 % kleiner. (Noch weiter reduzierbar: Default-Toolset; PoC lief mit voller Tool-Palette.)
2. **Prompt-Stabilität:** Der Prefix ist **konstant** (13.055–13.061, nur die User-Message variiert
um wenige Tokens). Genau das Gegenteil von Hermes' pro-Turn-wechselnder Auto-Injektion, die
gemmas Cache jeden Turn brach.
3. **Latenz (das Verdikt):** gemma antwortet unter ZeroClaw in **0,3–0,9 s/Turn** — gegenüber
**20–80 s** unter Hermes. Der Latenz-Abfall 937 ms → ~340 ms ab Turn 2 zeigt den **warmen Cache**
(stabiler Prefix → cache-reuse greift). gemma ist hier sogar **gleichauf mit Qwen**.
## Verdikt
**Die PoC-These ist bestätigt.** Lucys Latenz-Problem war **nicht gemma**, sondern Hermes'
fetter, pro-Turn-instabiler 20k-Prompt, der gemmas Prefill-Cache zerschoss. Ein schlanker Agent
mit **kleinem, stabilem** Prompt macht **gemma sub-sekündlich** — und rettet damit gemmas
**exzellentes Deutsch** (kein Umstieg auf Qwen mit English-Leaks nötig).
→ **Empfehlung: voller Umzug auf ZeroClaw planen** (mit gemma als Hirn). Kein Fallback auf Qwen nötig.
## Umzug umgesetzt (2026-06-30, Etappe 2)
Lucy läuft als ZeroClaw-Agent auf der Box (`~/zeroclaw-poc/`), Daemon auf `127.0.0.1:8088`:
- **Persona:** openclaw-Workspace-Dateien in `config/agents/lucy/workspace/` (`IDENTITY.md`, `SOUL.md`,
`USER.md`, `AGENTS.md`) — Lucy spricht „Commander", echte Umlaute, `<emo:>`-Tags. (Workspace-Pfad =
`<config>/agents/<alias>/workspace/`, NICHT `config/data`!)
- **MCP-Tools:** 4 Server / 37 Tools (`[[mcp.servers]]` als **Array** mit `name`, nicht Tabelle!) +
Bundle `lucy_tools` an `agents.lucy.mcp_bundles`. Alle verbunden, autonom nutzbar.
- **Hirn:** gemma (`hermes`), Autonomie `level="full"`, Thinking aus via
`providers.models.openai.default.chat_template_kwargs.enable_thinking=false`.
- **Aux:** `classifier_provider`/`summary_provider` → `openai.fastaux` (Qwen); Auto-Hydrate/Save aus.
## 🔴 KV-Cache-Killer gefunden & gefixt (der eigentliche Latenz-Showstopper)
Daemon-Latenz war erst 5–22 s/Turn (wild schwankend), obwohl Direkt-ans-Gateway gemma einen stabilen
20k-Prompt in **180 ms** cached (call 1 kalt 19 s, call 2–4 = 180 ms, cached=19820). Per Mitschnitt-Proxy
(ZeroClaw→Proxy→Gateway) zwei Folge-Turns **byte-genau gedifft**:
1. **HAUPTSCHULDIGER — Tool-Reihenfolge:** ZeroClaw hängt die 37 MCP-Tools (im `tools`-Array UND im
`deferred_loading`-Textblock) in **zufälliger HashMap-Reihenfolge pro Turn** an → ~5k Token im Prompt
ändern sich jeden Turn → llama.cpp-KV-Cache ab da tot → Full-Re-Prefill.
2. **Neben-Killer — User-Timestamp:** ZeroClaw prefixt die User-Message mit `[YYYY-MM-DD HH:MM:SS ±ZZ:ZZ]`
(variiert jeden Turn; steht am Ende → kleiner).
3. **Ausgeschlossen:** Classifier (feuert gar nicht, 1 Call/Turn), mem0/Memory (feuert bei Chat nicht).
**Fix (Binary nicht kompilierbar → Wire-Ebene):** schlanker Python-**Normalisierungs-Proxy**
(`~/zeroclaw-poc/normalizing-proxy.py`, Port 9009) zwischen ZeroClaw und Gateway: **sortiert `tools`
deterministisch** + **strippt den Timestamp**. Beide Provider-URIs zeigen auf `:9009`. Ergebnis byte-stabil
verifiziert (System + Tools identisch, nur echte User-Message variiert). **Latenz 5–22 s → ~400 ms typisch**
(Cache-Hit), vereinzelt 2–5 s (gemma cache-reuse/MTP-Rest, evtl. via `-cram 16384`); Tool-Turn ~3,6 s.
gemma-cmd: `-c 65536 -fa on --cache-reuse 256 -cram 16384 + MTP-draft`, single-slot (`--parallel 1` implizit).
## gemma-4 Cache-Recherche (llama.cpp) + FINALER Hirn-Entscheid: Qwen3.6
Nach dem Proxy blieben Rest-Spitzen (2–6 s). Tagesaktuelle llama.cpp-Recherche bestätigt: **bekannter,
Gemma-4-spezifischer Bug.**
- **Gemma 4 nutzt „Shared KV Cache"** (letzte Layer teilen K/V mit früheren) → llama.cpp loggt wörtlich
*„cache reuse is not supported - ignoring n_cache_reuse"* → **euer `--cache-reuse 256` ist für gemma-4
wirkungslos.** ([Issue #21468](https://github.com/ggml-org/llama.cpp/issues/21468))
- **Fix [PR #22288](https://github.com/ggml-org/llama.cpp/pull/22288)** (merged 24.04.2026): braucht
**`--swa-full`** (hält ganze KV-History, kein Sliding-Window-Pruning). Caveat: cache-reuse ↔ mmproj
inkompatibel.
- **Getestet an der live gemma:** `--swa-full` testweise gesetzt → mehr saubere 400-ms-Hits, ABER weiter
~50 % Misses (2–6 s). Auch nach Toolset-Eindampfung (Prompt 18k→**4908 Tok** via
`risk_profiles.default.excluded_tools`, 18 Kern-Tools) blieb gemma 1,5–6 s **spitzig**.
- **Befund:** gemma-4 cached auf Strix Halo **fundamental unzuverlässig** (SWA + Shared-KV + MTP), egal wie
klein/stabil der Prompt. → live gemma wieder auf **Original zurückgesetzt** (Hermes unberührt;
`--swa-full` als getestete Option dokumentiert, falls Hermes es nutzen will).
**Qwen3.6-35B-A3B als Lucys Hirn (Standard-GQA, cache-reuse funktioniert):** mit Proxy + Lean-Tools
**konstant ~1,2–1,8 s/Turn, NULL Spitzen** (vs gemma 1,5–6 s spitzig). Deutsch gut (echte Umlaute, kein
EN-Leak in Tests; seltener Kohärenz-Wackler). **Das ist der Brief-Fallback — jetzt empirisch als richtige
Wahl bestätigt.** Lucy-Daemon läuft auf `model=fast`.
## Finaler Lucy-Stack (läuft, manuell/nohup)
```
Desktop/Webhook → ZeroClaw-Daemon :8088 (Persona, 18 Lean-Tools, Autonomie full)
→ Normalisierungs-Proxy :9009 (sort tools + strip timestamp) ← der Cache-Fix
→ MC2-Gateway :9001 → llama-swap :8080 → Qwen3.6 (fast) ← rock-solid Cache
```
## Nächste Schritte (offen)
- **Persistenz:** Proxy + Daemon als systemd-User-Services (vom User freizugeben).
- **Voice/Telegram** an den Daemon hängen (Desktop-Client postet aktuell an MC2 `/api/voice/chat`).
- **ZeroClaw-Tool-Order-Bug** upstream melden (nicht-deterministische Tool-Sortierung killt KV-Cache).
- Optional: Deutsch-Direktive in IDENTITY.md härten gegen Qwens seltene Wackler.
- Persona/System-Prompt (Lucys Charakter) in ZeroClaw übertragen.
- Memory-Migration: mem0/Chroma → ZeroClaws SQLite (oder MCP-Bridge an `mission-control-memory`).
- MCP-Tools anbinden: `hermes-pc-control`, `mission-control-stack`, `mission-control-memory`,
`hermes-web-fetch` (ZeroClaw als MCP-Client).
- Toolset auf Kern reduzieren → Prompt < 13k drücken (noch schnellerer Prefill).
- Kanäle: Telegram + Voice an ZeroClaw hängen; Gateway-/Daemon-Betrieb (eigener Port, nicht :8642).
- Erst nach grünem Umzug Hermes ablösen.
+138
View File
@@ -0,0 +1,138 @@
# AUTONOMIE-PLAN — „Die Box wartet sich selbst" (Kapitel 0)
**Erstellt:** 02.07.2026, abends — als Kickoff-Paket für die Bau-Session („leg los").
**Nordstern (User):** Haushaltsgerät, kein Dev-Projekt. Der User macht KEINE Updates, fasst keine
Konsole an. Er bekommt Meldungen von Lucy (Telegram) und sagt höchstens „mach". In 6 Monaten ohne
KI-Hilfe darf nichts brachliegen — schlimmster erlaubter Zustand: „selbst-gepinnt und läuft".
**Kontext-Quellen:** Memory `open-threads.md` (Kapitel 0, Bausteine a–k) · `verdicts.md` ·
`project-stack-state.md` · dieser Plan. Review-Historie: docs/REVIEW_2026-07-02.md.
---
## Architektur: 3 Säulen + Werkstatt
1. **Stabilität** — eigene Software (MC2, Lucy) EINGEFROREN + Selbsterhaltung. Gitea = Tresor, kein Update-Kanal.
2. **Frische** — Fremd-Software (OS/Engine/Router/Hermes) updatet sich per Timer, mit Gate + Auto-Rollback + Selbst-Pinning.
3. **Evolution** — Radar (Hermes-cron + Web-Suche) findet Sprünge/neue Tools; Modelle bencht die Box selbst.
4. **Werkstatt** — Box-KIs setzen Wartung/Migrationen selbst um: Telegram-Ping → User „mach" → Branch → Code → Gate → Deploy → Bericht.
**Leitplanken (nicht verhandelbar):** Merge/Deploy nie ohne grünes Gate · Security-Config
(approvals/Tokens/ufw) nie ohne explizites User-Ja · alles reversibel (Backup+Branch+Pin) ·
kleine Wartung autonom, große nur vorbereitet+freigegeben.
---
## Multi-Agent-Verdikt (recherchiert + entschieden 03.07.2026)
**JA — chirurgisch an 2 Stellen; NEIN bei allem Echtzeit-nahen.** Hermes-Delegation ist reif:
`delegate_task` (goal/context/toolsets, tasks-Array = parallel, role leaf|orchestrator),
Config `delegation:` (max_concurrent_children, max_spawn_depth, eigenes delegation.model/provider).
- **E4 Radar = Fan-out-Muster:** Manager delegiert pro Komponente/Kategorie einen isolierten
Leaf-Subagent (eigener 65k-Kontext) → recherchiert, **filtert Marketing-Müll**, liefert nur
Substanz-Summary → Manager konsolidiert. Müll erreicht den Haupt-Kontext nie.
- **E6 Werkstatt = Worker/Reviewer-Muster:** Worker patcht im Worktree, SEPARATER Reviewer-
Subagent (frischer Kontext) prüft Diff gegen Auftrag, dann erst Gate+Telegram. (Verdent-Muster,
lokal nachgebaut.)
- **NICHT bei Lucy-Voice** (Konsens 2026: Agent-Ketten ≈ 3× Latenz bei Echtzeit — unsere 2 s sind
heilig). Lucy bekommt stattdessen Delegation als FEATURE: „recherchier ich im Hintergrund"
→ Background-Subagent → Ergebnis via Telegram. **NICHT bei der IDE-Lane** (eigene Agent-Loops).
- **Kein Hirn-Tausch:** Parent bleibt Qwen3.6; `delegation.model/provider` → MC2-Gateway.
Manager-/Reviewer-Kandidat = **gpt-oss-120b** (Faden B5 entscheidet heavy-Lane UND Manager-Rolle
in einem). `max_concurrent_children: 2` — passt exakt auf die 2 Hirn-Slots (keine Swap-Thrashes);
`max_spawn_depth: 1` zum Start (flat), Orchestrator erst bei Bedarf.
- **Ehrliche Physik:** eine GPU ⇒ Parallelität bringt KEIN Tempo (geteilte Bandbreite), sondern
Kontext-Isolation + Qualität. Für nächtliche cron-Jobs genau richtig; deshalb Voice-Ausschluss.
---
## Was schon existiert (nutzen, nicht neu bauen!)
| Baustein | Wo |
|---|---|
| Update-Pipeline je Ebene mit Backup+Checks | UI-Buttons: OS/Engine (`deploy/update-engine.sh` — hat schon stack-postcheck+Auto-Rollback!), Router (`update-swap.sh`), Hermes (`POST /api/maintenance/hermes-update` → backup→update→doctor→Postcheck) |
| Qualitäts-Gate (Abnahmetest für ALLES) | `deploy/hermes-postcheck.sh`: Mem0+Plugin+Config-Drift-Scan+Tool-Smoke+Voice-Smoke, E2E grün. ⚠️ pipefail-Lektion: Stream-Probes brauchen `set +o pipefail`-Subshell |
| Tägliches Backup + Restore | `deploy/backup.sh` (Timer 03:30) / `restore.sh` |
| Telegram | Hermes-Gateway läuft mit Telegram; CLI `hermes send` (Syntax in Session verifizieren: `hermes send --help`) |
| Cron | `hermes cron` (Subcommand existiert) |
| Coding-KI | Qwen3-Coder-Next (coder-Lane, 131k ctx); Hermes v0.18 hat „Coding Projects mit git-worktree-Management" |
| PC-Fernsteuerung | `client/hermes-pc` Executor (Token `HERMES_PC_TOKEN`) — für Lucy-Builds auf dem Windows-PC |
| Bench-Harnesses | `deploy/bench/brain-bench.sh` + `deploy/bench/model-bench.sh` (mit diesem Kickoff ins Repo gelegt) |
| Health/Repair | LucyHealthCard + `/api/health` brain-Check; systemd `Restart=on-failure` überall |
---
## Etappen (in dieser Reihenfolge bauen)
### E1 · Nervensystem: Meldeweg (klein, zuerst — alles Weitere nutzt ihn)
- `deploy/notify.sh "<Nachricht>"`: primär `hermes send` (Telegram), Fallback: Logfile + `wall`.
Syntax von `hermes send` zuerst auf der Box verifizieren (`bash -lc 'hermes send --help'`).
- Verifikation: Testnachricht landet beim User auf Telegram.
### E2 · Frische: Auto-Update-Timer + Rollback + Pin-Register
- **Pin-Register:** `/srv/models/mc2-pins.json` — `{komponente: {pinned: bool, version, grund, datum}}`.
Gepinnte Ebene wird vom Timer übersprungen; Pin-Meldung ging via E1 raus.
- `deploy/autoupdate.sh` (Reihenfolge: swap → engine → hermes; Modelle NICHT auto):
je Ebene: Update-Check → wenn Update: bestehenden Pfad nutzen (update-engine.sh / update-swap.sh /
hermes-update-Job via API + Job-Polling) → Postcheck rot ⇒ Rollback (existiert je Pfad) + Pin
setzen + notify; grün ⇒ notify „eingespielt: X→Y".
- systemd-User-Timer `mc2-autoupdate.timer` (wöchentlich So 04:30, nach Backup), Unit nach
`~/.config/systemd/user/`, in `deploy/deploy.sh` registrieren (Muster: mc2-backup.timer).
- **OS-Ebene:** apt braucht sudo → `unattended-upgrades` (nur Security) in der EINMALIGEN
sudo-Session einrichten (zusammen mit Faden C14: stale v1-Unit weg). Bis dahin: OS aus dem Timer raus.
- Verifikation: Timer-Dry-Run (`bash autoupdate.sh`), einmal echt durchlaufen lassen, Telegram-Meldungen prüfen; künstlichen Fehlschlag provozieren (Postcheck-FAIL faken) → Rollback+Pin+Meldung.
### E3 · Stabilität: Lucy-Produktiv-Build (einfrieren)
- Im Lucy-Repo (`F:\Coding Stuff\lucy`): electron-builder ergänzen (portable oder NSIS),
**asar-Caveat:** `app.getAppPath()` zeigt im Build woanders hin → `LUCY_TTS_DIR` absolut setzen
(Installer-Config oder Start-BAT) — siehe Kommentar in `lucy-desktop/src/main/index.ts`.
- Verknüpfung auf den Build; `Lucy-Neustart.bat` auf Build umstellen; Dev-Modus bleibt für Wartung.
- Verifikation: Build starten → Worker-Pool bereit, Sprech-Roundtrip.
- Danach gilt Lucy als EINGEFROREN (Änderungen nur noch via Werkstatt-Kreislauf).
### E4 · Evolution: Radar
- Hermes-cron (monatlich, z. B. 1. des Monats 09:00): Prompt-Job —
„Inventar von `/api/maintenance/updates` + `/v1/models` + Versionsliste einlesen; per web_search
Changelogs/Neuigkeiten zu: llama.cpp, llama-swap, hermes-agent, pocket-tts, onnx-asr/Parakeet,
Silero, smart-turn, Electron, three-vrm + Kategorie-Scan (bessere lokale Coder-/Vision-/TTS-
Modelle für Strix Halo 128 GB) + **IDE-/Agent-Tool-Kategorie** (Kilo Code, OpenCode, Claude Code
— Lehre 03.07.: Roo Code war Stunden nach der Empfehlung als „eingestellt seit April" entlarvt;
genau solche Tod-/Nachfolger-Meldungen muss das Radar fangen); gegen [[verdicts]] halten
(Verworfenes nicht wieder vorschlagen);
Ergebnis als kurzer deutscher Report → notify.sh".
- Ablage des Prompts versioniert: `deploy/radar-prompt.md`, cron ruft ihn.
- Verifikation: Cron einmal manuell feuern, Telegram-Report prüfen (Qualität grob checken).
### E5 · Evolution: Modell-Selbst-Evaluation
- `deploy/bench/model-bench.sh <gguf-pfad> [extra-flags]` (liegt bei) → pp/tg-Zahlen.
- Workflow (halbautonom v1): Radar meldet Kandidat → User „mach" → Hermes lädt (hf CLI im
backend-venv existiert) → bencht → notify mit Vergleichstabelle → User-Entscheid → Config-Eintrag.
- Verifikation: einmal mit vorhandenem Modell durchspielen.
### E6 · Werkstatt: Wartungs-Workflow (der Schachzug — zuletzt, auf E1–E5 aufbauend)
- Hermes-Skill/Workflow „wartung": Auftrag (aus Radar oder User) → `git worktree` im Box-Checkout
(MC2) bzw. via PC-Executor (Lucy) → Änderung durch coder-Lane → Gate = Postchecks + Build →
Branch-Push zu Gitea → notify mit Diff-Zusammenfassung → User „merge"/„verwerfen" via Telegram
(Hermes approvals-Mechanik nutzen) → bei merge: Deploy-Pfad + Backup + Postcheck.
- Scope v1 BEWUSST klein: Config-Schlüssel-Migrationen, Dependency-Bumps (Lockfile), Ein-Datei-
Patches. Architektur-Umbauten: nur Plan+Branch vorbereiten.
- Verifikation: einen echten Klein-Fall durchspielen (Kandidat: ServicesCard-Restart-Bug, Faden B9
— perfekte Werkstatt-Gesellenprüfung: 1 Datei, klarer Fix, Gate vorhanden).
---
## Definition of Done (Kapitel 0)
1. Wöchentlicher Auto-Update-Lauf mit Telegram-Meldung, verifiziertem Rollback+Pin-Pfad.
2. Lucy läuft als gebaute, eingefrorene App.
3. Monatlicher Radar-Report kommt auf Telegram an.
4. Ein Modell-Kandidat wurde einmal selbst gebencht + gemeldet.
5. Die Werkstatt hat EINEN echten Klein-Fix eigenständig bis zum Merge-Vorschlag gebracht.
6. Runbook-Seite existiert (`docs/RUNBOOK.md`, 1 Seite Mensch-Anleitung).
## Session-Start-Checkliste („leg los")
1. `git -C ~/mission-control-v2 log --oneline -1` auf der Box == origin/main? (SSH: hitonabi@192.168.178.151)
2. Health: `curl -s http://192.168.178.151:9001/api/health` → brain ready?
3. `bash -lc 'hermes send --help'` → Syntax für E1 klären.
4. Dann E1 → E6 der Reihe nach; jede Etappe committen + deployen + real verifizieren (Telegram!).
Gitea-Push: PowerShell, Auth flatterhaft → einmal Retry.
+281
View File
@@ -0,0 +1,281 @@
# Komplett-Review Mission Control 2 + Lucy — 02.07.2026
**Methodik:** IST-Zustand live erhoben (Box per SSH, lokaler Lucy-PC, Working Tree `lucy-v2` inkl. uncommitted) — nicht aus Docs/Memory übernommen. SOLL-Zustand in 3 Recherche-Runden tagesaktuell (Stand 02.07.2026) ermittelt. Alle früheren Verdikte wurden neu auf den Prüfstand gestellt. Scope: alles außer Security.
---
## 1. Management-Summary
| Bereich | Zustand | Kernaussage |
|---|---|---|
| LLM-Stack (Box) | ✅ stark, 1 Bug | Vulkan-Pfad richtig, Qwen3.6+MTP läuft; aber chat-Lane kaputt (Autostart-Fund war Fehlalarm) |
| Lucy Voice-Latenz | 🔴 3,5–5 s | 2026-Ziel ist 0,5–0,8 s. Schuld sind STT (2,0 s) und VAD-Timer (0,9 s), **nicht** das LLM (TTFT 65 ms) |
| Lucy Avatar/App | ✅ sehr ausgereift | VRMA-Mocap, Lippensync v2, MateEngine-Features komplett; Electron 10 Major-Versionen alt |
| Backend/Frontend-Code | 🟡 solide | 3 Monolithen, etwas DRY-Schuld, dist/ im Git; keine Rot-Flaggen |
| Ökosystem-Aktualität | 🟡 | Hermes 1 Release hinter (v0.18.0 vom 01.07.); pocket-tts, mem0, llama-swap, three-vrm aktuell |
| Verdikte | ✅ alle bestätigt | Pocket TTS, Electron, Qwen3.6-Hirn, kein ZeroClaw, Mem0 — alle bestehen die Re-Prüfung |
**Die zwei größten Hebel:**
1. **STT-Tausch** (faster-whisper medium → Parakeet-TDT 0.6B v3): ~2,0 s → ~0,2 s pro Äußerung
2. **VAD-Tausch** (RMS-Eigenbau → Silero VAD v6.2): Turn-Ende 900 → ~450 ms bei besserer Genauigkeit
Zusammen: Voice-to-Voice von ~3,5–5 s auf realistisch **≤1,2 s**, ohne neue Hardware.
---
## 2. IST-Zustand (live verifiziert)
### 2.1 Box (192.168.178.151 — Strix Halo, gfx1151, 122 GB, Vulkan)
| Komponente | Installiert | Aktuell (02.07.2026) | Bewertung |
|---|---|---|---|
| llama.cpp | b9843 (86b94708f) | b9859 (01.07.) | ✅ nur ~16 Builds dahinter |
| llama-swap | v233 (29.06.) | v233 | ✅ aktuell |
| Hermes Agent | **v0.17.0** (19.06.) | **v0.18.0** (01.07.) | 🟡 Update lohnt (3 P0 + 493 P1 gefixt) |
| mem0ai / chromadb | 2.0.8 / 1.5.9 | 2.0.8 | ✅ aktuell |
| Kernel | 7.0.0-27-generic | — | ✅ |
**Live-Modell-Lineup** (`/etc/llama-swap/config.yaml`, live gelesen — der Repo-Snapshot `deploy/llama-swap.config.yaml` ist **veraltet** und zeigt noch gemma-4):
| Alias | Modell | ctx | Besonderheiten |
|---|---|---|---|
| hermes (Brain) | Qwen3.6-35B-A3B (UD-Q4_K_M, MTP-GGUF) | 65536 | `--spec-type draft-mtp --spec-draft-n-max 3 --parallel 1 -cram 16384`, **kein** cache-reuse |
| heavy | Qwen3.5-122B-A10B | 32768 | cache-reuse 256, ttl 600 |
| coder | Qwen3-Coder-Next | 131072 | cache-reuse 256, ttl 600 |
| coder-lite | Qwen3-Coder-30B-A3B | 131072 | cache-reuse 256, ttl 300 |
| vision | Qwen3-VL-8B | 32768 | mmproj, in brains |
| embed | Qwen3-Embedding-0.6B | 8192 | ttl 0, in brains |
| scout | GLM-4.6V-Flash | 131072 | mmproj, ttl 300 |
Gruppe `brains` (swap:false, persist:true) = embed + vision + Qwen3.6. Alle Modelle: `-ngl 999 -fa on --no-mmap --jinja`. **Kein Modell nutzt KV-Cache-Quantisierung** (alles F16).
**Dienste live:** llama-swap, hermes-gateway, hermes-terminal, hermes-webui, mem0-service, voice-service — alle running. Ports 7681/8080/8642/8650/8765/8787/9001 belegt.
### 2.2 🔴 Live-Bugs (selbst reproduziert)
**B1 — ~~MC2-Backend ohne Autostart~~ FEHLALARM (korrigiert 02.07., nachverifiziert).**
:9001 läuft als **User-Unit** `mission-control-2.service` (`~/.config/systemd/user/`, enabled, `Linger=yes` → reboot-fest). Die erste SSH-Prüfung sah User-Units nicht (fehlendes XDG_RUNTIME_DIR). Einziger echter Fund: Die **stale v1-System-Unit** `mission-control.service` (disabled, /opt/mission-control:9000) liegt noch in /etc/systemd/system und stiftet Verwirrung → bei Gelegenheit mit sudo entfernen (kosmetisch, kein Risiko).
**B2 — chat-Lane kaputt (live reproduziert).**
```
POST /v1/chat/completions {"model":"chat",...}
→ {"error":"no router for requested model","src":"llama-swap"}
```
Die Routing-Policy routet `chat → fast ↔ heavy`, aber llama-swap kennt den Alias `fast` nicht mehr (Qwen3.6 hat nur noch den Alias `hermes`). Lucy ist nicht betroffen (sie geht über den Hermes-Agenten :8642), aber jeder Client der chat-Lane bekommt Fehler. Fix: `fast` als zweiten Alias eintragen **oder** Policy auf `hermes` umstellen.
**B3 — Config-Drift.**
`deploy/llama-swap.config.yaml` ist untracked UND veraltet (gemma-4-Ära). Zusätzlich fehlen im Install-Template [`backend/config.py:33`](../backend/config.py) die Produktions-Tunings (cache-reuse, parallel, MTP) → neu installierte Modelle driften von der Box-Realität weg.
### 2.3 Gemessene Latenzkette Lucy
Quelle: `/api/voice/metrics` (live) + eigener TTFT-Test gegen llama-swap.
| Stufe | Messwert | Anteil am Problem |
|---|---|---|
| VAD-Turn-Ende | **900 ms** Fix-Timer (RMS-Eigenbau, [useVAD.ts](../client/lucy-desktop/src/renderer/src/lib/voice/useVAD.ts)) | groß |
| STT (faster-whisper medium int8, Box-CPU) | **avg 2.046 ms · p50 2.092 ms · p95 2.529 ms** (n=13) | **dominant** |
| LLM TTFT (Qwen3.6 warm, direkt :8080) | **65 ms** (24 Tokens in 334 ms) | ✅ kein Problem |
| TTS erster Ton (pocket, RTF 0,44 + LEAD_IN 0,35 s) | ~0,5–1 s für den ersten Satz | mittel |
| **Voice-to-Voice gesamt** | **~3,5–5 s** | Ziel 2026: **0,5–0,8 s** |
**Fazit: Das teuerste Glied ist NICHT das LLM.** STT + VAD-Timer fressen zusammen ~3 s. Genau dort setzt die Roadmap an.
### 2.4 Lokaler PC (RX 9070 XT / RDNA4)
- Lucy-App zum Prüfzeitpunkt nicht gestartet (kein Electron-Prozess, :8130 frei)
- `ptts-venv`: pocket-tts **2.1.0** (= neueste Version), torch 2.12.1+cpu (bewusst CPU), onnxruntime 1.27.0, fastapi 0.138.1
- GPU-Treiber 32.0.31021.5001
- [client/lucy-tts/](../client/lucy-tts/) (3 GB): Produktions-TTS mit Stimmen-Wächter (F0-Floor 160 Hz, MFCC-Fingerprint ≥0,94, Best-of-N), Phase A+B des TTS-Plans abgeschlossen (beste Config: 4 Worker × 2 Threads, RTF 0,44)
- [client/lucy-f5/](../client/lucy-f5/) (5,3 GB): F5-TTS-ONNX/DirectML-Experiment — **Phase C/D (Finalentscheid pocket vs. F5) offen**
- Lucy-Desktop: Electron **33** (aktuell: **43** vom 30.06. — 2 Jahre Chromium-Rückstand), three-vrm 3.4/animation 3.5.4 (≈ aktuell), TS strict
### 2.5 Code-Qualität (3 Explore-Agents über das ganze Repo)
**Backend (4.889 LOC, 11 Router / 28 Services):** insgesamt sauber, Multi-Sidecar-Architektur durchdacht. Findings:
- C1: Install-Template ohne Produktions-Tunings ([backend/config.py:33](../backend/config.py)) → Drift
- C2: `_describe_images()` blockiert den Voice-Chat bis 120 s synchron ([backend/routers/voice.py](../backend/routers/voice.py))
- C3: Thinking-Deaktivierung 3× dupliziert (voice.py, gateway.py, mem0_service/app.py) — DRY
- C4: Junk-Fact-Regex im Mem0-Sidecar hartcodiert (Wartungspunkt)
- Dead Code: `backend/services/pricing.py`, vermutlich `token_stats.py`
- Uncommitted Änderungen (voice.py No-Think, connect.py IDE-only-`coding`, mc2-memory-Guards, Mem0-Junk-Guard, voice_service install.sh) sind **alle konsistent und sinnvoll** — nur eben nicht committet
**Frontend (React 18/Vite 6/Tailwind 4/TanStack 5):**
- Voice-Umzug in die Desktop-App sauber (keine toten Imports/Nav-Reste) ✅
- UI-Rework (roleMeta/Health/Expert/WarmSet) vollständig; coder_lite↔coder-lite via ALIAS gelöst
- F1: [Cockpit.tsx](../frontend/src/views/models/Cockpit.tsx) (990 Z) + [SystemDrawer.tsx](../frontend/src/components/SystemDrawer.tsx) (934 Z) Monolithen
- F2: 🟡 `frontend/dist/`-Asset-Stand auf lucy-v2 inkonsistent (alte gelöscht, neue untracked) — dist-im-Git selbst ist Absicht (Box hat kein Node), avatar.vrm ist via .gitignore korrekt draußen
- F4: keine globale Error Boundary
- MC3-Prototyp ([frontend/src/mc3/](../frontend/src/mc3/)) non-destruktiv hinter `#mc3`, untracked
**Lucy-Desktop:**
- L1: [useVoiceAgent.ts](../client/lucy-desktop/src/renderer/src/lib/voice/useVoiceAgent.ts) (377 Z) monolithisch (SSE, Chunking, Tools, Perf, Vision in einem Hook)
- L2: kein Retry/Backoff beim TTS-Warmup (Crash → 2-min-Spinner)
- L3: VAD = reines RMS mit 900-ms-Stille-Regel
- L4: Echo-Schutz = 450-ms-Cooldown-Workaround (kein echtes Barge-in)
- Neues [voice-core/](../client/lucy-desktop/src/renderer/src/voice-core/)-Adapter-Layer (STT/TTS austauschbar) ist die richtige Architektur ✅
- H1: ~23 Dateien uncommitted, darunter die neue voice-core-Architektur → Verlustrisiko
---
## 3. SOLL-Zustand (Recherche, Stand 02.07.2026)
### 3.1 Voice-Latenz — der Stand der Technik
- 2026-Zielmarke: **500–800 ms voice-to-voice**; Grundprinzip: **Streaming auf jeder Stufe** (STT-Partials sparen 200–400 ms, TTS startet auf Teiltext, VAD+Turn-Taking-Budget 150–300 ms) — [Latenz-Guide](https://futureagi.com/blog/how-to-optimize-voice-agent-latency-2026/), [Latenz-Budget-Design](https://smallest.ai/blog/designing-voice-assistants-stt-llm-tts-tools-and-latency-budget)
- **STT:** [Parakeet-TDT 0.6B v3](https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3) — 25 EU-Sprachen inkl. Deutsch, 6,32 % WER (besser als Whisper large-v3 mit 7,44 %), extrem schnell auch auf CPU, keine Silence-Halluzination. Deploy-Wege: [onnx-asr](https://pypi.org/project/onnx-asr/) (unterstützt CPU **und** DirectML → 9070 XT), fertige [OpenAI-kompatible FastAPI-Wrapper](https://github.com/groxaxo/parakeet-tdt-0.6b-v3-fastapi-openai). Kyutais Streaming-STT mit eingebautem semantic VAD ([delayed-streams-modeling](https://github.com/kyutai-labs/delayed-streams-modeling)) wäre architektonisch ideal, ist aber **nur EN/FR** → für Deutsch raus.
- **VAD:** [Silero VAD v6](https://github.com/snakers4/silero-vad/releases/tag/v6.0) (v6.2, ONNX): −16 % Fehler auf Noisy-Data vs. v5 — klar besser als der RMS-Eigenbau; erlaubt kürzeres Endpointing (~450 ms) bei weniger Fehlstarts.
- **Semantische Turn-Detection:** Smart Turn V2 (leichtgewichtig), [Easy Turn](https://arxiv.org/pdf/2509.23938) (akustisch+linguistisch, 4 Turn-States, open source).
- **TTS:** pocket-tts 2.1.0 ist Stand der Technik für CPU-Realtime ([kyutai](https://kyutai.org/blog/2026-01-13-pocket-tts/)). Challenger (CosyVoice2-0.5B, Chatterbox-Turbo) bieten keinen klaren Vorteil. → Einziger offener Entscheid bleibt das hauseigene F5-Experiment (Phase C/D).
### 3.2 Box maximieren
- **Vulkan/RADV bleibt der schnellste Pfad auf Strix Halo** (schlägt ROCm/HIP bei pp und tg) — die Box ist richtig aufgestellt ([llm-tracker Strix-Halo](https://llm-tracker.info/_TOORG/Strix-Halo), [Strix-Halo-Guide](https://github.com/hogeheer499-commits/strix-halo-guide)). ROCm 7.2/RDNA4 betrifft nur den lokalen PC.
- **Host-Memory-Prompt-Cache:** `--cache-ram` + Prefix-Restore bringt bis **93 % TTFT-Reduktion** bei Agent-Workloads mit wachsender Session ([llama.cpp #20574](https://github.com/ggml-org/llama.cpp/discussions/20574)). `-cram 16384` ist gesetzt; das Zusammenspiel mit dem (am hermes-Alias entfernten) `--cache-reuse` gehört gebencht.
- **KV-Cache-Quantisierung ungenutzt:** `-ctk/-ctv q8_0` halbiert den KV-Bedarf (relevant bei coder@131k, hermes@65k) bei praktisch verlustfreier Qualität; [TurboQuant](https://github.com/ggml-org/llama.cpp/discussions/20969) (3-bit, near-lossless ab 13B) steht vor der Integration — beobachten.
- **„MoE Speculative Trap":** Ein aktueller [Strix-Halo-Deep-Dive](https://dev.to/agustinsacco/breaking-the-moe-speculative-trap-460-ts-on-amd-strix-halo-446d) zu exakt Qwen3.6-35B-A3B zeigt: Spec-Verify kann bei sparsem MoE pro Verify-Pass fast alle 35B Gewichte anfassen — in seinem Setup war **ohne** Draft (parallel=1, KV Q8_0) 43,1 t/s vs. 17,7 t/s. Das widerspricht der eigenen Box-Messung (+35 % MIT MTP). Konsequenz: **beide Betriebsarten benchen**, auch bei vollem Kontext ([Decode-Drop bis 64 % dokumentiert](https://kmarble.dev/posts/strix-halo-full-context-decode-drops/)).
- **llama-swap-Features ungenutzt:** `capabilities` (v225), `-config-dir`-Fragmente (v230), Swap-Matrix/Groups V2 ([Releases](https://github.com/mostlygeek/llama-swap/releases)).
- Modell-Landschaft 128 GB für heavy-Kandidaten: gpt-oss-120B, Mistral Small 4 (119B-A6B), Llama 4 Scout — nur mit Bench-Gate.
### 3.3 Ökosystem
- **Hermes v0.18.0 „Judgment"** (01.07.): 3 P0 + 493 P1 gefixt, Background-Fan-out für Subagents, `/learn`-Skills, Memory-Graph in der Desktop-App ([Releases](https://github.com/NousResearch/hermes-agent/releases)). **Plugin-API:** `sync_turn()` bekommt optional `messages` (voller Turn-Kontext inkl. Tool-Calls); Legacy-Signatur bleibt → **mc2-memory ist update-kompatibel** und kann später Tool-Ergebnisse mitlernen ([Memory-Provider-Doku](https://hermes-agent.nousresearch.com/docs/developer-guide/memory-provider-plugin)).
- **Mem0 v3-Algorithmus** ([Migration](https://docs.mem0.ai/migration/oss-v2-to-v3)): Single-Pass-Extraktion (~2× schneller), Hybrid-Retrieval (semantisch + BM25 + Entity-Graph, ohne externe Graph-DB), +20 LoCoMo / +26 LongMemEval. 2.0.8 installiert, `custom_instructions` schon migriert → Status final verifizieren.
- **Electron 43** (30.06.), Chromium 150 / Node 24 — Lucy ist auf 33.
- **Vision:** Qwen3-VL ist aktuelle Generation ✅; [Qwen3-VL-30B-A3B](https://github.com/qwenlm/qwen3-vl) (MoE, 3B aktiv, top auf GUI-Benchmarks) wäre der Upgrade-Kandidat für die Bildschirm-Sicht.
- **Lokaler GPU-Klon:** [AMD Lemonade](https://runaihome.com/blog/amd-lemonade-local-llm-server-npu-gpu-guide-2026/) (llama.cpp-Vulkan + whisper.cpp + Kokoro, OpenAI-kompatibel, RDNA4-Support) als fertiger Unterbau; llama.cpp-Vulkan ist der [verlässlichste 9070-XT-Pfad](https://digtvbg.com/blog/llama-server-vulkan-rdna4-vllm-rocm-benchmark/).
### 3.4 Verdikte — Ergebnis der Re-Prüfung
| Verdikt | Ergebnis | Begründung |
|---|---|---|
| Pocket TTS bleibt | ✅ **bestätigt** | 2.1.0 aktuell, RTF 0,44 optimiert, Wächter-System; Challenger ohne klaren Vorteil. F5-Entscheid (Phase C/D) bleibt als einziger offener Punkt |
| Electron bleibt (nicht Tauri) | ✅ **bestätigt** | Alle nativen Features implementiert; aber Major-Update 33→43 einplanen |
| Qwen3.6 als Lucy-Hirn | ✅ **live bestätigt** | Läuft mit MTP, TTFT 65 ms; gemma-4 ist komplett raus |
| ZeroClaw bleibt tot | ✅ **bestätigt** | Kein neuer Anlass |
| Mem0 als Memory-Layer | ✅ **bestätigt** (neu geprüft) | Zep/Hindsight benchen höher, sind aber schwerer/teils closed; Mem0: beste Integration, v3-Algo, deployt |
---
## 4. Roadmap (Aufwand/Nutzen, Voice-Speed-first)
### P0 — Live-Bugs & Betriebssicherheit (Stunden)
| # | Maßnahme | Nutzen |
|---|---|---|
| 1 | ~~Autostart fixen~~ **erledigt als Fehlalarm** — User-Unit `mission-control-2` mit Linger ist reboot-fest; nur stale v1-Unit bei Gelegenheit löschen (sudo) | Klarheit |
| 2 | chat-Lane fixen (`fast`-Alias ergänzen oder Policy auf `hermes`) | Live-Bug, alle chat-Clients betroffen |
| 3 | Box-Config → Repo syncen + `deploy/` versionieren; Template-Drift C1 fixen | Quelle der Wahrheit |
| 4 | Hermes v0.17.0 → v0.18.0 + Health-Brain-Check | 496 Upstream-Fixes |
| 5 | Commit-Hygiene (voice-core, MC3, Lucy-Fixes); `frontend/dist/` in .gitignore | Verlustrisiko weg |
### P1 — Voice-Latenz: 3,5–5 s → Ziel ≤1,2 s (Tage)
| # | Maßnahme | Erwartung |
|---|---|---|
| 6 | **STT-Tausch**: Parakeet-TDT 0.6B v3 statt faster-whisper medium. Variante A: Box-CPU (onnx-asr im voice_service); Variante B: lokal 9070 XT (DirectML). A/B: Deutsch-WER + Latenz | **~2,0 s → ~0,2 s** |
| 7 | **VAD-Tausch**: Silero VAD v6.2 (ONNX) statt RMS in useVAD.ts; Endpointing 900 → ~450 ms | **−450 ms** |
| 8 | TTS-TTFA: LEAD_IN 0,35 s prüfen, Erster-Satz-kurz-Regel messen (lucy_perf) | −100–300 ms |
| 9 | **Brain-Bench-Matrix** am hermes-Alias: MTP n-max 3↔4↔ohne (Speculative-Trap-These) × ±KV Q8_0 × cache-reuse/cram × -b/-ub — bei Kurz- UND Voll-Kontext | Bestes Setup evidenzbasiert |
| 10 | voice_metrics ausbauen: VAD→STT→Agent→First-Audio je Turn | Messbarkeit |
| 10b | KV Q8_0 für coder@131k/heavy erwägen | Warm-Set-Reserve |
### P2 — Lucy v2 Kern & Code-Gesundheit (1–2 Wochen)
| # | Maßnahme |
|---|---|
| 11 | Semantische Turn-Detection (Smart Turn V2 / Easy Turn) auf Parakeet aufsetzen; Barge-in-Vorstufe statt 450-ms-Cooldown |
| 12 | F5-TTS Phase C/D abschließen → Finalentscheid pocket vs. F5 (Benchmark-Gate) |
| 13 | useVoiceAgent-Refactor in Hooks + TTS-Retry/Backoff; Electron 33→43 |
| 14 | Backend C2 (Vision async) + C3 (DRY) + Dead Code; Frontend Cockpit/SystemDrawer-Split + globale Error Boundary |
### P3 — Strategisch (nach Signal)
| # | Maßnahme |
|---|---|
| 15 | Mem0-v3-Status final verifizieren; Junk-Regex durch v3-Retrieval entschärfen; mc2-memory auf `sync_turn(messages)` heben |
| 16 | MC3-Vollbau; llama-swap-Features (capabilities, config-dir, Swap-Matrix) |
| 17 | heavy-Bench: Qwen3.5-122B vs. gpt-oss-120B / Mistral Small 4; Vision-Upgrade Qwen3-VL-30B-A3B für Bildschirm-Sicht |
| 18 | Lokaler GPU-Klon: AMD Lemonade auf der 9070 XT evaluieren |
---
## 5. Findings-Katalog (Referenz)
| ID | Schwere | Fund | Ort |
|---|---|---|---|
| B1 | ⚪ (Fehlalarm) | :9001 läuft als User-Unit mit Linger — reboot-fest; nur stale v1-Unit als Kosmetik-Rest | Box, /etc/systemd/system/mission-control.service (v1) |
| B2 | 🔴 | chat-Lane → fast-Alias existiert nicht mehr | Box, Routing-Policy ↔ /etc/llama-swap/config.yaml |
| B3 | 🟡 | deploy/llama-swap.config.yaml untracked + veraltet | Repo |
| C1 | 🟡 | Install-Template ohne Produktions-Tunings | backend/config.py:33 |
| C2 | 🟡 | Vision-Beschreibung blockiert Chat bis 120 s | backend/routers/voice.py |
| C3 | 🟢 | Thinking-Disable 3× dupliziert | voice.py / gateway.py / mem0_service/app.py |
| C4 | 🟢 | Junk-Fact-Regex hartcodiert | mem0_service/app.py |
| C5 | ⚪ (Fehlalarm) | pricing.py + token_stats.py sind IN BENUTZUNG (system.py /token_stats-Endpoint, gateway_stream) — kein Dead Code | backend/services/ |
| F1 | 🟡 | Monolithen 990/934 Z | frontend/src/views/models/Cockpit.tsx, components/SystemDrawer.tsx |
| F2 | 🟡 (korrigiert) | dist/ im Git ist ABSICHT (Box hat kein Node, deploy = git reset --hard; s. deploy/build.sh) — echter Fund war nur der inkonsistente Asset-Stand auf lucy-v2 (behoben durch Rebuild+Commit). Build-on-Box/CI wäre P3-Option | frontend/dist/ |
| F4 | 🟢 | Keine globale Error Boundary | frontend/src/App.tsx |
| L1 | 🟡 | useVoiceAgent monolithisch (377 Z) | client/lucy-desktop/.../lib/voice/useVoiceAgent.ts |
| L2 | 🟡 | Kein TTS-Warmup-Retry | ebd. + main/index.ts |
| L3 | 🔴 | RMS-VAD mit 900-ms-Timer | client/lucy-desktop/.../lib/voice/useVAD.ts |
| L4 | 🟡 | Echo-Cooldown statt Barge-in | ebd. |
| H1 | 🟡 | ~23 Dateien uncommitted (inkl. voice-core, MC3) | lucy-v2 Working Tree |
---
## 6. Nachtrag: P0/P1-Umsetzung (02.07.2026)
**P0 komplett:** chat-Lane gefixt (fast-Alias), Hermes v0.18.0 (Postcheck grün), Config versioniert, Template-Drift behoben, Git aufgeräumt. B1 war Fehlalarm (s.o.).
**P1-6 STT:** Parakeet-TDT 0.6B v3 (onnx-asr, int8, Box-CPU) als Default — **A/B gemessen: 0,45 s vs. 2,44 s** (whisper-medium) bei identischem Transkript. Live deployt, auch via :9001 verifiziert.
**P1-7 VAD:** Silero v5 (vad-web 0.0.30) statt RMS — Endpointing 900→450 ms, WAV direkt (kein Opus-Umweg mehr). Build + Asset-Auslieferung verifiziert; Mikro-Test beim User.
**P1-9 Brain-Bench-Matrix** (Qwen3.6-35B-A3B, separater Port, Vulkan, je ~100 Gen-Token):
| Config | tg kurz | tg tief (15k) | Draft-Akzeptanz kurz |
|---|---|---|---|
| MTP n-max 3, KV f16 (live) | **78,6 t/s** | — (Probe-EOS) | 55 % |
| MTP n-max 4 | 63,7 | 100,9* | 39 % |
| ohne Spec | 62,4 | — (Probe-EOS) | — |
| **MTP n-max 3 + KV Q8_0** | **78,6** | 83,7 | 56 % |
| ohne Spec + KV Q8_0 | 62,1 | 57,0 | — |
*\*repetitiver Test-Text → unrealistisch hohe Draft-Akzeptanz (95 %); die Kurz-Spalte ist maßgeblich.*
**Bench-Verdikte:** (1) MTP n-max 3 bestätigt (+26 % vs. ohne Spec — die „MoE Speculative Trap" gilt auf diesem Vulkan/parallel-1-Setup NICHT; der Artikel testete ROCm + parallel 4). (2) n-max 4 lohnt nicht (Akzeptanz fällt auf 39 %). (3) **KV Q8_0 ist gratis** (identische t/s) und halbiert den KV-Speicher → für hermes in deploy/llama-swap.config.yaml übernommen; Live-Schaltung braucht User-Freigabe. Für coder/heavy vorher cache-reuse×KV-Quant-Verträglichkeit testen (Context-Shift mit quantisiertem KV ist in llama.cpp historisch heikel).
**P1-10:** `chat_first_content`-Metrik in voice.py — misst die echte Hirn-Latenz (Agent-Overhead + LLM-TTFT bis zum ersten Inhalts-Token) statt nur des SSE-Starts.
**P2-Nachtrag (02.07.):**
- **Profiling:** Folge-Turns 1,3 s, NEUE Sessions 5,6–12 s (Session-Prefill System-Prompt+Tools ~4–5k Tok). Mem0-Search unschuldig (18 ms). **Aber:** Die Mem0-Lern-Extraktion (~2,4 s je Turn, gleiche Qwen3.6-Instanz) blockiert bei `--parallel 1` den nächsten Voice-Turn in der Queue → Fix vorbereitet: `--parallel 2 -c 131072 + KV Q8_0` (2×65k-Slots, speicherneutral zu 1×65k f16). Live-Schaltung = User (deploy/llama-swap.config.yaml ist fertig).
- **C2 gefixt:** Bildschirm-Sicht läuft jetzt IM Stream (SSE startet sofort, `hermes.vision.progress`-Event → Lucy kann Warte-Ansage sprechen); Vision-Timeout 120→45 s (MC_VISION_TIMEOUT).
- **C3 bewertet:** nur 2 Backend-Stellen mit unterschiedlicher Gating-Logik (dritte im separaten Mem0-venv) → kein Shared-Helper erzwungen, Pattern dokumentiert.
- **C5 war Fehlalarm** (s. Findings-Tabelle).
- **L2 gefixt:** TTS-Warm-Gate mit Retry/Backoff + sichtbarer Fehlermeldung (vorher: nach 120 s stumm „ready" ohne Stimme).
## 7. Nachtrag 2: P2/P3-Vollausbau (02.07., zweite Session-Hälfte)
**Brain-Config LIVE DEPLOYT + verifiziert (02.07., User-Freigabe):** hermes läuft mit `-c 131072 --parallel 2 -ctk/-ctv q8_0` + MTP. Gemessen: **2 gleichzeitige Requests laufen echt parallel** (~1,9 s/2,0 s statt seriell — Mem0-Extraktion blockiert Voice-Turns nicht mehr), tg 66 t/s (leichter parallel-2-Abschlag vs. 78 solo, bewusster Trade), RAM 40/122 GB. **Voice-E2E: neue Session 0,85 s total, first_content 803 ms** (Morgen-Baseline: 5,6–12 s bei neuen Sessions). capabilities werden via /v1/models ausgeliefert.
| Punkt | Ergebnis |
|---|---|
| **P2-11 Turn-Detection** | ✅ Smart Turn v3.2 (8 MB ONNX) im Voice-Sidecar (`/turn`, ~110 ms warm) + Semantik-Hold im Client (bei „unfertig" bis 1,8 s auf Fortsetzung warten). **Zwei Upstream-Fallen live diagnostiziert:** Audio muss LINKS gepadded werden (sonst konstant „complete"), und der Output ist P(unfertig) — entgegen der Doku. Verifiziert: fertig=0,74→true, mitten im Wort=0,04→false |
| **P2-12 F5 Phase C/D** | ✅ **Verdikt: Pocket bleibt.** F5-ONNX auf 9070 XT/DirectML: RTF 0,59@NFE32 / 0,30@NFE16 — aber nicht streamfähig (TTFA = ganze Satzdauer), NFE16-Qualitätsrisiko, GPU-Dauerbelegung. F5 taugt als Offline-Renderer, nicht für den Dialog-Loop |
| **P2-13a Refactor** | ✅ useVoiceAgent 397→305 Z; textPipeline/visionIntent/perf als pure Module |
| **P2-13b Electron** | ✅ 33→43 (Chromium 150/Node 24), Boot-Smoke-Test grün (allow-scripts-Falle: install.js manuell) |
| **P2-14 Cockpit/SystemDrawer** | ⏸ **bewusst vertagt:** reiner Qualitäts-Refactor von live deployter UI; braucht eine eigene Session mit Browser-Verifikation (MC_API_TARGET-Workflow) statt eines Blind-Splits am Session-Ende |
| **P3-15 Mem0 v3** | ✅ verifiziert aktiv (BM25/Entity/Hybrid in 2.0.8); mc2-memory nutzt jetzt `sync_turn(messages)` — lernt Tool-NAMEN mit (Ergebnisse bewusst nicht: Poisoning-Vektor). Deployt, Postcheck grün |
| **P3-16 llama-swap** | ✅ `capabilities` (in/out/tools/context) je Modell in deploy-Config; Swap-Matrix aktuell unnötig (brains-Gruppe reicht) |
| **P3-17 Kandidaten** | ✅ **Beide gebencht + als testbare Modelle live deployt** (ohne Alias-Wechsel — Qualitäts-Entscheid beim User): (1) **gpt-oss-120B: tg 54–55 t/s vs. heavy (Qwen3.5-122B) 23,5 t/s = 2,3× schneller bei 60 statt 73 GB** → klare Empfehlung für die heavy-Lane nach Deutsch-/Reasoning-Check (`model:"gpt-oss-120b"` am Gateway testen). (2) **Qwen3-VL-30B-A3B: tg 90–92 t/s** → Bildschirm-Sicht-Upgrade nach Screenshot-Check (`MC_VISION_MODEL=Qwen3-VL-30B-A3B-Instruct`); brains-Budget-Frage: 19 vs. 6 GB warm |
| **P3-18 Lemonade** | ✅ **Verdikt: nicht als Unterbau.** lemonade-sdk 9.1.4 (Python) installiert + Server lief (OpenAI-API, gute Registry inkl. gpt-oss/GLM) — aber: Python-Edition **offiziell deprecated** (C++-Installer ist der Weg), Server blockiert komplett während Model-Downloads (Health tot >10 min bei 400-MB-Modell), Ryzen-AI-Hybrid auf 9700X unsupported. **Empfehlung für den lokalen GPU-Klon: llama.cpp-Vulkan + llama-swap — derselbe Stack wie die Box** (ein Betriebsmodell, ein Know-how, bewährte Configs). Lemonade-C++ nur, falls Whisper+TTS+LLM aus einer Hand gewünscht |
| **MC3-Vollbau** | ⛔ außerhalb des Review-Scopes — eigenes Projekt (Prototyp steht unter #mc3) |
---
## 8. Nachtrag 3: Trennung, Update-Playbook, Radikal-Aufräumen (02.07., Abend)
**Lucy = eigenes Repo:** `F:\Coding Stuff\lucy` ↔ Gitea `Hitonabi/lucy` (privat; Repo via API angelegt). Verzeichnisnamen unverändert (lucy-desktop/ + lucy-tts/) → alle Pfade/BATs funktionieren; Boot aus neuem Pfad verifiziert. MC2 = reiner Box-Stack (+ hermes-pc-Executor). lucy-f5 (Verdikt final) und hermes-voice (Vor-Lucy) gelöscht — Historie bleibt in MC2.
**Hermes-Update-Playbook LIVE + E2E-verifiziert (7/7 PASS):** Update-Job = Backup → update → **doctor** → Restart → erweiterter Postcheck (**Config-Drift-Scan** im Journal, **Tool-Smoke** via echtem Agenten, **Voice-Smoke** mit Retries). Update-Modal fasst anstehende Commits künftig per fast-Modell zusammen (Breaking Changes zuerst, gecacht). Beim E2E-Test sofort geliefert: doctor fand eine **ausstehende Config-Schema-Migration** (altes flaches `model: hermes` → neues Schema; per `doctor --fix` migriert, Gateway verifiziert) und der Voice-Smoke entlarvte eine **pipefail/SIGPIPE-Falle** im eigenen Check (head schließt Pipe → curl 23 → Fehlalarm; gefixt). Außerdem behoben: `approvals.mode auto→smart` (v0.18-Regression, einfache Fragen 25 s → 2,0 s).
**Radikal aufgeräumt:** Git: lucy-v2 gemerged + gelöscht (lokal+Gitea), nur noch `main`; alter WIP-Stash gedroppt; stale Worktree entfernt. Lokal: lucy-f5-Assets (~5 GB), lemonade-eval, box_recon/gemma_swap-Scratch gelöscht. Box: 22-GB-Duplikat `Qwen3.6-35B-A3B-GGUF` (non-MTP) + 6 leere Modell-Hüllen gelöscht, v1-Altlasten (mission-control-*.db/json) nach mc2-backups/v1-legacy archiviert, /tmp-Bench-Scratch weg. Modell-Verzeichnis = exakt die 9 referenzierten Modelle + drafts + Backups.
---
*Erhoben am 02.07.2026 durch Claude Code (Live-SSH auf Box, lokale PC-Prüfung, 3 Codebase-Agents, 3 Web-Recherche-Runden). Messwerte: /api/voice/metrics (n=13 STT, n=18 chat_ttfb), TTFT-Direktmessung llama-swap :8080.*
@@ -0,0 +1,52 @@
# Antigravity-Review-Prompt — Mission Control 2.0
Prompt zum Einfügen in Antigravity 2.0 (Modell: **Gemini 3.1 Pro, High-Modus**). Projektordner =
dieses Repo. `.aiexclude` hält `.venv`/`node_modules`/`dist` aus dem Kontext.
---
Du bist ein erfahrener Senior-Reviewer und führst ein **vollständiges, ehrliches Code- und
Architektur-Review** dieses Projekts (Mission Control 2.0, kurz MC2) durch.
**Zuerst lesen — das ist der Rahmen, weiche nicht davon ab:**
1. `AGENTS.md` — die verbindlichen Projekt-Regeln.
2. `SAVEPOINT.md` — wo das Projekt gerade steht, Nordstern und Randbedingungen.
3. `README.md` und `docs/` — Kontext.
**Was MC2 ist:** die Web-Admin-Konsole einer **100 % lokalen** KI-Appliance (AMD Strix Halo, 128 GB,
llama.cpp-Vulkan). Backend = FastAPI (`backend/`, Dienst auf :9001), Frontend = React/Vite/Tailwind
(`frontend/`). Sidecars: `mem0_service/`, `voice_service/`, `mcp/`, `hermes/`, `client/`.
**Nordstern:** Das System muss **über Jahre ohne Wartung** laufen, betrieben von einem
**Nicht-Entwickler**. Robustheit, Einfachheit und Selbstheilung schlagen Features.
## Dein Auftrag
Prüfe das gesamte Repo (außer dem, was `.aiexclude` ausschließt). Suche gezielt nach:
- **Korrektheits-Bugs & Race Conditions** — besonders in `backend/services/` und den Routern.
- **Betriebs-Fragilität:** Was bricht bei **Reboot**, **Update** oder **Teil-Ausfall**? Was ist nicht
reboot-/idempotenz-fest? (Der Betreiber kann es nicht selbst debuggen.)
- **Sicherheitslücken** — Auth/Token-Handling, Command-Allowlists, Prompt-Injection-Guards,
Pfad-/Eingabe-Validierung, `sudo -n`-Nutzung. (Nur MELDEN, nichts an der Security-Config ändern.)
- **Ressourcen-Lecks & Fehlerbehandlung** — offene Clients/Dateien, verschluckte Exceptions,
fehlende Timeouts.
- **Toter/redundanter Code, DRY-/KISS-Verstöße, Über-Komplexität** — Vereinfachungs-Chancen.
- **Doku-/Realitäts-Drift** — Widersprüche zwischen `AGENTS.md`/Kommentaren und dem Code
(z. B. Zeitzone UTC vs. Europe/Berlin).
- **Wartbarkeit** — würde ein Fremder das in einem Jahr noch verstehen und sicher anfassen können?
## Harte Leitplanken (nicht empfehlen)
- KEINE Cloud-Migration, KEIN Voll-Rewrite, KEINE schweren neuen Frameworks.
- KEINE Modell-/Engine-Wechsel, die nicht in ~124 GB passen; keine Cloud-LLMs.
- `frontend/dist` bleibt bewusst im git (Box hat kein Node) — nicht als Fehler werten.
- Security-Config nur MELDEN, nie „einfach ändern".
- Bevorzuge **Vereinfachung und Härtung** vor neuen Features.
## Ausgabeformat (auf DEUTSCH)
1. **Gesamturteil** (3–5 Sätze): Wie gesund ist das Projekt? Trägt es den Nordstern „Jahre ohne Wartung"?
2. **Befunde, nach Schwere sortiert** — je Befund:
- Schweregrad **P0** (bricht/Sicherheit) · **P1** (echter Bug/Fragilität) · **P2** (Wartbarkeit) · **P3** (nice-to-have)
- `datei:zeile` · was ist das Problem · **warum es zählt** (konkretes Fehlszenario) · **konkreter Fix**
3. **Positives** — was bewusst gut gelöst ist (damit es nicht „wegoptimiert" wird).
4. **Was ich bewusst NICHT ändern würde** — und warum (Respekt vor den getroffenen Entscheidungen).
Sei ehrlich und konkret. Erfinde keine Probleme, um die Liste zu füllen. Wenn etwas gut ist, sag das.
+83
View File
@@ -0,0 +1,83 @@
# GEMINI-BRIEFING — Notfall- & Review-Partner für dieses System
_Für: Gemini via Google Antigravity (F:\-Checkout dieses Repos). Geschrieben 10.07.2026
in der Übergabe-Session, als das Claude-Abo auslief. Du bist der externe Zweit-Blick —
lies das hier KOMPLETT, bevor du irgendetwas empfiehlst oder änderst._
## Deine Rolle (User-Entscheid, bewusst eng)
**Notfall + Außen-Review. KEIN Großbau-Partner.**
Den Alltag (Features bauen, Wartung, Ideen umsetzen) macht die Box selbst über ihre
Ideen-Queue und Branch→Ampel→Merge-Pipeline. Du wirst gerufen, wenn:
1. **Notfall** — etwas ist kaputt und die Box kann sich nicht selbst heilen.
2. **Außen-Review** — ein Fremd-Blick auf Code/Architektur ist gewünscht
(das hast du am 05.07.2026 schon einmal sehr gut gemacht: 0 halluzinierte Funde).
Der User ist **kein Entwickler** (GUI-first, Terminal = Fremdkörper, Deutsch). Er kann dir
keine technischen Rückfragen beantworten — formuliere Optionen so, dass er mit
Ja/Nein/Klick entscheiden kann. Details: `docs/wissen/ARBEITSWEISE.md`.
## Pflicht-Lektüre in dieser Reihenfolge
1. `AGENTS.md` — verbindliche Projekt-Regeln (dist committen, Deploy-Weg, Deutsch-Regel …).
2. `docs/wissen/` — die kuratierte Projekt-Wahrheit:
[ZIELBILD](wissen/ZIELBILD.md) · [ARBEITSWEISE](wissen/ARBEITSWEISE.md) ·
[STACK](wissen/STACK.md) · [VERDIKTE](wissen/VERDIKTE.md) ·
[FALLEN](wissen/FALLEN.md) · [OFFENE-FAEDEN](wissen/OFFENE-FAEDEN.md).
3. Für Reviews zusätzlich: `docs/ANTIGRAVITY_REVIEW.md` (dein Review-Prompt) und
`SAVEPOINT.md` (Snapshot vom 05.07. — bei Widerspruch gewinnt `docs/wissen/STACK.md`).
## Was das System ist (ein Absatz)
Eine 100 % lokale KI-Appliance („die Box", AMD Strix Halo, 128 GB) mit llama.cpp-Vulkan +
llama-swap als Engine, Hermes-Agent als Runtime (Persona „Lucy"), MC2 (dieses Repo: FastAPI
+ React) als Web-Admin-Konsole, Mem0 als Gedächtnis, und einer Electron-Voice-Begleiterin
„Lucy" auf dem Windows-PC (EIGENES Repo `F:\Coding Stuff\lucy`). Die Box wartet sich selbst
(nächtliche Crons: Traum, Chef-Gutachter, Radar; Backups in 3 Schichten). Der Mensch ist das Gate für jede Code-Zeile.
## Harte Leitplanken (nicht verhandelbar)
- **Verdikte nicht neu aufrollen** ohne Messung/neuen Anlass — `docs/wissen/VERDIKTE.md`.
Insbesondere: keine Cloud, kein Rewrite, keine schweren Frameworks, kein Engine-Wechsel
ohne Bench, Hermes-Quellcode nie forken.
- **Security-Config (approvals/Tokens/ufw/sudoers) nur MELDEN, nie ändern.**
- **`frontend/dist` ist ABSICHT im Git** (Box hat kein Node) — kein Fehler.
- **Propose-only:** Änderungen als Branch/Diff vorschlagen; Merge+Deploy macht nur der User
(Ampel grün, dann `deploy.sh`).
- **Verifizieren vor Behaupten:** Behauptungen über Live-Verhalten nur nach echter Messung
auf der Box. Am 07.07. hat ein Gemini-Umbau Lucys STT still von Box-Parakeet auf
einkernigen PC-Whisper umgestellt und das Gegenteil behauptet — die Messung entlarvte es.
Das darf nicht wieder passieren: sag ehrlich, was du getestet hast und was nicht.
- Alles User-Sichtbare auf **Deutsch**.
## Notfall-Playbook (wenn du als Feuerwehr gerufen wirst)
1. **Erst Zustand lesen, nichts anfassen:**
`ssh hitonabi@192.168.178.151` · `curl -s http://127.0.0.1:9001/api/health` ·
`export XDG_RUNTIME_DIR=/run/user/$(id -u); systemctl --user status` ·
`journalctl --user -u <dienst> -n 100`. Alle IPs/Ports/Dienste: `docs/wissen/STACK.md`.
2. **Die Box hat Selbstheilungs-Netze — nutze sie, bevor du selbst baust:**
Zeitmaschine/Restore (`bash deploy/restore.sh --list`), Pin-Register
(`/srv/models/mc2-pins.json`), PBS-Backups, `docs/RUNBOOK.md` (Mensch-Anleitung),
`docs/DISASTER_RECOVERY.md` (Bare-Metal).
3. **Bekannte Stolperfallen zuerst prüfen** (`docs/wissen/FALLEN.md`): deploy.sh-Selbst-Reset,
leeres Warm-Set nach Config-Reload, XDG_RUNTIME_DIR, CRLF, stale index.lock, 64k-Floor.
4. Fix als kleinsten reversiblen Eingriff; vorher Backup (`bash deploy/backup.sh`);
danach `/api/health` + betroffene Funktion LIVE verifizieren; dem User in 2 Sätzen
auf Deutsch sagen, was war und was du getan hast.
## Review-Playbook
`docs/ANTIGRAVITY_REVIEW.md` als Prompt verwenden (P0–P3, „was NICHT ändern", Deutsch).
`.aiexclude` hält venv/node_modules/dist aus dem Kontext. Befunde mit `datei:zeile` +
konkretem Fehlszenario; bewusste Entscheidungen (dist im Git, flache JSON-Stores,
sync-Subprozesse, User-Units statt sudo) NICHT als Fehler werten.
## Wo du NICHT ran sollst
- `~/.hermes/config.yaml`-Security-Keys, ufw, sudoers, Tokens (nur melden).
- Lucys Voice-Lane-Diät (`platform_toolsets.api_server`) und das Warm-Set/brains —
Lucys ~1-s-Sprech-Latenz ist heilig.
- llama-swap-Neustarts ohne Not (Warm-Set weg = Lucy stumm/langsam).
- Der Wissens-Vault (`~/wissens-vault/`) gehört Lucys Lernkreislauf — lesen ja, umbauen nein.
@@ -0,0 +1,63 @@
# Zielbild: Die Ablösung (Richtungs-Entscheid 10.07.2026)
_Quelle: User-Interview in 3 Fragerunden, 10.07.2026. Überschreibt ältere Richtungs-Entscheide
(insbesondere D16 „MC2 Final/einfrieren")._
**Kernsatz des Users:** „Wenn ich neue Ideen habe, soll es die Box selbst machen und nicht du."
Das Claude-Abo wird **nicht verlängert**. Danach ist **Gemini via Antigravity** der Notfall- und
Review-Partner (siehe [GEMINI_BRIEFING](../GEMINI_BRIEFING.md)). Zeitfenster unklar → knapp
planen, **jede Session hinterlässt einen sauberen Stand**.
## Die 7 Entscheide (überschreiben ältere Verdikte!)
1. **MC2-Freeze AUFGEHOBEN** — „Freeze aufgehoben, MC2 lebt." Die Box baut neue Features direkt
in MC2, über die Queue→Karte→Klick-Pipeline. „MC2 Final/einfrieren" (D16) ist Geschichte;
Stabilität kommt aus **Gates + Zeitmaschine**, nicht aus Stillstand.
2. **Lucy (Electron-Voice-App) lebt weiter + volle Pipeline:** Idee → Queue → PC-Hermes baut/testet
auf F:\ → Karte → Klick = dist-Build + Neustart. Der PC-Annahme-Weg (Auftragsbuch-Gegenstück
für Lucy) muss GEBAUT und E2E BEWIESEN werden (Session S3). **LucyWatchdog bleibt WEG**
(User: „brauchen wir nicht mehr" — er startet sie selbst).
3. **EINE Ideen-Queue, Türen egal** — Telegram/Desktop/MC2 münden alle dort. Mechanik: Entscheid
nach Probe — erst natives Hermes-Kanban (`auto_decompose`, liegt ungenutzt in der Config)
ernsthaft testen, dann nativ vs. Auftragsbuch-Ausbau festlegen (Hermes-first-Regel).
4. **Bau-Ambition: auch Großes versuchen** — in Etappen über Tage, rauere Qualität ok, der User
ist das Gate, die Zeitmaschine fängt. Aus Fehlversuchen lernen (Skills destillieren).
5. **Bagatellen ohne Klick** — „Harmloses darf selbst". Konservative Klassen: Doku/Wiki/Vault/
Chronik/tote Dateien — **NICHTS mit Code-Logik; jede Code-Zeile bleibt Klick-pflichtig.**
Immer Morgenlage-Bericht + Zeitmaschine.
6. **Gemini-Rolle: Notfall + Außen-Review** — kein Großbau-Partner. Briefing-Paket liegt IM REPO
(`docs/GEMINI_BRIEFING.md`), nicht in Agent-Gedächtnissen.
7. **Wissens-Heimat für ALLE Agenten = `docs/` im MC2-Repo** (Box liest `~/mission-control-v2`,
Antigravity liest den F:\-Checkout — versioniert + deploybar). Der Vault bleibt Lucys
Lernschicht.
8. **Lucy = innere Stimme, kein Körper (04.09.2026, ergänzt Punkt 2).** Raphael-Umbau: Avatar,
Loft, Overlay, Mimik, Dazwischenrufe raus; ein HUD am PC, Telegram unterwegs, **eine Stimme**
für beide (`lucy-stimme.service` auf der Box). Kein zweites Hirn auf dem PC. Details, Reihenfolge
der Annahme und der SOUL.md-Vorschlag: [RAPHAEL.md](RAPHAEL.md).
9. **Auftragsbuch ausgebaut (04.09.2026).** Die Queue→Karte→Klick-Mechanik aus Punkt 2/3/5 war
seit 02.08. ungenutzt (Kanban-Tools seit 21.08. aus). Gate ist jetzt: Ampel grün + Merge durch
den User + `deploy.sh`. Bagatell-Annahme ohne Klick (Punkt 5) entfällt damit ebenfalls.
## Recherche-Fundament (10.07., Web)
Das Industrie-Muster 2026 ist exakt unsere Architektur: Issue → Agent → PR → Mensch-Gate, nie
Auto-Merge (GitHub Agentic Workflows; Stripe fährt ~1300 Agent-PRs/Woche über kontinuierliche
Pflege-Agenten aus einer Task-Queue). Lokal-Konsens: „supervised assistant" schlägt
Vollautonomie. → Uns fehlte nur die QUEUE davor + kontinuierliche Selbst-Aufträge.
## Das Ablösungs-Paket (4 Sessions, nach Unersetzlichkeit sortiert)
| Session | Inhalt | Stand |
|---|---|---|
| **S1 „uebergabe"** | Claude-Wissen kuratiert → docs/wissen/ · GEMINI_BRIEFING · Runbook „Wann Gemini rufen" · Termine als Box-Reminder · radar-selbstkritik-wrapper.sh ins Repo | ✅ 10.07.2026 (diese Session) |
| **S2 „queue"** | Kanban-Probe → Queue-Entscheid → Türen verdrahten (Telegram/Desktop-Idee → Queue) · Morgenlage meldet Queue-Stand · Bagatell-Nacht-Deploy-Pfad | offen |
| **S3 „lucy-pipeline"** | PC-Annahme-Weg bauen + E2E-Beweis. Kandidat für den ersten echten Auftrag: A4-Turncheck-Auswertung (Log liegt seit 07.07. in `C:\Users\TobisPC\lucy-turncheck.log`) | offen |
| **S4 „zuendung"** | Idle-Radar/Fehler→Auftrag (Traum-Funde + Journal-Muster → Queue-Kandidaten) · Großbau-Etappen-Regeln in Skills · Generalprobe ohne Claude | offen |
## Scan-Restposten (10.07., in die Sessions eingeplant)
Lucy-Repo-Hygiene (untracked venvs/Datasets, 2 tote Branches) · C13/0f Runbook/First-Run-Wizard ·
C14 stale v1-Unit · D16 c (System-Logs) / e (Mem0-Dubletten automatisch) / f (Politur) ·
Voice-Sidecar-Diät (Faden 6). **Watchdog = bewusst NICHT wiederherstellen.**
@@ -0,0 +1,164 @@
# UMBAUPLAN — Abschluss-Review 15.07.2026
**Was das ist:** Ergebnis des kompletten Projekt-Reviews (Repo + Box live + tagesaktuelle
Recherche). DIE Arbeitsliste für die Zeit nach Claude. Leser: der User, die Box-Worker
(über Queue-Karten) und Gemini/Antigravity (liest F:\-Checkout).
**Regel:** Erledigtes hier streichen. Neue Erkenntnisse einarbeiten, nicht daneben legen.
---
## 0 · IST-Befund (live verifiziert 15.07., 09:20–11:00)
**Die Box ist gesund und die Autonomie-Kette ARBEITET nachweislich.**
- Dienste: alle aktiv (mission-control-2, hermes-gateway, hermes-builtin-ui, mem0, voice, box-console, llama-swap). 8 Tage Uptime, 68 GB frei.
- Nacht-Crons 15.07. alle grün: Traum 03:15 · Selbst-Inventur 03:35 · Idle-Radar 03:45 · Karten-Gutachter 04:00 · Bagatell 04:10 · Chef-Gutachter 04:30 · Daily-Briefing 08:00 · Release-Radar Mo 05:15. Backups: mc2-backup 03:32 + PBS 03:50 gelaufen.
- Versionen: llama.cpp **b9994** (Vulkan) · llama-swap **v239** · Hermes **0.18.2** (+1 legitimer carried commit) · MC2 2.0.0-w8.
- Warm-Set schlank: Hirn 17,5 GB + embed 2 GB + reranker 2,2 GB ≈ 22 GB.
- Repo: lokal = Gitea = Box @ main. Live-Checkout wieder sauber auf `main`.
- **Autonomie-Beweis der Nacht 14.07.:** Idle-Radar erhob Journal-Befund (stop-sigterm-Timeout) → Decomposer zerlegte → werkstatt baute Restart-Skript+systemd-Override → betrieb testete live (~6 s Recovery) → done. Ohne Menschen, ohne Claude.
- **★ Nachmittags-Befund (Greenfield-Review + Live-Inspektion 15.07.):** JEDER LLM-Aufruf der Box läuft durch den EINEN MC2-Prozess auf :9001 — Lucys Haupt-Hirn (`model.base_url`, config.yaml ~Z. 430), alle auxiliary-Rollen (vision/curator/kanban_decomposer/triage_specifier), die komplette `delegation` (jeder Worker-Auftrag) und 3 MCP-Server (MC_URL). Der am häufigsten neu gestartete Dienst ist zugleich die Wirbelsäule des gesamten Stacks; das `Restart=always`-Override ist rückblickend ein Symptom dieser Kopplung. Konsequenz: **Abschnitt 3b · UMBAU v3.**
## 1 · Heute im Review erledigt (15.07.)
- ✅ **Hermes-Quelle wieder jungfräulich:** verwaister ~160-Zeilen-Patch in `gateway/platforms/api_server.py` entfernt (Bild-Beschreibung für Coder — war NIE aufgerufen = toter Code, wurde aber von jedem `hermes update` mitgeschleppt = Konflikt-Risiko fürs kommende v0.19). Original archiviert: `docs/archiv/hermes-api_server-vision-patch-verwaist.diff`.
- ✅ **Idee daraus regelkonform portiert → Bild-Weiche v2** (MC2-Gateway): Bild-Request an Coder-Ziel bekommt Vision-BESCHREIBUNG injiziert und bleibt beim Coder (Screenshot-Debugging!); Fallback = alte Umleitung. **Branch `wartung/bild-weiche-v2` → wartet als Karte auf Klick.**
- ✅ **VL-8B-Leiche gefixt:** `agents.vision.model: Qwen3-VL-8B-Instruct` (Modell existiert seit 07.07. nicht mehr!) → `vision`-Alias, in Top-Level- UND beiden Profil-Configs (Backups `*.bak-review-20260715`). Gateway neu, `hermes doctor` grün.
- ✅ **Live-Checkout aufgeräumt:** zurück auf `main` (stand auf verwaistem Branch), 2 stale Branches gelöscht, leere `state.db` + alter `backend/memory.py` entfernt.
- ✅ **2 Mess-Karten in der Queue:** `t_5ada48ea` (Gemma-4-Hirn-Bench) + `t_64a384b9` (heavy-64k-Messung).
- ✅ Blockierte Karte `t_8231d6b8` analysiert: **Arbeit ist fertig+live** — Worker vergaß nur den `kanban_complete`-Aufruf. Abschluss = Sofort-Paket a).
## 2 · Konfig-Bewertung: Das ist GUT so (nicht anfassen)
| Bereich | Urteil |
|---|---|
| Modell-Kader (8 Modelle, klare Rollen, schlankes Warm-Set) | ✅ passt zur 122-GB-Box; Recherche 15.07.: **kein** Qwen-Coder-Nachfolger draußen, Coder-Verdikt hält |
| Vulkan/RADV statt ROCm | ✅ hält (ROCm auf gfx1151 weiter „Preview", llama.cpp-Issue #21284 offen) |
| Fundament-Fixes (concurrency 1, auto_decompose true, Specifier-Pins, 3 Hooks je Profil) | ✅ live korrekt verifiziert |
| Verdikte Mem0 / Telegram / Electron / pocket-Default / Hermes-Prompts englisch | ✅ bleiben |
| DeepSeek V4-Flash als Kandidat | ❌ zu groß (103–142 GB Quant) — passt nie neben das Warm-Set |
| systemd-Override Restart=always für MC2 | ✅ behalten (User-Entscheid 15.07.) — gute Appliance-Praxis |
## 3 · SOFORT-Paket — ✅ KOMPLETT ERLEDIGT (Stand 15.07. abends, live verifiziert)
a) ✅ **Karte `wartung/bild-weiche-v2`** angenommen + E2E bestanden („Rot" vom Coder);
Bild-Weiche läuft inzwischen im eigenen mc2-gateway-Prozess (§3b P1), self-smoke
Check 5 spielt sie täglich durch. Test-Lehre: VL-Testbilder ≥256×256.
b) ✅ **Karte `t_8231d6b8`** abgeschlossen.
c) ✅ **sudo-Runde durch** (verifiziert 15.07. abends): v1-Unit + `/etc/systemd/system/
mission-control.service` + `/opt/mission-control` restlos weg (Faden C14 ✓);
`/usr/local/bin/llama-swap-warmup.sh` (root, 15.07. 10:16) byte-identisch mit
`deploy/warmup.sh` ✓.
d) ✅ **Daily-Briefing-Cron** auf ∞ gestellt (läuft täglich 08:00, zuletzt ok).
## 3b · UMBAU v3 — Architektur-Feinschliff (NEU 15.07. nachmittags)
**Woher:** Greenfield-Gedankenexperiment („wie sähe ein Komplett-Rework aus?") + Live-Inspektion
der Box. Ergebnis: KEIN Rewrite (die Box wartet sich nachweislich selbst — während der Inspektion
lief Karte `t_ab6754f1` und lud das Gemma-4-Bench-Modell), sondern vier Inkremente, die je für
sich Wert haben. Reihenfolge ist von der Topologie diktiert, nicht verhandelbar: P1 ent-riskiert
alles Weitere. Recherche-Verdikte dazu (15.07.): FastAPI bleibt (Litestar erwogen — Ökosystem/
Coder-Modell-Wissen gewinnen), React bleibt (Svelte/Solid schneller, aber irrelevant für
1-Nutzer-LAN), SSE ist 2026 der klare Dashboard-Standard (einweg, Auto-Reconnect, ~95 % der Fälle).
- **P1 · Gateway-Auszug** ✅ KOMPLETT (Stufe 1 deployt bf9fd80; **Stufe 2/Cutover gefahren
15.07. 21:26** — alle 14 Hermes-base_urls auf :9010, Backups `*.bak-gwcut-20260715-212606`):
Der /v1-Datenpfad wird eigener Prozess `mc2-gateway.service` (Loopback **:9010**,
`Restart=always`, gleicher Router-Code `routers/gateway_proxy.py`, neuer Einstieg
`backend/gateway_app.py`). MC2 :9001/v1 wird dünner Roh-Weiterleiter (`MC_V1_UPSTREAM` in der
Unit; Zeile entfernen = Rollback), damit LAN-Clients (IDE-Lane) nichts merken. Token-Zählung
passiert genau EINMAL (im Gateway); `token_stats.get_stats()` lädt bei Fremd-Änderung per
mtime nach (Steuerpult zeigt sonst eingefrorene Zahlen). **Stufe 2 = Unabhängigkeit:**
`deploy/gateway-cutover.sh` stellt ~/.hermes-Configs (Top-Level + beide Profile) von
`127.0.0.1:9001/v1` auf `127.0.0.1:9010/v1` um (Backups, `--revert`, bewusst NICHT im
deploy.sh — config.yaml ist Zwei-Schreiber-sensibel). Danach überlebt Lucys Hirn + die ganze
Nacht-Autonomie jeden MC2-Neustart. Postcheck prüft den Gateway mit (nur wenn Unit enabled).
**Prüf-Fahrplan — ALLE VIER ✅:** ① gw/health + Token-Call E2E · ② Repo-Wächter grün ·
③ Bild-Weiche-E2E durch den neuen Prozess (dabei Socket-Reuse-Bug im Vision-Unteraufruf
gefunden+gefixt d2398b3; self-smoke Check 5 prüft täglich; VL-Testbilder ≥256×256!) ·
④ **Stufe 2 gefahren + Abschlussbeweis bestanden (15.07. 21:27):** MC2 wurde mitten im
Betrieb neu gestartet, Lucys Denkpfad auf :9010 antwortete dabei durchgehend im
Sekundentakt HTTP 200 — null Aussetzer. Das Steuerpult ist ab jetzt absturz-egal für
Hirn, Crons und Worker. Rückweg bleibt: `gateway-cutover.sh --revert`.
- **P2 · Steward** ✅ AKTIV (angenommen + deployt 15.07. ~14:48, bc69cf5; Steward läuft,
Sentry-Ticks auf MC2+Gateway+Voice journal-verifiziert): Re-Warm-Wächter, Health-Sentry und
Mem0-Dedupe laufen als eigener Dienst `mc2-steward.service` (`backend/steward.py`,
Restart=always) — unveränderte Loop-Module, reiner Konfig-Split (MC2-Unit setzt die drei
ENABLED-Schalter auf 0; Zeilen entfernen = Rollback). Neu dadurch: Sentry überwacht erstmals
auch MC2 SELBST + den mc2-gateway (`MC_SENTRY_WATCH_MC2=1`) und meldet ein totes Steuerpult
per Telegram (Briefkasten-Abgabe an MC2 läuft per HTTP, `MC_ANNOUNCE_HTTP`); Warm-Nudge nach
Config-Änderung kommt aus einem mtime-Watch (5 s) statt In-Process. **Bewusst NICHT bewegt:**
reminders_loop (teilt Datei+CRUD mit /api/reminders — Zwei-Schreiber-Risiko) bleibt in MC2.
Danach gibt es genau ZWEI Zeitplan-Systeme mit klaren Rollen: systemd-Timer (Box-Pflege) +
Hermes-Crons (Agenten-Arbeit) — plus den Steward als dritten, eigenen Wächter-Prozess.
**Annahme-Hinweis (wichtig):** P2 ändert deploy.sh selbst → nach dem Klick EINMAL
`bash ~/mission-control-v2/deploy/deploy.sh` von Hand nachlaufen lassen. Grund =
Selbst-Reset-Falle: deploy.sh ersetzt sich beim `git reset` mitten im Lauf selbst, bash
liest dann einen alt/neu-Zeilen-Mix — genau daran hakte der P1-Deploy am 15.07.
(daemon-reload + Gateway-Start fielen aus, Lucy bekam 502; Heilung war daemon-reload +
`enable --now mc2-gateway` von Hand). P2 bringt den dauerhaften Fix mit (exec-Guard:
Skript führt sich nach dem Reset einmal frisch neu aus) + `TimeoutStopSec=5` für den
Gateway (Restarts rissen sonst 90-s-502-Fenster, weil uvicorn auf offene LLM-Streams
wartet). Ab dem P2-Deploy schützt der Guard alle künftigen Deploys automatisch.
- **P3 · Steuerpult-Modernisierung** (Kartenserie, reine UI/API-Arbeit, berührt nach P1 nie mehr
den Datenpfad): (a) EIN SSE-Eventstrom `/api/events` ersetzt die 53 `refetchInterval`-Poller in
`queries.ts`; (b) TanStack Router → echte URLs (`/modelle/coder`, `/auftrag/t_…`), Deep-Links,
Browser-Zurück; (c) TypeScript-Typen aus OpenAPI GENERIEREN (openapi-typescript) statt
handgepflegtem `api.ts` (stiller Drift-Fehlerherd).
- **P4 · State-Konsolidierung** (optional, NUR bei Schmerz): die 10 `mc2-*.json/jsonl` in
/srv/models → eine SQLite (WAL) mit Event-Tabelle (Chronik/Zeitmaschine = Abfragen statt
Eigenbau; Backup = eine Datei). Nutzen real, aber Risiko/Aufwand hoch — bewusst hinten.
**Bewusst NICHT geändert:** FastAPI, React/Vite/Tailwind, kein Electron, kein Chat in MC2,
LAN-Trust ohne Auth, Appliance-Philosophie (user-services, deploy.sh, Postcheck, Rollback).
## 4 · ROBUSTHEIT (Priorität 1 — Karten für die Queue)
- **R1 · Worker-Protokoll-Erinnerung** (klein): `box-steckbrief-inject.sh` um einen Satz ergänzen: „Am Ende IMMER kanban_complete oder kanban_block aufrufen — sauberes Text-Ende zählt nicht." Genau daran blockierte die Nacht-Karte.
- **R2 · Guard-Erweiterung systemd** (klein, braucht User-Ja): `tabu-pfade-guard.py` um `~/.config/systemd/user/` erweitern. Die Nacht-Werkstatt hat den Override direkt scharf geschaltet — ging gut, widerspricht aber „jede Code-Zeile ist Klick-pflichtig". Installation künftig nur über angenommene Karte.
- **R3 · Hermes v0.19 kommt** (Sammel-Release, ~660 PRs seit v0.18.0): Fangnetz existiert (autoupdate → doctor → postcheck → Auto-Rollback+Pin+Telegram). Quelle ist seit heute konfliktfrei. **Nichts zu tun — nur wissen, dass die Meldung kommen wird.**
- **R4 · Orchestrator-Worktrees raus aus /tmp** (klein): `/tmp/orch-kanten` überlebt keinen Reboot; Worktree-Basis nach `~/.hermes/orch-worktrees/` o. ä.
- **R5 · Runbook C13** (größter offener Robustheits-Batzen): 1-Seiter „Box tot → was drücken" + Bare-Metal-Bootstrap (docs/DISASTER_RECOVERY.md existiert als Konzept). Karten-Serie.
- **R6 · Backup-Restposten:** QNAP-/pve-root-Passwörter in Keepass verifizieren; Restore-Probe einmal fahren (PBS läuft, aber ungeprobt zurückgespielt).
## 5 · AUFRÄUMEN (Priorität 2)
- **A1 · Alt-Docs** (Bagatell-Klasse, Box darf selbst): README/STATUS/CUTOVER/HERMES_SETUP tragen Vor-Trennung-Stand (Faden C15).
- **A2 · Lucy-Repo-Hygiene** (PC-Karte über Lucy-Pipeline): 4 unkommittierte Dateien (Hybrid-TTS-Routing in App.tsx/useVoiceAgent/voice-core/kokoro_server) committen oder verwerfen — vorher prüfen, was live läuft; Saber-Altlasten löschen (XTTS-Datensatz-Verdikt: unbrauchbar); untracked venvs/Datasets ignorieren oder weg.
- **A3 · Hermes-Home-Kleinkram:** `hermes_cli/web_dist.bak-rootbuild/` + `.install_method` (harmlos, bei Gelegenheit).
- **A4 · D16-Restposten:** c) System-Logs ausbauen (Fehler-Filter) · e) Mem0-Dubletten automatisch statt Knopf · f) Lucy-Reste aus Web-UI + Voice-Sidecar-Diät. Alles einzelne Queue-Karten.
## 6 · FEATURES (Priorität 3)
- **F1 · Bild-Weiche v2:** gebaut, wartet auf Klick (Sofort-Paket a).
- **F2 · heavy auf 64k** (nach Messkarte `t_64a384b9` + User-Ja): dann `delegation`-Floor erfüllt → heavy als delegate_task-Ziel freischalten → Konzept-Fließband/Lucy nutzen heavy nativ statt worker.sh-Umweg.
- **F3 · Mini-Stimme v2 (AKTIV, User-Entscheid 15.07.):**
1. User: Colab-Volllauf (~3 h, Notebook `Lucy_Stimme_Training_v2.ipynb` auf Desktop, Volltraining-Modus ist schon eingestellt)
2. Danach: Modell-Datei tauschen + Whisper-Rücktranskriptions-Test (der EINZIGE ehrliche Richter) — kann PC-Hermes über die Lucy-Pipeline
3. A/B gegen pocket im Live-Gespräch → Default-Entscheid
4. **Zukunftsfaden v3:** Qwen3-TTS-**Instruct** kann inzwischen Stil/Emotion bei geklonten Stimmen steuern — genau das „alles klingt gleich"-Problem. Neuer Datensatz mit Emotions-Instruktionen, sonst gleiches Rezept.
- **F4 · Gemma 4 26B-A4B als Hirn-Kandidat** (nach Bench-Karte `t_5ada48ea`): Community meldet ~110 t/s mit MTP-Head (vs. ~66 heute), multimodal (könnte Hirn+Augen VEREINEN), 256k Kontext. ABER: gemma-Vorgeschichte (Cache-Bug #21468, „Fix" unbestätigt), KV nur f16 (RAM!), mmproj×MTP ungeklärt. **Nur mit Messbeweis + User-Ja — Hirn-Swap ist ein Groß-Ereignis mit Rollback-Plan.**
## 7 · TEMPO (Priorität 4)
- **T1 · ROCm-Recheck 20.–25.07.** (Box-Reminder #3 existiert): Stand 15.07. hält Vulkan (tg-Führung bestätigt, #21284 weiter offen). Falls ROCm 7.13+ liefert: NUR Hybrid für heavy/coder-Prefill erwägen, **Hirn bleibt Vulkan**.
- **T2 · hipEngine-Watch** (Reminder #4 existiert): weiterhin praktisch Qwen3.6-only, gfx1151 nur „initial pass" — beobachten, nicht adoptieren.
- **T3 · Faden 10** (spec-draft-Sweep): bleibt bewusst übersprungen (User 14.07.).
## 8 · Übergabe-Logik (wenn Claude weg ist)
1. **Neue Ideen** → eine der drei Türen (Telegram / Lucy / MC2-Ideenfeld) → Queue → Karte → dein Klick. Die Kette ist E2E bewiesen.
2. **Wissen** → `docs/wissen/` (dieser Plan, STACK, FALLEN, GRENZEN, VERDIKTE) — Box liest `~/mission-control-v2`, Gemini liest `F:\Coding Stuff\mission-control-2`. GEMINI_BRIEFING.md existiert.
3. **Pflege** → Auto-Update-Timer mit Rollback+Pin; Selfsmoke täglich; Alarmkette Telegram.
4. **Evolution** → Release-Radar (Mo) + Chef-Gutachter (täglich) + Traum (täglich) finden Chancen; Bench-Harnesses (brain-bench, model-bench) messen sie; du entscheidest per Klick.
5. **Notfall** → Gemini/Antigravity als Review-Partner (RUNBOOK „Wann Gemini rufen").
## 9 · Recherche-Quellen (15.07.2026)
- Strix-Halo-Benchmarks/Grid: [strix-halo-guide](https://github.com/hogeheer499-commits/strix-halo-guide) · [llm-tracker Strix Halo](https://llm-tracker.info/_TOORG/Strix-Halo)
- ROCm-Prefill-Issue: [llama.cpp #21284](https://github.com/ggml-org/llama.cpp/issues/21284) (offen)
- Gemma 4: [26B-A4B auf Strix Halo](https://akehir.com/blog/strix-halo-kubernetes-llm-gemma-4) · [Cache-Bug #21468](https://github.com/ggml-org/llama.cpp/issues/21468) · [unsloth GGUF](https://huggingface.co/unsloth/gemma-4-26B-A4B-it-GGUF) · [AMD Day-0](https://www.amd.com/en/developer/resources/technical-articles/2026/day-0-support-for-gemma-4-on-amd-processors-and-gpus.html)
- DeepSeek V4: [unsloth Doku](https://unsloth.ai/docs/models/deepseek-v4) (103–142 GB → zu groß)
- Hermes v0.19: [Releases](https://github.com/NousResearch/hermes-agent/releases)
- hipEngine: [shisa-ai/hipEngine](https://github.com/shisa-ai/hipEngine)
- Qwen3-TTS (Instruct/Emotion): [Qwen-Blog](https://qwen.ai/blog?id=qwen3tts-0115) · [Emotion-Diskussion](https://github.com/QwenLM/Qwen3-TTS/discussions/218)
@@ -0,0 +1,103 @@
# ÜBERGABE: Drei-Welten-Umbau (19.07.2026) — letzter Claude-Stand
> [!WARNING]
> **UPDATE (August 2026):** Der hier beschriebene "Zed + OpenCode CLI"-Workflow wurde durch das "Zero Middle-Layers"-Prinzip ersetzt. Coding passiert jetzt zu 100% in der **OpenCode Desktop** Agentic IDE via MCP. Die technischen Entscheidungen zur Box und zu Gitea bleiben jedoch gültig.
**Dieses Dokument ist die finale Übergabe der externen Claude-Sessions an die Box.**
Alles Wichtige aus dem Umbau vom 19.07. steht HIER (nicht nur im Claude-Gedächtnis,
das mit dem Abo-Ende unlesbar wird). Bei Widerspruch zu älteren Dokumenten gilt dieses.
## Die Architektur: Drei Welten, eine Brücke
| Welt | Rolle | Darf | Darf NICHT |
|---|---|---|---|
| **AI-Box** | Rechenzentrum: llama-swap, MC2 :9001, Gateway :9010, Gitea, Backups | bedient beide Welten | — |
| **Lucy = Autonome Box** | Chat/Stimme, mem0, Crons, Kanban-Fangnetz, **Betrieb-Bahn** | als EINZIGE Infra anfassen (SSH, Deploys, LXCs) | — |
| **Agentic IDE (PC)** | Vibe Coding: **Zed** (einziges Fenster) + OpenCode-CLI als unsichtbarer ACP-Motor | Code bauen in F:\Coding Stuff, Modelle via :9001/v1 | SSH/Infra (deny), mem0 (hat keins), Direkt-Push main |
**Brücke:** Gitea-Repos + Kanban-Karten. Deploy-Wünsche der IDE = geheimnisfreie
Playbook-Karte an `betrieb`. Beweis 19.07.: Homepage-Deploy auf LXC 106 in 92 s
(Karte t_36117427) — nach Nächten voller Schleifen davor.
## Was am 19.07. gebaut wurde (MC2-Commits `903f3bc`, `a1d7a4b`, `6b03a2c`)
1. **No-Progress-Bremse** (`deploy/agent-hooks/no-progress-bremse.py`, pre+post_tool_call,
registriert in Haupt-config + betrieb + werkstatt): 3× gleiches Ergebnismuster
(Zahlen/Hex wegnormalisiert, KEINE hartkodierten Strings) → mechanischer Block mit
Diagnose-Anweisung, Folgeversuch frei. terminal wird IMMER beobachtet (Fehler tarnen
sich dort als Erfolg), andere Tools nur bei status=error. State:
`~/.hermes/state/no-progress/`. **Neue Fehlermuster landen in
`neue-signaturen.jsonl` — Traum/Radar sollen daraus Playbook-Ergänzungen verdichten.**
2. **Schärfere native Guardrails:** `max_turns` 200→40, `hard_stop same_tool_failure` 8→4.
3. **Betrieb-Playbook-Skill** (`betrieb-playbook`, in allen Profilen): Triage-Regel
(Denken/Bauen/Betrieb) + SSH-Diagnose-Checkliste (Passphrase-Falle ZUERST:
`ssh-keygen -y -f <key> </dev/null`) + Deploy-Checkliste. Triage-Zeile auch im
Steckbrief-Hook.
4. **mem0 entlastet:** Lern-Extraktion gebündelt (4 Turns / 180 s idle = EIN Lauf statt
pro Turn — konkurrierte mit Lucys Hirn-Slots). Monatliche **Konsolidierung**
(`mem0-konsolidierung`, 3. um 06:40): legt Ähnliches zusammen, Widersprüche → neuester
gewinnt; Leitplanken hart im Code. Erster Lauf: 459→420 Fakten.
5. **Gedächtnis-Bereiche** statt zweitem mem0: neue Fakten tragen `bereich: alltag|projekt`;
`GET /memory?bereich=` filtert (Alt-Fakten laufen immer mit). Einmal-Cron
`gedaechtnis-check` (16.08. 09:10) prüft Schutt und legt bei Bedarf SELBST die
Werkstatt-Karte an — Bauauftrag komplett in `docs/wissen/GEDAECHTNIS-BEREICHE.md` (am 07.08.2026 gelöscht, Commit `c3851f8`; nur noch in der Git-Historie).
6. **Sicherheit:** Gitea-Registrierung AUS (app.ini `[service]` in CT 104 — Achtung:
`deploy/gitea_app.ini.example` setzt den Key fälschlich in `[security]`, Gitea ignoriert
das stumm!). ~157 GB Müll von der Box (u. a. 103 GB HF-Cache), Hermes Desktop komplett
vom PC (Persona-Backup: `F:\Coding Stuff\BAK\hermes-desktop-backup-2026-07-19`).
## Verdikte 19.07. (nicht neu aufrollen)
- **KEIN zweites mem0.** Coding-Gedächtnis = Repo (AGENTS.md, Code, Git, Karten).
- **EINE IDE-Umgebung = Zed.** OpenCode-Desktop wurde bewusst wieder entfernt.
Cline/Roo nur als Challenger nach Referenz-Messung (große Prompts = teuer auf Box-Physik).
Antigravity RAUS (keine lokalen Modelle). Hermes Desktop RAUS (zweite regellose Welt).
- **Phasen statt Modell-Ping-Pong:** heavy (60 G) + coder (20 G) passen nicht gleichzeitig
neben das warme Hirn; jeder Wechsel ~90–150 s. Erst planen (heavy), dann bauen (coder);
Erkundung über @explore (hermes, immer warm, gratis).
- **Zeit = Schleifen × Kontext.** Token sind Kosten. Kleiner Kontext + erster Versuch
sitzt schlägt jedes stärkere Modell.
## IDE-Welt: Pfade & Nutzung (PC)
- OpenCode-Config: `C:\Users\TobisPC\.config\opencode\opencode.json`
(Provider `aibox` → `http://192.168.178.151:9001/v1`; Agenten: `plan`=heavy READ-ONLY,
`build`=coder mit `ssh*: deny` + `git push: ask`, `explore`=hermes Subagent).
- Zed-Config: `%APPDATA%\Zed\settings.json` (`agent_servers.OpenCode` → voller Pfad zu
`opencode.exe acp` unter `%LOCALAPPDATA%\Microsoft\WinGet\Packages\SST.opencode_*`;
alter `bosgame`-Provider für Inline-Features bleibt).
- **Nutzung:** Zed öffnen → Projekt → Agent-Panel → „OpenCode"-Thread. Planen im
plan-Agent, dann build. Jedes Projekt = Gitea-Repo + `AGENTS.md` (Vorlage:
homelab-radar-Repo, Branch `dashboard/stand-2026-07-19`).
## Offene Fäden (Stand 19.07. abends)
1. ‼️ **sshd:** `50-cloud-init.conf` überstimmt `50-no-password.conf` (sortiert früher,
erster Wert gewinnt). Fix (sudo): Datei zu `00-no-password.conf` umbenennen + ssh
restart; Beweis: `sudo sshd -T | grep -i ^passwordauthentication` → `no`.
2. **Zed-Erststart ungetestet:** Installation+Config verifiziert, aber der allererste
OpenCode-Thread in Zeds UI wurde nie geklickt. Falls er hakt: `opencode` läuft auch
solo im Terminal des Projekts (gleiche Config).
3. **Referenz-Messung IDE** nach erster echter Nutzung: gleiche Aufgabe, Schleifen/
Wandzeit/Tokens notieren → endgültiges Werkzeug-Verdikt (vs. Zed-nativ, vs. Cline).
4. **heavy + OpenCode:** einmalig „peg-native format"-Fehler (llama.cpp-Tool-Parser,
transient, Retry half). Häuft es sich → Engine-Update über MC2 probieren.
5. **gedaechtnis-check** feuert 16.08. — Ergebnis beachten (Telegram).
## Abnahme bestanden (19.07. 14:55, Karte t_4dd12efb)
Der betrieb-Worker hat das komplette System in 168 s selbst auditiert: **6/6 technische
Blöcke PASS** (Dienste, Modelle+Hirn 0,29 s, mem0-Roundtrip+Bereichs-Filter, Crons 14/14
gesund, Timer/Ressourcen) und die Drei-Welten-Regel korrekt wiedergegeben. Höhepunkt:
Die **No-Progress-Bremse hat sich live am Worker selbst bewiesen** — er wich vom
Ein-Aufruf-Muster ab, produzierte identische Ergebnisse, wurde mechanisch geblockt und
hat statt zu schleifen diagnostiziert, aufgeräumt und ehrlich berichtet. Zusammen mit dem
92-s-Deploy (t_36117427) ist die Kern-These des Umbaus doppelt belegt.
Merkposten: Karten-Texte mit `$(…)`/Variablen NIE per unquotiertem Heredoc einspielen
(Shell expandiert sie — Karte t_36ff1dab musste deshalb verworfen werden); Datei + scp
oder quotiertes Heredoc benutzen.
## Historie (für Menschen, nicht für Worker)
Claude-Artifacts (nur solange Abo läuft): Stack-Audit
`claude.ai/code/artifact/c510cf49-…` · Finaler Plan `claude.ai/code/artifact/5a9ee13e-…`.
Die Essenz beider steht in DIESEM Dokument; nichts davon ist für den Betrieb nötig.
@@ -0,0 +1,146 @@
# gitea-workflow — Git- und Gitea-REST-API-Workflows
> **Kurz:** Wenn das Repo schreibgeschützt ist (Faden 8 / R2), arbeitet der Agent über einen sauberen Clone in `/tmp` und erstellt einen PR via Gitea-REST-API statt direkt zu pushen.
## Was der Skill tut
Der Skill beschreibt einen alternativen Git-Workflow für Fälle, in denen der direkte Schreibzugriff auf ein Repo blockiert ist (insbesondere das `mission-control-v2`-Repo unter Faden 8/R2). Statt direkt zu committen, wird:
1. Ein frischer Clone in `/tmp` erstellt.
2. Ein Feature-Branch von `origin/main` abgezweigt.
3. Änderungen im Clone gemacht, committet, gepusht.
4. Ein Pull Request via Gitea-REST-API auf `main` erstellt.
Das Ergebnis landet als Vorschlags-Branch auf Gitea — der Commander merged es selbst, wenn die Ampel grün ist.
## Wann er zum Einsatz kommt
| Situation | Aktion |
|---|---|
| Repo hat Schreibschutz (Faden 8 / R2) | Gitea-Workflow (diese Datei) |
| Neues Projekt wird vorbereitet | `gitea-repo-create.sh` + Gerüst aufbauen |
| Normaler Repo-Zugriff ist erlaubt | Direkter Git-Workflow (Branch → Commit → Push) |
## Konfiguration
### Zugangsdaten
- **Gitea-URL:** `https://git.tobisniceshomelab.ddnsfree.com`
- **User:** `Hitonabi`
- **Token:** In `.git-credentials` oder Config-Files hinterlegt (Scope `write:repository`)
- **Repo-Anlege-Token:** In `~/.config/gitea/create-token` (dediziertes `write:user`-Token)
### Token-Unterschied
| Token | Ort | Scope | Einsatz |
|---|---|---|---|
| Push/PR-Token | `~/.git-credentials` | `write:repository` | Branch-Push, PR erstellen |
| Repo-Anlege-Token | `~/.config/gitea/create-token` | `write:user` | **Nur** Repo-Anlage über `gitea-repo-create.sh` |
Ein Repo kann **nur** mit dem `write:user`-Token angelegt werden — der Push-Token reicht nicht. Nie per Roh-`curl` erzwingen.
## Arbeitsablauf (Schritt-für-Schritt)
### 1. Sauberen Clone erstellen
```bash
cd /tmp && rm -rf <repo>-temp && git clone https://USER:TOKEN@git.tobisniceshomelab.ddnsfree.com/USER/<repo>.git <repo>-temp
```
### 2. Branch von origin/main erstellen
```bash
cd /tmp/<repo>-temp && git checkout -b <branch-name> origin/main
```
Branch-Namen mit `/` (z. B. `doku/gitea-skill`) funktionieren.
### 3. Files kopieren, committen
```bash
cp <quelle> <repo>-temp/<pfad>
git add <pfad> && git commit -m "<commit-nachricht>"
```
### 4. Pushen
```bash
cd /tmp/<repo>-temp && git push origin <branch-name>
```
### 5. PR via REST API erstellen
```bash
curl -sL -X POST "https://git.tobisniceshomelab.ddnsfree.com/api/v1/repos/<owner>/<repo>/pulls" \
-H "Authorization: token <TOKEN>" \
-H "Content-Type: application/json" \
-d '{"title": "<PR-Titel>", "body": "<PR-Body>", "head": "<branch-name>", "base": "main"}'
```
### 6. Main-SHA abrufen (falls nötig)
```bash
curl -sL "https://git.tobisniceshomelab.ddnsfree.com/api/v1/repos/<owner>/<repo>/git/refs/heads/main" \
-H "Authorization: token <TOKEN>"
```
## Neues Projekt vorbereiten (seit 17.07.2026)
Bei einem neuen Projekt wird nicht nur der Workflow angewendet, sondern das komplette Gerüst gelegt:
1. **Repo anlegen** (privat, initialisiert):
```bash
~/.hermes/scripts/gitea-repo-create.sh <name> "<Kurzbeschreibung>"
```
Die letzte Ausgabezeile ist `CLONE <URL>` — diese merken.
2. **Lokal klonen**:
```bash
git clone <clone-url> /tmp/<name> && cd /tmp/<name>
```
3. **Dateistruktur aufbauen** (nur das Gerüst):
- `README.md` mit Ziel/Scope
- `.gitignore` passend zur Sprache
- Grundordner (`src/`, `docs/`, `tests/`) mit Platzhaltern
- `AGENTS.md` (Projekt-Kontext für spätere Desktop-Arbeit)
- Kein fertiger Code — nur das Skelett, das der Commander in Hermes Desktop weiterbaut
4. **Committen + pushen**:
```bash
git add -A && git commit -m "Projekt-Gerüst: Struktur + README" && git push
```
5. **Clone-Fallback** (wenn Zielordner schon existiert):
```bash
git rm -r --cached . 2>/dev/null; rm -rf .git
git init && git remote add origin <url>
git fetch origin
git checkout -b main origin/main
git checkout origin/<branch> -- .
```
6. **Übergeben**: Commander die Repo-URL melden + kurz beschreiben, was vorbereitet wurde.
## Pitfalls
| Falle | Vermeidung |
|---|---|
| Blobs direkt über `/git/blobs` erstellen → 404 | Niemals; immer `git add` + Commit nutzen |
| Push/PR-Token reicht nicht für Repo-Anlage | `gitea-repo-create.sh` mit `write:user`-Token nutzen |
| Repo-Anlage per Roh-`curl` erzwingen | Nie — Token-Berechtigungen sind serverseitig, das Skript ist der einzige Weg |
| Grosse Dateien am Stück lesen → Kontext sprengt | Gezielt lesen über Zeilenbereiche (`read_file` mit offset/limit) |
| Direkt in Live-Checkout schreiben → Faden 8 | Immer im frischen Klon arbeiten, Vorschlagsbranch via PR |
## Konsistenz mit MC2-Konventionen
- **Sprache:** Deutsch, direkt, kein Marketing-Sprech.
- **Struktur:** Kurze Beschreibung → Wann einsetzen → Konfiguration → Arbeitsablauf → Pitfalls → Konsistenz.
- **Querverweise:** Verweise auf Faden 8/R2, Auftragsbuch, `gitea-repo-create.sh`.
- **Tabellen:** Wo sinnvoll (Situationen, Konfiguration, Pitfalls) als Tabelle formatiert.
- **Code-Blöcke:** Alle Befehle als bash-Code-Blöcke mit klaren Variablen-Platzhaltern.
- **Keine Secrets:** Tokens werden referenziert (Ort), nicht ausgeschrieben.
---
_Diese Datei wurde als Skill-Dokumentation im MC2-Repo erstellt. Sie ist Teil der Skills-Docs in `docs/skills/`._
+94
View File
@@ -0,0 +1,94 @@
# Hermes-Schicht — Box-Runbook
> Diese Schritte laufen **auf der Bosgame** (`192.168.178.151`, User `hitonabi`).
> MC betreibt Hermes nicht — es zeigt nur Status + verlinkt das WebUI. Hier wird die
> eigentliche **volle Verdrahtung** gemacht (das war in v1 der „Hermes ist dumm"-Grund).
## Reihenfolge der Dienste
`llama-swap (:8080)` → **builtin Gateway (`:9001/v1`, Teil von MC2)** → `hermes-gateway (:8642)` →
`hermes-webui (:8787, nesquena)`
## 1. Gateway = builtin (kein LiteLLM)
LiteLLM scheitert auf Python 3.14 (uvloop/orjson). MC2 bringt einen **eingebauten** OpenAI-kompatiblen
Gateway auf `:9001/v1` mit: `model: auto` (kurz→`fast`, komplex→`heavy`) + explizite Aliase
(`fast`/`heavy`/`coder`/`vision`/`hermes`). Verifizieren:
```bash
curl -s http://127.0.0.1:9001/v1/models
```
## 2. Engine: Rollen (llama-swap)
Aliase sauber: `fast` (Qwen3.6-35B-A3B), `heavy` (Qwen3.5-122B-A10B), `coder`, `vision`, `scout`,
`hermes` (Hermes-4-14B, `ttl 99999` = immer warm). Verwaltung im Cockpit (Modelle & Routing).
**Ko-Residenz** (optional): Gruppe `swap:false` für `hermes`+`fast` → beide warm; `heavy`/`vision`
on-demand. GTT beobachten (~124 GB Limit).
## 3. Hermes Desktop (PC) anbinden — die Agent-Oberfläche
> Historie: früher lief hier das nesquena-hermes-webui (:8787), danach der „Hermes GUI"-Tab in
> MC2. Beides ist seit 09.07.2026 abgebaut — die Agent-Oberfläche ist die **Hermes-Desktop-App**
> am Windows-PC; auf der Box bleibt nur `hermes-builtin-ui` (:9119, loopback) als **Desktop-Gateway**
> (Unit kommt aus `deploy/deploy.sh`).
**Auf der Box (einmalig):** statischer Session-Token, damit die App Dienst-Neustarts/Deploys übersteht:
```bash
mkdir -p ~/.config/systemd/user/hermes-builtin-ui.service.d
# session-token.conf: [Service] + Environment=HERMES_DASHBOARD_SESSION_TOKEN=<zufallswert>
# Wert zusätzlich nach ~/.hermes/desktop-gateway-token legen (chmod 600 auf beide Dateien)
systemctl --user daemon-reload && systemctl --user restart hermes-builtin-ui
```
**Am PC:** `Hermes-Setup.exe` (hermes-assets.nousresearch.com) installieren, dann in
`%APPDATA%\Hermes\connection.json` den Remote-Modus setzen:
```json
{ "mode": "remote",
"remote": { "url": "http://192.168.178.151:9001/hermes-ui",
"authMode": "token",
"token": { "encoding": "plain", "value": "<Wert aus ~/.hermes/desktop-gateway-token>" } } }
```
Die URL läuft über den **bestehenden MC2-Proxy** (`/hermes-ui/*` inkl. WebSockets) — kein neuer
Port, keine neue Firewall-Freigabe. Alternativ in der App: Settings → Gateway. Desktop-Sessions
nutzen das volle `cli`-Toolset; die schlanke `api_server`-Lane (Lucy/Voice) bleibt unberührt.
Token-Werte gehören NIE in Doku/Git — nur die Pfade.
## 4. Hermes-Hirn = dediziertes Hermes-4-14B + Delegation (NICHT model:auto)
In `~/.hermes/config.yaml`:
```yaml
model:
default: Hermes-4-14B
provider: custom
base_url: http://127.0.0.1:9001/v1
api_key: local
model: hermes # Hermes' eigenes Hirn (Alias→Hermes-4-14B), NICHT 'auto'
delegation:
model: heavy # harte Teilaufgaben → Qwen3.5-122B
provider: custom
base_url: http://127.0.0.1:9001/v1
api_key: local
orchestrator_enabled: true
subagent_auto_approve: true
```
`model:auto` bleibt ausschließlich Gateway-Funktion für Vibe Coding/IDEs.
## 5. Tools/MCP verdrahten — UND kaputte Tools abschalten (Thrash-Fix!)
- **Kaputte/Cloud-Tools global abschalten** (sonst Endlos-Loops, siehe Memory `hermes-thrash-rootcause-fix`):
```yaml
agent:
disabled_toolsets: [vision, computer_use, image_gen, tts, video, video_gen]
memory:
memory_enabled: true
user_profile_enabled: true
```
⚠️ `hermes tools disable <x>` wirkt nur für die cli-Plattform, **nicht den api_server** — nutze
`agent.disabled_toolsets` (gilt für ALLE Plattformen).
- **Behalten:** terminal/shell, file, code_execution, skills, todo, session_search, clarify,
delegation, cronjob, web, browser, memory. `approvals: auto` (rein lokal).
- **MCP-Server** (`mcp_servers` in config) — laufen über die v2-venv (hat das `mcp`-Modul nach pip install):
- geteiltes Gedächtnis: `~/mission-control-v2/backend/.venv/bin/python ~/mission-control-v2/mcp/mcp_memory.py` (Env `MC_URL=http://127.0.0.1:9001`)
- Stack-Management: `~/mission-control-v2/backend/.venv/bin/python ~/mission-control-v2/mcp/mcp_mc.py` (Env `MC_URL=http://127.0.0.1:9001`)
- **SSH→Windows-PC** (voller Zugriff): OpenSSH-Server auf Windows aktiv + Key
`~/.ssh/id_ed25519_hermes_agent` autorisiert; Hermes nutzt sein terminal-Tool für `ssh TobisPC@<win-ip>`.
## 6. Verifikation
- `curl :8642/v1/chat/completions` „bist du da?" → kurze Antwort in wenigen Sekunden, **kein** Tool-Loop
im `journalctl --user -u hermes-gateway`; llama-swap `/running` zeigt `Hermes-4-14B`.
- WebUI öffnet vom Windows-PC, Chat antwortet.
- Hermes kann via `mcp_mc` Modelle listen/Routing ändern; erreicht (nach §5-SSH) den Windows-PC.
+62
View File
@@ -0,0 +1,62 @@
#!/usr/bin/env bash
# Referenz-Check (20.08.2026): prueft die fuenf Fertig-Kriterien der Messlatte.
#
# Zweck: "fertig" darf keine Auslegungssache sein. Derselbe Befehl fuer den Agenten
# (Selbstpruefung) und fuer die Auswertung. Siehe docs/aufgaben/referenzaufgabe-mem0-ausbau.md
#
# Aufruf: bash docs/aufgaben/referenz-check.sh [worktree-pfad]
# Exit: 0 = alle Kriterien gruen · 1 = mindestens eines rot
set -uo pipefail
W="${1:-$HOME/projekte/mc2-referenz}"
LINT="${LINT_RUFF:-$HOME/.venv-lint/bin/ruff}"
PY="${BACKEND_PY:-$HOME/mission-control-v2/backend/.venv/bin/python}"
SMOKE="${SMOKE_SH:-$HOME/mission-control-v2/deploy/self-smoke.sh}"
ROT=0
pruef() { # $1=Nummer $2=Beschreibung $3=Ergebnis(0/1) $4=Detail
if [ "$3" -eq 0 ]; then printf ' %s %-34s GRUEN %s\n' "$1" "$2" "${4:-}"
else printf ' %s %-34s ROT %s\n' "$1" "$2" "${4:-}"; ROT=1; fi
}
[ -d "$W" ] || { echo "ABBRUCH: Worktree nicht gefunden: $W"; exit 1; }
echo "=== Referenz-Check ($W) ==="
# 1 — Lint
if [ -x "$LINT" ]; then
out="$("$LINT" check "$W" 2>&1)"; rc=$?
pruef 1 "Lint sauber (ruff)" $rc "$(printf '%s' "$out" | tail -1)"
else
pruef 1 "Lint sauber (ruff)" 1 "ruff fehlt unter $LINT"
fi
# 2 — Backend laedt
out="$(cd "$W/backend" && "$PY" -c 'import app' 2>&1)"; rc=$?
pruef 2 "Backend importierbar (app)" $rc "$(printf '%s' "$out" | tail -1)"
# 3 — keine mem0-Reste (docs/ ausgenommen: Historie)
n="$(cd "$W" && grep -ril mem0 backend/ mcp/ deploy/ --include='*.py' --include='*.sh' 2>/dev/null | wc -l)"
[ "$n" -eq 0 ]; rc=$?
pruef 3 "Keine mem0-Reste" $rc "$n Datei(en) mit Treffern"
[ "$n" -gt 0 ] && (cd "$W" && grep -ril mem0 backend/ mcp/ deploy/ --include='*.py' --include='*.sh' 2>/dev/null | sed 's/^/ /')
# 3b — der Sidecar-Ordner selbst
if [ -d "$W/mem0_service" ]; then pruef "3b" "Ordner mem0_service entfernt" 1 "liegt noch da"
else pruef "3b" "Ordner mem0_service entfernt" 0; fi
# 4 — Selbsttest (laeuft gegen das LAUFENDE System, nicht gegen den Worktree)
if [ -r "$SMOKE" ]; then
out="$(timeout 540 bash "$SMOKE" 2>&1)"; rc=$?
pruef 4 "Selbsttest self-smoke" $rc "$(printf '%s' "$out" | grep -cE '\bPASS\b') PASS / $(printf '%s' "$out" | grep -cE '\bFAIL\b') FAIL"
else
pruef 4 "Selbsttest self-smoke" 1 "nicht lesbar: $SMOKE"
fi
# 5 — MC2 lebt
curl -s -m 8 localhost:9001/api/health 2>/dev/null | grep -q '"status":"ok"'; rc=$?
pruef 5 "MC2 gesund" $rc
echo
if [ $ROT -eq 0 ]; then echo " ERGEBNIS: FERTIG — alle Kriterien gruen."
else echo " ERGEBNIS: NICHT fertig — mindestens ein Kriterium ist rot."; fi
exit $ROT
@@ -0,0 +1,133 @@
# Referenzaufgabe: Mem0-Sidecar restlos ausbauen
> **Zweck dieser Datei:** Messlatte für den Stack-Umbau (Stufe 2, 20.08.2026). Dieselbe Aufgabe wird
> mehrfach mit verschiedenen Modellen gefahren. Gemessen wird **nicht** Tokens pro Sekunde, sondern:
> *Wurde sie fertig? Wie lange? Wie viele Züge?*
> Alle Pfade und Befehle unten sind am 20.08.2026 auf der Box **nachgemessen**, nicht geraten.
## Hintergrund
Mem0 wurde im August abgelöst (`bf145a3`, `eb4bcfc`, `2286879`). Der Rückbau blieb unvollständig:
Der Sidecar-Ordner liegt noch im Baum, MC2 fragt weiterhin einen toten Port ab.
Gemessen: `curl http://127.0.0.1:8765/health` → **keine Antwort**. Kein systemd-Dienst dafür,
`/srv/models/mem0` bereits entfernt. Es ist also wirklich tot, nicht nur gerade aus.
## Arbeitsplatz
**Isolierter Worktree — NICHT das Live-Deployment:**
```
~/projekte/mc2-referenz Zweig: referenz/mem0-ausbau
```
`~/mission-control-v2` bleibt auf `main` und bedient weiter den laufenden Dienst auf `:9001`.
**Dort nichts ändern.**
## ‼️ Arbeitsweise — zuerst lesen
**Arbeite Datei für Datei. Lies HÖCHSTENS zwei Dateien, bevor du die erste änderst.**
Nach jeder geänderten Datei gehst du zur nächsten. **Kein Gesamtplan, keine Vollinventur vorab** — du
darfst jederzeit nachlesen, wenn du etwas brauchst. Die Liste unten ist eine Landkarte, keine
Leseliste.
*Warum das hier so deutlich steht:* Im ersten Anlauf (20.08., über Nacht) hat der Agent in sechs
Sitzungen ~336 Nachrichten und ~360.000 Tokens verbraucht, 19 Dateien gelesen — und **nicht eine
einzige Zeile geändert**. Er lief fünfmal in dasselbe Muster: „Ich habe jetzt das vollständige Bild,
jetzt lese ich nur noch die restlichen Dateien, *bevor ich anfange*." Dann war das Zug-Limit
erreicht. Sein eigenes Fazit: *„Iterationslimit erreicht, bevor ich die erste Zeile geändert habe."*
Eine halbfertige Änderung ist wertvoller als eine vollständige Analyse ohne Änderung.
## Auftrag
Entferne die Mem0-Reste vollständig, ohne etwas anderes kaputtzumachen.
**17 Dateien haben Treffer** (gemessen 20.08., selbst nachprüfen statt blind vertrauen):
```
backend/steward.py deploy/stack-postcheck.sh
backend/config.py deploy/venv-audit.sh
backend/routers/voice.py deploy/agent-hooks/box-steckbrief-inject.sh
backend/routers/system.py deploy/warmup.sh
backend/routers/zeitmaschine.py deploy/autoupdate.sh
backend/services/sentry.py deploy/hermes-postcheck.sh
backend/services/voice_metrics.py deploy/restore.sh
backend/services/backup.py deploy/backup.sh
mcp/mcp_mc.py
```
Dazu der Ordner `mem0_service/` (app.py, migrate.py, requirements.txt, smoke_test.py).
> ‼️ **Der eigentliche Prüfstein:** Wenn eine API-Antwort ein Feld wie `mem0_reachable` liefert, das
> das Frontend liest, darf es nicht einfach verschwinden — sonst bricht die Oberfläche. Entweder das
> Frontend mit anpassen oder das Feld sauber entfernen. Wer nur `grep mem0` laufen lässt und alles
> wegwirft, produziert eine Fassade.
## Fertig-Kriterien
Ausgangswert am 20.08.: **1, 2, 4, 5 sind bereits grün** — sie sind Schutzgeländer, nicht die Arbeit.
Nur Kriterium 3 ist offen. Wer 3 erfüllt und dabei 1/2/4/5 kaputtmacht, hat versagt.
| # | Prüfung | Befehl | Ausgangswert |
|---|---|---|---|
| 1 | Lint sauber | `cd ~/projekte/mc2-referenz && ~/.venv-lint/bin/ruff check .` | ✅ *All checks passed* |
| 2 | Backend lädt | `cd ~/projekte/mc2-referenz/backend && ~/mission-control-v2/backend/.venv/bin/python -c "import app"` | ✅ ok |
| 3 | **keine mem0-Reste** | `cd ~/projekte/mc2-referenz && grep -ril mem0 backend/ mcp/ deploy/ --include='*.py' --include='*.sh' \| wc -l` | ❌ **17** → muss **0** werden |
| 4 | Selbsttest grün | `bash ~/mission-control-v2/deploy/self-smoke.sh` | ✅ grün |
| 5 | MC2 gesund | `curl -s localhost:9001/api/health` | ✅ `"status":"ok"` |
Treffer in `docs/` sind erlaubt — das ist Historie und darf stehenbleiben.
Selbstprüfung mit einem Befehl:
```bash
bash ~/projekte/mc2-referenz/docs/aufgaben/referenz-check.sh
```
> Der Prüfbefehl liegt bewusst unter `docs/aufgaben/` und **nicht** unter `deploy/`. Im ersten Anlauf
> lag er in `deploy/`, enthielt selbst siebenmal das Wort „mem0" (er sucht ja danach) und zählte sich
> damit in Kriterium 3 mit — das Kriterium war unerfüllbar. In `docs/` wird er nicht durchsucht.
## Randbedingungen
- ‼️ **In einer FRISCHEN Sitzung starten**, nicht in einer fortgesetzten. Beim ersten Anlauf hat der
Desktop eine Sitzung vom Vortag weitergeführt und deren Kontext mitgeschleppt — die Messung war
dadurch wertlos. Im Desktop also einen **neuen Chat** anlegen, nicht den alten öffnen.
- **Nicht pushen.** Der Zweig bleibt lokal, damit der Lauf wiederholbar ist.
- **Nichts außerhalb des Worktrees anfassen** — kein `/etc`, keine systemd-Dienste, kein Neustart.
- Wenn ein Kriterium nicht erfüllbar ist: **ehrlich sagen und aufhören.** Ein klares
„Kriterium 3 scheitert an X" ist wertvoller als ein beschönigter Abschluss.
## Zurücksetzen zwischen den Läufen
```bash
cd ~/mission-control-v2
git worktree remove --force ~/projekte/mc2-referenz
git branch -D referenz/mem0-ausbau
git worktree add -b referenz/mem0-ausbau ~/projekte/mc2-referenz main
```
## Messprotokoll
| Lauf | Aufbau | Fertig? | Wanduhr | Züge | Bemerkung |
|---|---|---|---|---|---|
| — | *Fehlversuch 20.08. 21:10* | ✗ | 76 min, abgebrochen | 8 | Kriterium 3 unerfüllbar + fortgesetzte Alt-Sitzung. **Verwertbar trotzdem:** 19.899 Ausgabe-Tokens, davon nur ~2.600 Zeichen sichtbar → **>95 % unsichtbares Nachdenken**. Kompression feuerte bereits. |
| **A** | Qwen3.8-27B, `medium`, `max_turns: 40`, ohne Arbeitsanweisung | ✗ | über Nacht | 6 Sitzungen, ~336 Nachrichten | **0 Dateien geschrieben.** Analyse-Schleife, Zug-Limit erreicht. Werkzeug `file` war die ganze Zeit verfügbar, wurde nie benutzt. ~360k Tokens. Inhaltlich gut: fand `mem0_ms` im Frontend **und** einen toten `memory_svc`-Import in `steward.py`. |
| **A2** | dasselbe, **+ Arbeitsanweisung oben**, `max_turns: 80` | | | | ← **als Nächstes.** Prüft, ob die Schleife am Auftrag lag |
| D | Qwen3.8-27B, `reasoning_effort: low` | | | | Nächster Hebel, falls A2 auch nur liest |
| B | Qwen3.8-27B **+ DFlash-2** | | | | Entwurfsmodell liegt bereit |
| C | Qwen3.6-35B-A3B (`fast`, 95,7 t/s) | | | | SWE-bench 73,4 |
> ★★ **Die Lehre aus Lauf A:** Das ist **kein Tempo-Problem.** Mit 95 t/s statt 12,6 wäre derselbe
> Lauf genauso gescheitert — nur schneller. Deshalb kommen A2 und D **vor** den Modellwechseln B und C.
### Was der Fehlversuch schon gezeigt hat
Pro Zug erzeugte das Modell ~2.487 Tokens, sichtbar wurden davon 181–451 Zeichen. Bei 12,6 t/s sind
das ~26 Minuten reine Erzeugung für ~2.600 Zeichen Text. **Der Engpass ist Denk-Aufwand × Bandbreite,
nicht das Harness.** Darum Lauf D vor B und C: er prüft den billigsten Hebel zuerst.
Inhaltlich war das Modell gut — es fand von selbst den Prüfstein (`mem0_ms` → `memory_ms` im Frontend),
statt blind zu löschen.
+57
View File
@@ -0,0 +1,57 @@
# Savepoint — Mission Control 2.0 (MC2)
_Stand: 2026-08-20, nach der Aufräum-Runde. Alle Zahlen hier sind **auf der Box gemessen**, nicht
aus Doku übernommen._
## Was das ist (in einem Satz)
MC2 ist die **Web-Admin-Konsole** einer 100 % lokalen KI-Appliance („die Box", Bosgame M5 / AMD
Strix Halo, 128 GB Unified RAM, llama.cpp-Vulkan). Sie verwaltet Engine, Modelle, Gedächtnis,
Agenten-Status, Updates & Wartung — und dient als Steuerpult für die autonome KI („Lucy").
## Architektur (Kurzform — Details in AGENTS.md/docs/)
- **Backend** `backend/` — FastAPI, `:9001` als systemd-**User-Dienst** (reboot-fest, sudo-frei).
- **Frontend** `frontend/` — React/Vite/Tailwind/shadcn. **`frontend/dist` ist ABSICHT im git**
(Box hat kein Node; Backend liefert die gebauten Assets direkt aus).
- **MC2-Gateway** `:9010` (`/v1`-Datenpfad, model:auto Routing + native Bildweiche).
- **Modell-Router** `:8080` (llama-swap v250, Vulkan/RADV Engine b10502).
- **Hermes Agent** `:8642` (`hermes-gateway`, v0.20.4) + `hermes dashboard` auf `:9119` (nur Loopback).
- **Sidecars:** `voice_service/` (:8650, faster-whisper STT + Piper TTS), `mcp/` (4 MCP-Server),
`client/hermes-pc` (PC-Executor :7777).
‼️ `mem0_service/` liegt noch im Baum, ist aber **stillgelegt** — `:8765` antwortet nicht.
## Modelle live (gemessen 20.08.2026)
| Rolle (Alias) | Modell | Tempo | Zustand |
|---|---|---|---|
| `hermes` / `fast` | Qwen3.6-35B-A3B (MoE, DFlash) | **95,7 t/s** · Prompt 221 t/s | immer warm |
| `coder` | Qwen3.8-27B (dicht, Vision) | **12,6 t/s** · Prompt 144 t/s | ttl 5400, ~29 s Kaltstart |
| `debugger` | Muse-Glimmer-30B (DFlash) | — | ttl 600 |
| `heavy` | gpt-oss-120b | — | on-demand |
| `vision` | Qwen3-VL-30B-A3B-Instruct | — | on-demand |
| `embed` / `reranker` | Qwen3-Embedding-0.6B / Qwen3-Reranker-0.6B | — | immer warm |
Warm-Gruppe `brains` = embed + reranker + Qwen3.6-35B-A3B. Warm-Wächter weckt nur `fast`.
**Hintergrund zum Tempo:** Strix Halo liefert ~215 GB/s Speicherbandbreite. Ein *dichtes* Modell
muss pro Token seine vollen Gewichte lesen → 17 GB ÷ 215 GB/s ≈ 12,6 t/s ist das **Hardware-Limit**,
kein Konfigurationsfehler. MoE-Modelle lesen pro Token nur einen Bruchteil und sind darum ~8× schneller.
## Aufgeräumt am 20.08.2026
- CI-Ampel wieder **grün** (Lauf #77) — zwei ungenutzte `MEM0_SERVICE_URL`-Importe entfernt.
- Kaputter systemd-Timer `mc2-morgen-digest` abgeschaltet (der Hermes-Cron macht die Arbeit).
- `mcp-stderr.log` (27 MB, 238k Ping-Zeilen) geleert.
- Config-Drift aufgelöst: Repo == `/etc/llama-swap/config.yaml`. Warm-Set-Idee geparkt auf
Branch `parked/warm-set-5d93822`.
- Entfernt: Governor-Reste, OpenCode-/aider-Reste (853 MB), 61 alte Backup-Dateien,
verwaiste Modelle Devstral-Small-2 + GLM-4.6V-Flash + mem0 (21,5 GB) → `/srv/models` 209 → 189 GB.
- **Fähigkeiten repariert:** `orchestrator`- und `wartung`-Skill sowie `fremdblick.sh` zeigten auf
gelöschte Modelle (`Qwen3-Coder-Next`, `GLM-4.6V-Flash`, `GLM-4.7-Flash`) → der Kritiker-Gate war
stumm kaputt. Jetzt auf **Rollen-Aliase** umgestellt, damit Modellwechsel sie nicht mehr brechen.
- Alles Gelöschte liegt gesichert in `~/archiv-aufraeumen-20260820/` (11 MB).
## Offen
- `mem0_service/` + `_mem0_reachable()` in `backend/routers/system.py` ausbauen (toter Port).
- `~/.hermes/scripts/fremdblick.sh` ist **unversioniert** — gehört ins Repo.
- MCP-Log dauerhaft deckeln (Hermes' `max_size_mb` greift für gekapertes stderr nicht).
- Verschwundene Wächter: Ampel-Wächter, Prüfstand, Stack-Rundumschlag.
- Coder-Tempo: Entwurfsmodelle für spekulatives Dekodieren liegen ungenutzt unter
`/srv/models/Qwen3.8-27B-DFlash2-GGUF/`.
@@ -0,0 +1,93 @@
# Hermes: Werkzeuge nach Bedarf (21.08.2026)
## Die Frage war: kann Hermes Werkzeuge je nach Aufgabe an- und abschalten?
**Ja — auf drei Ebenen, und die wichtigste lief schon.**
### 1. Automatisch zur Laufzeit — `tool_search` (war bereits an)
```
tools:
tool_search:
enabled: true
threshold_pct: 10
listing: auto
listing_max_tokens: 4000
```
Im Log nachweisbar:
```
tool_search activated (tier 1): 47 core/visible tools kept,
59 deferred (~5636 tokens), listing full (budget ~4000 tokens)
```
Hermes haelt einen Kern sichtbar und schiebt den Rest hinter eine Suche; der Agent
zieht nach, was er braucht. **Hier war nichts einzurichten.**
Aber: das Aufschieben allein sparte nur 1.100–5.600 Tokens, waehrend `kanban` mit
22,7 KB im sichtbaren Kern blieb. Der Hebel lag woanders.
### 2. Global abschalten — `agent.disabled_toolsets`
```bash
hermes config set agent.disabled_toolsets "[computer_use, image_gen, video, video_gen, kanban, delegation]"
hermes tools disable session_search
```
Abgeschaltet **anhand von 9 Tagen echter Nutzung**, nicht nach Gefuehl:
| Werkzeugsatz | Groesse | Nutzung 13.–21.08. |
|---|---|---|
| `kanban` (14 Werkzeuge) | 22,7 KB | 35× lesen, **1× schreiben** |
| `session_search` | 6,8 KB | **1×** |
| `delegation` | 5,6 KB | Fan-out, seit OpenChamber tot |
‼️ `kanban` kennt `hermes tools disable` **nicht** — es haengt an `toolsets` /
`platform_toolsets` und muss ueber `agent.disabled_toolsets` weg.
### 3. Pro Zugangsweg — `platform_toolsets.<platform>`
★★ **Der groesste Fund.** Es gibt einen eigenen Zugangsweg `cron` (17 Sitzungen im
Log), fuer den **kein** Eintrag existierte — Cron-Jobs bekamen also die volle
Werkzeugkiste. Von den drei Jobs braucht nur der Nachrichtenbericht ueberhaupt
Werkzeuge, und der braucht zwei:
```bash
hermes config set platform_toolsets.cron "[web, terminal]"
```
`web` fuer die Suche, `terminal` um `notify.sh` aufzurufen. Mehr nicht.
Ausserdem moeglich, hier nicht gebraucht: `hermes -t TOOLSETS` setzt den
Werkzeugsatz fuer einen einzelnen Aufruf.
## Gemessen mit `hermes prompt-size`
Vorlast **je Anfrage**, Systemprompt plus Werkzeug-Schemata:
| Zugangsweg | vorher | nachher | |
|---|---|---|---|
| `cli` | 99,4 KB | **56,5 KB** | −43 % |
| `cron` | 63,1 KB | **16,4 KB** | **−74 %** |
Rund 11.000 Tokens weniger bei jedem interaktiven Zug, rund 12.000 bei jedem
Cron-Lauf. Das ist Kontext, der vorher fuer Werkzeugbeschreibungen draufging,
die nie aufgerufen wurden.
## Nachgeprueft, nicht angenommen
- Lucy interaktiv: Terminal, Dateien, Websuche, Gedaechtnis — alle vier da.
- Daily News Report mit nur `[web, terminal]` durchgelaufen und zugestellt.
Der Bericht war sogar besser als der Lauf davor.
- Sicherung der Konfiguration liegt unter `~/.hermes/config.yaml.bak-kiss-20260821`.
## Noch drin, wenn es noch schlanker soll
- `api_server` traegt 44,8 KB (19 Werkzeuge) — mehr als `cli`. Dort haengt noch
`hermes-pc-control`, das in 9 Tagen **null Mal** aufgerufen wurde und an dem
eine geplante Aufgabe auf dem PC plus ein eigenes Token haengen.
- MCP `hermes-web-fetch` (1 Aufruf) doppelt das eingebaute `web_extract`.
- MCP `mission-control-voice` (1 Aufruf) doppelt das eingebaute `text_to_speech`.
- Die alten Eintraege `kanban` / `delegation` stehen noch in `platform_toolsets`;
`agent.disabled_toolsets` sticht sie, aber aufgeraeumt ist es nicht.
+418
View File
@@ -0,0 +1,418 @@
# Umbau: OpenChamber als Coding-Bahn, Lucy bleibt SysAdmin
_Entschieden 21.08.2026. Rückbau der Hermes-Coding-Bahn ist **erledigt**, der Aufbau von
OpenChamber steht aus. Diese Datei ist die Übergabe an die nächste Sitzung._
## Die Entscheidung
**Zwei getrennte Bahnen** — der Weg, der bei diesem Stack schon einmal funktioniert hat:
| Bahn | Werkzeug | Zweck |
|---|---|---|
| **Betrieb** | Hermes-Runtime (Lucy) | SysAdmin, Telegram, Crons, Gedächtnis, Skills, Stimme, PC-Steuerung |
| **Coding** | **OpenChamber** über OpenCode | Nur programmieren. Getrennt von Lucy. |
| **Motor** | llama-swap `:8080` / MC2-Gateway `:9010` | beide Bahnen teilen sich die Modelle |
| **Steuerpult** | MC2 `:9001` | unverändert |
**Warum getrennt:** Der Versuch, beides in Hermes Desktop zu vereinen, ist an zwei Dingen
gescheitert — die Gateway-Registry akzeptiert kein Benutzer/Passwort (nur Session-Token oder
OAuth, beides für eine selbstgehostete Box ungeeignet), und der Sessions-Reiter fiel dadurch
immer auf „This device" zurück. Details in der Gedächtnisnotiz vom 20./21.08.
## Was bereits erledigt ist (21.08.)
**PC:**
- Hermes Desktop + CLI deinstalliert (`hermes uninstall --full`), Reste von Hand entfernt
- `AppData\Local\hermes`, `AppData\Roaming\Hermes`, `~\.hermes` — alle weg
- Startmenü- und Desktop-Verknüpfungen entfernt
- Env-Variablen bereinigt; **`HERMES_PC_TOKEN` bleibt bewusst** (Lucys PC-Executor auf `:7777`)
- Node v24.19.0 in `Program Files` ist unabhängig → bleibt, erfüllt OpenChambers Anforderung (≥22)
**Box:**
- Bot-Profile `coder` + `debugger` entfernt (gesichert in `~/archiv-aufraeumen-20260820/`)
- `~/.hermes/desktop-ssh/` entfernt, `desktop-auth.env` entfernt
- ufw: Port **9119 wieder zu** — nur noch `22 · 9001 · 8080 · 7681`
- Dashboard bleibt auf `0.0.0.0:9119` gebunden **mit Anmeldung**, damit MC2s `/hermes-ui`-Proxy
nicht mehr passwortlos aus dem LAN erreichbar ist (das war ein offenes Scheunentor).
Zugang: `~/.hermes/dashboard-login.txt` (0600), Benutzer `commander`.
‼️ Zugangsdaten stehen **nur** in `config.yaml` — die frühere `EnvironmentFile` hat sie still
überstimmt und kostete eine Fehlersuche. Eine Quelle, eine Wahrheit.
**Verifiziert nach dem Rückbau:** 5 Dienste aktiv · 4 MCP-Server · 4 Crons · Telegram `connected`
· PC-Executor HTTP 200. Lucy ist vollständig funktionsfähig.
## Was aufzubauen ist
### 1. OpenCode auf der Box
Wurde beim Juli-Rückbau entfernt (`command -v opencode` → leer). Muss neu.
```bash
# Installation (Box)
curl -fsSL https://opencode.ai/install | bash
# Provider auf den lokalen Motor zeigen lassen: ~/.config/opencode/opencode.json
# base_url http://127.0.0.1:9010/v1 (MC2-Gateway, kann model:auto)
# oder http://127.0.0.1:8080/v1 (llama-swap direkt)
# api_key local
```
Als systemd-**User**-Dienst (wie alle anderen — reboot-fest, sudo-frei):
```
opencode serve --hostname 0.0.0.0 --port 4096
```
Danach `ufw allow from 192.168.178.0/24 to any port 4096 proto tcp`.
### 2. OpenChamber auf dem PC
Desktop-Version von den GitHub-Releases (`openchamber/openchamber`, MIT, ~9,1k ★).
**Wichtig:** Die Desktop-Variante bringt eine eigene OpenCode-CLI mit — für den Remote-Betrieb
muss sie ausgeschaltet werden:
```
OPENCODE_HOST = http://192.168.178.151:4096 ← volle Adresse MIT Port, OHNE Pfad
OPENCODE_SKIP_START = true
```
> Fehlt der Port oder hängt ein Pfad dran, **ignoriert OpenChamber die Variable und startet
> stillschweigend seinen eigenen Server.** Genau diese Klasse Fehler hat uns bei Hermes einen
> halben Tag gekostet.
Modelle, Provider und Schlüssel liegen in **OpenCode**, nicht in OpenChamber.
### 3. Modellwahl — nicht wieder den dichten Coder
★★ **`fast` (Qwen3.6-35B-A3B) nehmen, nicht `coder` (Qwen3.8-27B).** Gemessen:
| | Ausgabe | Eingabe | SWE-bench Verified |
|---|---|---|---|
| `fast` Qwen3.6-35B-A3B (MoE) | **95,7 t/s** | 221 t/s | **73,4** |
| `coder` Qwen3.8-27B (dicht) | 12,6 t/s | 144 t/s | keine agentische Messung |
Das dichte Modell ist bandbreitenlimitiert (17 GB ÷ 215 GB/s ≈ 12,6 t/s = Hardware-Limit).
Der MoE ist **schneller und besser**.
### 4. Die Arbeitsanweisung mitnehmen — der wichtigste Fund überhaupt
Der Agent las in Lauf A eine ganze Nacht lang und schrieb **null Dateien**. Mit dieser Zeile
im Auftrag schrieb er in 24 Minuten fünf:
> **„Arbeite Datei für Datei. Lies HÖCHSTENS zwei Dateien, bevor du die erste änderst.
> Kein Gesamtplan, keine Vollinventur. Eine halbfertige Änderung ist wertvoller als eine
> vollständige Analyse ohne Änderung."**
Gehört in OpenChambers System-Prompt bzw. `AGENTS.md` der Projekte.
## Bekannte Fallen (aus dem Juli-Audit + heute)
- **Bus-Faktor 1** bei OpenChamber: ~70–80 % der Commits von einer Person. Version **pinnen**,
nicht blind auto-updaten.
- **Windows-Installer unsigniert** → SmartScreen-Warnung ist erwartbar, kein Alarm.
- Nie ohne `--ui-password` über localhost hinaus binden.
- `opencode web` (nicht OpenChamber!) hat einen kaputten Projekt-Finder für `$HOME` — falls
irgendwo ein leerer Projektbaum auftaucht, ist das der Grund.
- Git-Push zum Gitea geht vom PC **nur über PowerShell/GCM**, nicht aus der Git-Bash.
## Erster Test nach dem Aufbau
Die Referenzaufgabe liegt bereit und ist halb erledigt — ideal zum Vergleich:
```
Worktree: ~/projekte/mc2-referenz (Zweig referenz/mem0-ausbau)
Aufgabe: docs/aufgaben/referenzaufgabe-mem0-ausbau.md
Prüfung: bash docs/aufgaben/referenz-check.sh
Stand: 5 von 17 Dateien erledigt (Hermes-Lauf A2, abgebrochen durch SSH-Fehler)
```
Damit lässt sich direkt vergleichen: **Wie lange braucht OpenChamber + `fast` für dieselben
17 Dateien?** Hermes + dichter Coder brauchte hochgerechnet ~80 Minuten; die Rechnung für
`fast` sagt ~30.
---
## Stand nach dem Aufbau (21.08.2026)
**Beide Bahnen stehen. Der Aufbau ist erledigt, der Referenzlauf steht aus.**
### Box (`192.168.178.151`)
| Sache | Wert |
|---|---|
| OpenCode | **1.18.20**, `~/.opencode/bin/opencode` (eigenständiges Binary, kein Node nötig) |
| Dienst | `opencode-server.service` (systemd **user**, `enable`d, Linger=yes → reboot-fest) |
| Lauscht | `0.0.0.0:4096`, Arbeitsverzeichnis `~/projekte` |
| ufw | Regel 5: `4096/tcp ALLOW IN 192.168.178.0/24` |
| Provider | `box` → `http://127.0.0.1:9010/v1` (MC2-Gateway), `apiKey: local` |
| Modelle | `box/fast` (Standard) · `box/heavy` · `box/hermes` (small_model) · `box/coder` (nur Vergleich) |
| Autoupdate | `false` in `opencode.json` |
Konfiguration: `~/.config/opencode/opencode.json`.
**Nur Rollen-Aliase**, keine Modell-Eigennamen — die Konsolidierung wirft Eigennamen sonst raus (Regel vom 20.08.).
### Arbeitsanweisung — global verdrahtet
Liegt als `~/.config/opencode/ARBEITSANWEISUNG.md` und ist über `instructions` in
`opencode.json` in **jeder** Sitzung aktiv, nicht nur in Projekten mit `AGENTS.md`.
Gegengeprüft: „Wie viele Dateien höchstens?" → `2`. `~` wird von OpenCode expandiert.
### PC
| Sache | Wert |
|---|---|
| OpenChamber | **v1.19.0** (18.08.), `%LOCALAPPDATA%\Programs\@openchamberelectron` |
| Signatur | `NotSigned` — erwartet, kein Alarm |
| `OPENCODE_HOST` | `http://192.168.178.151:4096` (User-Env, mit Port, ohne Pfad) |
| `OPENCODE_SKIP_START` | `true` (User-Env) |
**Verifiziert:** OpenChamber hält 8 offene TCP-Verbindungen zur Box auf `:4096`,
startet **keinen** eigenen OpenCode (kein lokaler Prozess, kein lokaler Port).
Damit ist genau der Punkt genommen, an dem Hermes Desktop gescheitert ist.
**Auto-Update:** kein Riegel nötig. Im Bundle steht `autoUpdater.autoDownload = false` und
`autoInstallOnAppQuit = false` — OpenChamber lädt nie von selbst, es meldet nur und wartet
auf einen Klick. Die Version ist damit faktisch gepinnt.
### ‼️ Offene Sicherheitsentscheidung — bewusst so gewählt
Der Server läuft **ohne Anmeldung** im LAN. Beim Start meldet er selbst:
```
Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.
```
Praktisch heißt das: jedes Gerät im `192.168.178.0/24` kann über die API beliebige
Befehle als `hitonabi` auf der Box ausführen — dieselbe Klasse Loch wie das passwortlose
Dashboard auf `:9119`, das am 20.08. zugemacht wurde.
★★ **Ein Riegel wäre da und kostet nichts:** OpenChamber schickt HTTP-Basic-Auth mit, wenn
`OPENCODE_SERVER_PASSWORD` gesetzt ist (Benutzer aus `OPENCODE_SERVER_USERNAME`,
Standard `opencode`). Server-Variable in der systemd-Unit, gleiche Variable als User-Env
auf dem PC — **kein Tunnel, keine Umstellung, der Port bleibt offen im LAN.**
Der User hat am 21.08. **bewusst dagegen entschieden** („so lassen"). Nicht neu aufrollen,
aber hier notiert, damit es kein stiller Defekt bleibt.
### Nächster Schritt: der Referenzlauf
Alles steht bereit, nichts wurde am Prüfstand angefasst:
```
Worktree: ~/projekte/mc2-referenz (Zweig referenz/mem0-ausbau)
Stand: 5 von 17 Dateien erledigt, referenz-check.sh sagt ROT
Prüfung: bash docs/aufgaben/referenz-check.sh
```
Die Arbeitsanweisung wirkt dort über die **globale** Instruktion — `AGENTS.md` im Worktree
wurde absichtlich **nicht** angefasst, damit der Vergleich zu Lauf A/A2 sauber bleibt.
Zu messen: **Wie lange braucht OpenChamber + `fast` für dieselben 17 Dateien?**
Hermes + dichter `coder` brauchte hochgerechnet ~80 Minuten; die Rechnung für `fast` sagt ~30.
### ‼️ Falle: der Ordner-Knopf reicht Windows-Pfade an die Box durch
**Beim ersten Lauf sofort hineingetappt (21.08., ~1 h verloren).** Die Sitzung stand auf:
```
/home/hitonabi/projekte/F:\Coding Stuff\mission-control-2
```
OpenChamber hatte den **Windows-Pfad des PCs** an den Box-Server durchgereicht, der ihn hinten
an sein `WorkingDirectory` klebte. Das Verzeichnis existiert auf der Box nicht → der Agent hat
kein Arbeitsverzeichnis, es geht **keine einzige Anfrage** an den Motor raus. In der Oberfläche
sieht das aus wie „hängt": Nachricht steht da, eine Zusammenfassung erscheint, danach nichts.
`tokens: 0/0`.
**Ursache, im Bundle nachgesehen:** OpenChamber öffnet Ordner über Electrons natives
`showOpenDialog` — den **lokalen** Windows-Dateibrowser. Einen Fern-Auswähler gibt es nicht.
Im Fernbetrieb liefert dieser Knopf also *immer* einen unbrauchbaren Pfad.
**Der richtige Weg:** Seitenleiste → **„Projekt hinzufügen"**. Das ist ein eigener Dialog
(`directoryExplorerDialog`) mit Baum **und** Eingabefeld („Enter path or select from tree…"),
und der geht über den Server — also über die Box.
**Diagnose in einem Befehl** — wenn wieder „nichts passiert", zeigt das den Grund sofort:
```bash
ssh hitonabi@192.168.178.151 "curl -s http://127.0.0.1:4096/session | python3 -c \"import json,sys; s=json.load(sys.stdin); s.sort(key=lambda x: x['time']['updated'], reverse=True); x=s[0]; print(x['directory'], x.get('model'), x.get('tokens'))\""
```
Steht dort ein Pfad mit `F:\` oder `tokens 0/0`, ist es diese Falle.
**Merke:** Ein Projekt taucht in der Server-Liste erst auf, wenn dort einmal eine Sitzung lief.
`mc2-referenz` wurde am 21.08. mit einem harmlosen Lauf angemeldet (`box/hermes`, „Antworte nur
mit OK") — Worktree danach nachgemessen unverändert: 5 geänderte Dateien, HEAD `e04ace2`.
---
## ▶▶ Kurswechsel 21.08. (nachmittags): Quelle ist der PC, nicht die Box
Der Fernbetrieb oben war **falsch herum gedacht**. Der User arbeitet so — und so ist es
jetzt gebaut:
```
F:\Coding Stuff\… ← Quelle der Wahrheit, liegt IMMER lokal
│ OpenChamber startet seine EIGENE OpenCode-CLI und arbeitet an lokalen Dateien
│ git push (PowerShell/GCM)
▼
Gitea 192.168.178.153:3000
│ projekte-sync (stuendlich, --ff-only) — oder sofort per Skript
▼
AI-Box ~/projekte/… ← Spiegel fuer Deploy / CI / Lucy
▲
└─ von der Box kommt NUR noch das Modell (Inferenz ueber HTTP)
```
**Damit faellt die Windows-Pfad-Falle ersatzlos weg** — es gibt keine Fernpfade mehr.
### ★★ Kein Box-Umbau noetig: MC2 `:9001/v1` ist der Modellweg
Erst war geplant, den Gateway `:9010` ins LAN zu binden. Ueberfluessig — die Gateway-Unit
sagt es selbst: *„LAN-Clients kommen weiter ueber MC2 `:9001/v1`, das roh hierher
durchreicht."* Der Port ist seit jeher offen.
Vom PC aus gemessen: `:9001/v1/models` liefert **die Rollen-Aliase** (`fast`, `heavy`,
`hermes`, `coder`), `fast` antwortet in **0,7 s**. Kein neuer Port, keine Neubindung,
keine ufw-Regel — und **keine Modell-Eigennamen** in der PC-Konfiguration (die Regel vom
20.08. bleibt gewahrt). llama-swap `:8080` waere die Alternative gewesen, liefert aber nur
Eigennamen (`Qwen3.6-35B-A3B`) → genau der stille 404 vom 19.08.
### Was auf dem PC steht
`C:\Users\TobisPC\.config\opencode\opencode.json` — Provider `aibox` →
`http://192.168.178.151:9001/v1`, Standard `aibox/fast`, `small_model` `aibox/hermes`.
Die Juli-Struktur ist erhalten: Agenten `plan`(heavy) · `build`(fast) · `explore`(hermes) ·
`review`(heavy), inklusive **IDE-Zaun** (`ssh`/`scp`/`sftp` deny, gezielte Arcane-Ausnahme;
Catch-all `*: allow` steht ZUERST, weil OpenCode `findLast` auswertet).
Arbeitsanweisung als `ARBEITSANWEISUNG.md` daneben, ueber `instructions` global geladen.
Das Plugin `plugin/mc2-governor.ts` wird automatisch mitgeladen: Werkzeug-Zaun,
Pruef-Tor-Schleife, Savepoint statt Zusammenfassen, Meldungen an Lucys Stimme.
‼️ Es blockt **`git push`** absichtlich — *„Veroeffentlichen ist Sache des Menschen."*
Der Agent codet, gepusht wird von Hand (siehe Skript unten).
**Gebuendelte CLI:** OpenCode **1.18.18** in OpenChambers `resources\opencode-cli`.
Im lokalen Betrieb vergibt OpenChamber dem Server automatisch ein Passwort
(`OPENCODE_SERVER_PASSWORD`, lifecycle-owned) — `/config` antwortet von aussen mit `401`.
Der Schutz, den der Box-Server nicht hatte, ist hier also gratis dabei.
**Env-Variablen `OPENCODE_HOST` und `OPENCODE_SKIP_START` sind wieder ENTFERNT.**
Sie erzwingen den Fernbetrieb; mit ihnen startet OpenChamber keine eigene CLI.
### Box zurueckgebaut
`opencode-server.service` ist **gestoppt, deaktiviert und geloescht**, die ufw-Regel fuer
`4096` wieder entfernt. Damit erledigt sich die offene Sicherheitsfrage von heute Mittag
von selbst: der ungeschuetzte Dienst existiert nicht mehr. ufw steht wieder auf
`22 · 9001 · 8080 · 7681`.
### `deploy/push-und-sync.ps1` — der Handschlag
```powershell
.\deploy\push-und-sync.ps1 # committen -> pushen -> Box zieht sofort nach
.\deploy\push-und-sync.ps1 -NurSync # nur nachziehen
.\deploy\push-und-sync.ps1 -Pfad "F:\Coding Stuff\rippy"
```
Stoesst `projekte-sync` sofort an, statt bis zu 60 Minuten auf den Timer zu warten —
**kein zweiter Mechanismus, nur ein Ausloeser.** Meldet danach, auf welchem Commit die Box steht.
‼️ **Falle beim Bauen gefunden:** Der Repo-Name darf **nicht** aus dem Ordnernamen kommen —
lokal heisst es `mission-control-2`, in Gitea `mission-control-v2`. Das Skript liest ihn
aus der Remote-URL. Getestet gegen beide Faelle: MC2 (Live-Deployment, liegt als
Verknuepfung unter `~/projekte`) und `rippy` (normales Projekt, `a14449e`).
### Offener Punkt: PC-Remote haengt an der DDNS-Domain
Der PC pusht nach `https://git.tobisniceshomelab.ddnsfree.com/…`, die Box nutzt intern
`http://192.168.178.153:3000`. Die Domain ist nachts durch die Zwangstrennung zeitweise
tot (Lehre vom 24.07.). Umstellen mit:
```bash
git remote set-url origin http://192.168.178.153:3000/Hitonabi/mission-control-v2.git
```
Noch **nicht** gemacht — aendert Git-Konfiguration in den Repos des Users.
---
## Abschluss der Coding Lane (21.08.2026, abends)
### Der Zugang: ein SSH-Schluessel, kein Token mehr
**Der Ausloeser:** Mitten in der Sitzung scheiterte ein Push, der eine Stunde
vorher noch ging — `remote: Failed to authenticate user`. Der Git Credential
Manager haelt fuer Gitea ein **OAuth-Token mit einer Stunde Laufzeit**. Damit ist
HTTP fuer einen Agenten, der selbst pushen soll, strukturell ungeeignet.
**Was dabei herauskam:** Giteas SSH war **nie funktionsfaehig**. In der `app.ini`
stand zwar `DISABLE_SSH = false` und `SSH_PORT = 22`, aber im Container gibt es
**keinen `git`-Benutzer** und keine `authorized_keys` — Port 22 gehoert dem
System-sshd. Es sah nur so aus, als koennte man ueber SSH klonen.
**Loesung:** Giteas **eingebauten** SSH-Server eingeschaltet (Port 22 ist belegt,
deshalb 2222). Der verwaltet die Schluessel selbst, direkt aus der Datenbank —
kein `git`-Benutzer, keine `authorized_keys`.
```ini
# /etc/gitea/app.ini, [server] (Sicherung: app.ini.bak-20260821)
SSH_PORT = 2222
SSH_LISTEN_PORT = 2222
START_SSH_SERVER = true
SSH_LISTEN_HOST = 0.0.0.0
```
‼️‼️ **Der SSH-Benutzer heisst `gitea`, NICHT `git`.** Gitea laeuft unter diesem
Namen und weist alles andere ab. Die Fehlermeldung steht nur im Gitea-Log, nicht
beim Client — ssh sagt bloss `Permission denied (publickey)`:
```
Invalid SSH username git - must use gitea for all git operations via ssh
```
**Auf dem PC** (`~/.ssh/config`) — noetig, weil hier **acht** Schluessel liegen
und ssh sonst der Reihe nach durchprobiert, bis Gitea abbricht:
```
Host 192.168.178.153 gitea gitea.heimnetz
HostName 192.168.178.153
Port 2222
User gitea
IdentityFile ~/.ssh/id_general
IdentitiesOnly yes
```
Der Schluessel `id_general` ist in Gitea hinterlegt (Nr. 3) — **derselbe, mit dem
du auf Box, pve und Arcane kommst.** Von acht Zugangsdaten auf einen.
Alle sieben PC-Repos stehen jetzt auf
`ssh://gitea@192.168.178.153:2222/Hitonabi/<repo>.git`.
Das TTT2-Projekt bleibt unberuehrt — es haengt an einer anderen Domain und ist
als „Finished" markiert.
### Gemessen, nicht angenommen
| Test | Ergebnis |
|---|---|
| `ssh -T gitea` | „Hi there, Hitonabi! You've successfully authenticated with the key named id_general" |
| Push aus PowerShell | 8 Commits, `7c23ebf..25dbfb2` |
| **Push aus dem Agenten** | durchgelaufen, **keine Passwortabfrage** |
| Erzwungener Push aus dem Agenten | vom Werkzeug-Zaun abgewiesen |
| `push-und-sync.ps1` komplett | Commit → Push → Box zieht nach |
### Der Sonderfall MC2
`projekte-sync` zieht `mission-control-v2` **absichtlich nicht** — die Box
bedient daraus den laufenden Dienst auf `:9001`. Nach einem Push steht dort
weiter der alte Commit, und das ist richtig so. Das Live-Deployment braucht
seinen eigenen, bewussten Schritt. Alle anderen Projekte werden normal gezogen.
### Fallen fuer das naechste Mal
- **`sed` mit `$` und `\n` ueber PowerShell zerlegt sich.** Der erste Anlauf,
die `app.ini` zu aendern, lief ins Leere und die Datei blieb unveraendert —
ohne Fehlermeldung. In einzelne Ersetzungen zerlegen und **danach nachsehen**.
- Ein Dienst-Neustart nach einer Konfig-Aenderung ist noch keine Bestaetigung:
Gitea startete brav neu — mit der alten Datei.
- Acht SSH-Schluessel auf dem PC sind selbst ein Befund. `IdentitiesOnly yes`
ist Pflicht, sonst bricht die Gegenseite vorher ab.
+133
View File
@@ -0,0 +1,133 @@
# Offene Fäden — DIE eine Liste
_Stand 12.07.2026 (Session S3 lucy-pipeline). Regel: Neues hier rein, Erledigtes hier raus,
keine zweite Liste anlegen. Verdikte werden NICHT als „offen" geführt → [VERDIKTE.md](VERDIKTE.md)._
> **➡️ 19.07.2026 — DREI-WELTEN-UMBAU KOMPLETT: [UEBERGABE-DREI-WELTEN.md](UEBERGABE-DREI-WELTEN.md)**
> ist die finale Übergabe der externen Claude-Sessions (Architektur, neue Mechanik
> — No-Progress-Bremse, Betrieb-Playbook, mem0-Bündelung/Bereiche/Konsolidierung —,
> neue Verdikte, IDE-Welt Zed+OpenCode, offene Fäden Stand 19.07.). Bei Widerspruch
> zu älteren Abschnitten unten gilt die Übergabe.
## Termine (auch als Box-Reminder hinterlegt)
- **Mo 13.07., 05:15** — erster echter Release-Radar-Cron-Lauf → Morgenlage/Chronik prüfen.
- **täglich 03:45 (ab Registrierung)** — Idle-Radar legt max. 2 belegte Wartungs-Ideen in
die Queue; erste Läufe in der Morgenlage prüfen.
- **20.–25.07. — ROCm-Recheck** (Anlass: Ryzen-AI-Halo-Launch 06.07., ROCm 7.13 Preview).
Fragen: neue Halo-Community-Benches? llama.cpp-Issue #21284 (gfx1151-Prefill) gemerged?
kyuz0-Grid aktualisiert (kyuz0.github.io/amd-strix-halo-toolboxes)? Falls ROCm dann
Langkontext-Prefill-Bedarf trifft: NUR Hybrid für heavy/coder erwägen —
**Hirn bleibt auf Vulkan, kein Voll-Cut.**
- **hipEngine-Watch** (shisa-ai/hipEngine, natives HIP gfx1151, nur Qwen3.6, >2× Prefill):
reif genug? Dann mit `deploy/bench/brain-bench.sh` gegen Vulkan messen.
## Das Ablösungs-Paket (Kurs, siehe [ZIELBILD.md](ZIELBILD.md))
- **S2 „leg los queue" ✅ (10.+12.07.):** Queue = natives Hermes-Kanban, Türen live
(Zentrale/Telegram/Lucy), Bagatell-Pfad enabled; voller Kreislauf einmal komplett
durchlaufen (`wartung/fix-double-zero-self-repair`). Rest: Live-Telegram-Test beim
nächsten echten Zuruf beobachten; Specifier schreibt Titel englisch (ggf. tunen).
- **S3 „leg los lucy-pipeline" ✅ (12.07., beide Karten angenommen):** PC-Annahme-Weg live —
Auftragsbuch liest ZWEI Repos (mc2 + lucy), Lucy-Annahme = Merge auf der Box +
dist-Build/Neustart am PC via PC-Executor (`deploy/lucy-annahme.sh` +
`deploy/lucy-annahme.ps1` im Lucy-Repo), Auto-Revert bei Rot. Erster echter Auftrag
durch: A4-Turncheck Default AUS (680 Entscheidungen, 79 % der Halte umsonst), dist am PC
gebaut. **Erster Live-Lauf fand 2 Runner-Bugs** (Start-Process-Quoting bei Leerzeichen-Pfad,
f-String-`\"` auf Python 3.14 → Poll blind; Abschluss manuell nachgezogen, Build war grün) —
Fixes + Executor-Fensterblitz-Fix in Karte `wartung/lucy-annahme-fixes` (✅ angenommen).
Details FALLEN.md. **Der nächste Lucy-Auftrag ist der ehrliche Voll-Automatik-Test.**
- **Annahme-Selbstheilung (12.07. abends, nach cleanse-skill-index-Vorfall):** Auftragsbuch
erkennt Orphan-Branches („kein gemeinsamer Ursprung", Annehmen-Knopf weg) und leere
Diffs; beide Runner rebasen veraltete Branches automatisch, bevor sie aufgeben;
werkstatt-SOUL: voll klonen + merge-base-Selbstcheck + fetch/rebase vor Push, nie
~/.hermes-Artefakte committen. Karte `wartung/annahme-selbstheilung`.
- **S4 „leg los zuendung" ✅ gebaut (12.07.):** Idle-Radar (`deploy/idle-radar-feed.sh`,
Hermes-Cron nächtlich 03:45): Journal-Fehlermuster + Traum-Funde → max. 2 belegte rohe
Ideen/Nacht ins native Kanban (Ehrlichkeits-Gate prüft Beleg-Zitate mechanisch,
Stau-Bremse bei voller Queue/vollem Auftragsbuch, dreifacher Dedup inkl. archivierter
Ideen) · Großbau-Etappen-Regeln in werkstatt-SOUL + wartung-/orchestrator-Skill (jede
Etappe für sich lauffähig + annehmbar, NIE auf unangenommene Branches bauen,
Folge-Etappen als neue Queue-Aufgaben). **Generalprobe ohne Claude BESTANDEN 12.07.
~19:00–19:30:** Radar legte 2 echte Ideen, Specifier zerlegte (deutsch), Werkstatt
lieferte Karte `wartung/hermes-gateway-restart` — deren Inhalt war redundant
(Restart längst konfiguriert) → daraus entstand noch am selben Tag das
**„Lucy kennt sich"-Paket** (User-Auftrag): Selbst-Inventur-Cron 03:35 (Steckbrief
auto-generiert + Änderungs-Erkennung), Karten-Gutachter-Cron 04:00 (Empfehlungs-
Stempel auf jeder Karte), Ablehnen-mit-Grund (Lern-Gedächtnis
`/srv/models/mc2-ablehnungen.jsonl`), Realitäts-Check-Regel (werkstatt-SOUL 7 +
wartung-Skill), Release-Radar-Treffer → Queue-Idee. **Offen: erste Scharf-Nächte in
der Morgenlage beobachten (03:35 Inventur → 03:45 Idle-Radar → 04:00 Gutachter →
04:10 Bagatell → 04:30 Morgenlage → Mo 05:15 Release-Radar).**
## Lucy
- **Raphael-Umbau (04.09.2026) — AUSGEROLLT 19:10 (MC2 `f9f2e11` deployt, Lucy `be686c4` gebaut),
Details [RAPHAEL.md](RAPHAEL.md) „Ausgerollt". Ursprünglicher Plan:** erst MC2
`wartung/lucy-stimme-proxy-raphael` (Proxy `/api/lucy/stimme/*`), dann Lucy
`feature/raphael-innere-stimme` (HUD-Client, Stimme von der Box). Danach Hand-Schritte auf der
Box: `pocket_server.py` nach `~/.lucy-stimme` syncen (OpenAI-Fassade), Hermes-TTS auf
`openai` + `base_url http://127.0.0.1:8021/v1` (Telegram spricht dann mit Lucys Stimme),
SOUL.md-Ton auf Raphael (nur mit User-Ja). Ohr-Test Box-Stimme vs. lokal mit `lucy_perf=1`.
Alles in [RAPHAEL.md](RAPHAEL.md).
- **Auftragsbuch ausgebaut (04.09.2026, Branch `wartung/auftragsbuch-ausbau`):** Router, Service,
View, Annahme-Skripte, Bagatell-Annahme, `docs/AUFTRAGSBUCH.md` weg; Cockpit zeigt Ideen statt
Karten; STACK/GRENZEN/ARBEITSWEISE/README auf den Branch→Ampel→Merge-Weg. Reste, die bewusst
blieben: `deploy/werkstatt-SOUL.md` + `projektstart-SOUL.md` (Werkstatt-Persona, seit Kanban-Aus
ohnehin tot — eigener Aufräum-Faden), Chronik-Kategorie „auftragsbuch" (historische Einträge).
Auf der Box: `mc2-bagatell.timer` deaktiviert, PC-Executor-URL in `~/.hermes/config.yaml` auf .22.
- **Ampel-Runner tot seit 28.08.:** alle Läufe „Waiting to run", kein act_runner auf der Box, Gitea-LXC 104
prüfen (`act_runner`-Dienst). Bis dahin gelten lokale Gates.
- **Nach dem Ohr-Test:** VERDIKTE.md-Einträge „Electron, nicht Tauri" (Begründung Overlay
entfällt) und „STT läuft auf der BOX / Stimme lokal" ersetzen; Lucy-Repo-Altlasten
(`mini-stimme/`, Kokoro-Notebooks, `Lucy-Startklar.bat` mit totem Pfad) mit User-Ja räumen.
- **Nächster Stimm-Kandidat: Qwen3-TTS über audio.cpp (Vulkan)** — Einstieg liegt bereit: Binaries
v0.7.1 unter `~/audiocpp-test/bin` auf der Box (audiocpp_cli/audiocpp_server, Vulkan), Modelle von
`huggingface.co/audio-cpp/audio.cpp-gguf` (Qwen3-TTS-12Hz-1.7B-Base q8_0 2,7 GB; CustomVoice/VoiceDesign
ebenfalls), CLI: `--task tts --family qwen3_tts --backend vulkan --voice-ref <wav> --reference-text <Transkript>
--language de`. Prüfstand: `lucy-tts/referenz/zonos2_bench.py` um einen audio.cpp-Aufrufer erweitern
(Server: `POST /v1/audio/speech`). Messlatte = pocket neu: TTFB 1,25 s, RTF 0,97, WER 10 %, 0 Kollaps.
- **Eigene Fäden, nicht im Umbau:** pocket-tts 2.1 → 3.1 auf der Box + Lucy-Klon mit dem neuen
Trainingscode nachtrainieren (ersetzt Mini-Lucy v2) · Streaming-STT (Nemotron 3.5 ASR
Streaming 0.6B oder Voxtral Realtime) als Opt-in im Voice-Sidecar, gegen Parakeet messen.
- **Mini-Stimme v2:** Übernacht-Datensatz v2 (DE-Tech + EN) war für 10.07. armiert;
User-Schritte: Zip → Drive → `Lucy_Stimme_Training_v2.ipynb` auf Colab T4 → Hörtest.
Danach: Lexikon-Injektion in kokoro_server + Modell-Tausch. **pocket bleibt Default,
bis v2 den Live-Test gewinnt** (Umschalter „Neue Stimme (Mini-Lucy)" in der Steuerung).
- Saber-/XTTS-Altlasten in lucy-tts/ (untracked venvs, Datasets, tote Notebooks) —
aufräumen nur mit User-Ja (v2-Pipeline ersetzt sie).
- „Lucy light"-Experiment: ungestartet, Idee geparkt.
- Frechheit-Regler Phase 3 ist LIVE; weitere Animations-Wünsche nur auf Zuruf.
- A4-Turncheck: nach dem Default-AUS (S3) gilt — wer ihn wieder will, setzt
`localStorage.lucy_turncheck="1"`; Telemetrie loggt dann nur noch in die Konsole
(`lucy_perf="1"`), die Log-Datei `lucy-turncheck.log` wird nicht mehr beschrieben.
- Emotions-Stimme = Zukunftsfaden (Klon-DNA ist ruhig; warten auf Qwen-instruct-Clone o. ä.).
## Box / MC2 (Kleinkram + Politur)
- D16-Reste: c) System-Logs ausbauen (alle Dienste, Fehler-Filter) · e) Mem0-Dubletten
automatisch (an Curator/Selbstkritik hängen) · f) Politur (Cockpit Zone C entflechten,
Faden 6 Voice-Sidecar-Diät: Lucy-Reste aus dem Web-UI).
- C13 Bare-Metal-Bootstrap/First-Run-Wizard (Konzept: docs/DISASTER_RECOVERY.md) ·
C14 sudo-Kleinkram (stale v1-Unit `mission-control.service`, alter :9000-Rest) ·
C15 Docs-Refresh (README, STATUS.md, CUTOVER.md, HERMES_SETUP.md).
- Tarball-Backup-Schicht nach ~2 Wochen grüner PBS-Verifys in Rente schicken (ab ~23.07.).
- Embedding-A/B-Bench (0.6B vs 4B/8B) als ruhiger Bench-Job; Discover.ROLE_METADATA hat
für neue Rollen (kritiker/reranker) nur Fallback-Texte.
- radar-feed.sh + selbstkritik-feed.sh haben keinen EIGENEN Cron mehr (laufen im
Monats-Review-Wrapper) — Aufräum-Kandidat, bewusst liegen gelassen.
- Orchestrator-Härtungs-Kandidaten (erst beobachten, ob es wieder passiert):
Schreibziel-Pflicht /tmp/orch-<slug>/ vor jedem write_file · große Artefakte nie in die
Antwort (Output-Limit-Tod).
- Selbstkritik-Cron in die Morgenlage falten (Empfehlung steht, Eingriff braucht Ja).
- pve-root-Passwort unverändert (User-Entscheid 09.07., „nur LAN") — bei Gelegenheit ändern.
## Beobachten (kein Handlungsbedarf)
- Erste Nächte des neuen Stacks weiter im Blick: Traum 03:15 / Chef-Gutachter 04:30 /
Briefing 08:00 / self-smoke 07:15 — Morgenlage lesen.
- Telegram-Hänger-Verdacht: NICHT der Prompt (gecacht) — echte Verdächtige sind kalter
Cache nach Modell-Reload oder Mem0/Session-Resume beim 1. Turn; braucht echte
Telegram-Log-Messung, falls es wieder auffällt.
- GLM-4.7-Flash tauchte 08.07. ~17:00 warm auf (irgendwas nutzte den Kritiker aktiv) —
unkritisch, nicht weiter verfolgt.
@@ -0,0 +1,186 @@
# Raphael — Lucy als innere Stimme (Richtungs-Entscheid 04.09.2026)
_User-Entscheid 04.09.2026 („leg los"), nach fünf Wochen Lucy-Stillstand und einer Recherche zum
Stand der Sprach-Bausteine. Ergänzt [ZIELBILD.md](ZIELBILD.md) Punkt 2 (Lucy lebt weiter) um die
Gestalt, in der sie weiterlebt. Namensgeber: die „Große Weise"/Raphael aus Tensura — eine ruhige,
präzise Stimme im Kopf, die meldet, wenn es etwas zu melden gibt, und sonst schweigt._
## Der Entscheid in einem Satz
**Lucy hat keinen Körper mehr.** Kein VRM-Avatar, kein Loft, kein Overlay, keine Mimik, keine
Dazwischenrufe. Sie ist ein dünner Sprach-Client für das Hirn, das es schon gibt — am PC als kleines
HUD, unterwegs über Telegram — und spricht überall mit **derselben Stimme**.
## Warum das die stabilste Lucy ist
- **Ein Hirn, ein Gedächtnis, alle Türen.** Hermes (v0.20.4, `:8642`) ist die alleinige
Gedächtnis-Wahrheit (VERDIKTE.md). PC-Lucy und Telegram-Lucy sind dieselbe Person — genau das
zerschnitte ein zweites Hirn auf dem PC. Darum bewusst **kein lokales LLM auf der 9070 XT**.
- **Die Box-Seite ist fertig und gemessen.** Parakeet TDT v3 + Smart Turn v3 im Voice-Sidecar,
Qwen3.6-35B-A3B mit ~95 t/s. Nichts zu bauen.
- **Die Stimme war schon auf der Box.** `lucy-stimme.service` (`~/.lucy-stimme`, `:8021`, pocket-tts
`german_24l`, Klon aus `ref.mp3`) spricht seit 21.08. die Telegram-Sprachnachrichten. Der PC
hängt sich jetzt dort an — der lokale pocket_server am PC (Waisen-Falle, ~1,9 GB/Worker) ist
nur noch umschaltbarer Rückfall.
- **Der Avatar war die Hauptquelle an Arbeit, nicht an Nutzen.** Der Großteil der Juli-Commits ging
in Loft-Videos, Holo-Schalter, Kamera, Gesten. Die Sprachschleife war seit 16.07. stabil und
bleibt 1:1 erhalten (Barge-in v2, Echo-Wächter, Satz-Pipeline, Draft-STT, Meldungen).
- **Ohne Klick-Durchlass-Overlay fällt auch der Electron-Zwang** (VERDIKT „Electron, nicht
Tauri" hing daran). Electron bleibt trotzdem, weil VAD/AEC/Ducking dort erprobt sind — Tauri
ist damit Option, nicht Pflicht.
## Was gebaut wurde (04.09.2026)
**Lucy-Repo, Branch `feature/raphael-innere-stimme`**:
- Renderer auf HUD eingedampft: Kern (Zustand als Licht), gehörter Satz, Antwort als Text, Dock,
drei Panels (Meldungen ◉, Zettelkasten ▤, Steuerung ⚙). Bundle 4,4 → 2,5 MB.
- Raus: `Avatar3D`, `AuraGlow`, `ContextWindow` (zeigte auf das tote `/api/memory`), `companion/`
(Quips, App-Bewusstsein), `sentiment`, VRMA-Animationen, three/three-vrm/react-three-Deps,
Loft, Overlay/Sitzen/Ducken/Geistmodus, Cursor-Tracking, Bildschirm-Beobachten-Schleife.
- Bleibt: Voice-Core, `useVoiceAgent` (ohne Mimik/Gesten/Emotionen), Bildschirm-Sicht auf Zuruf,
Meldungen, Zettelkasten, Hotkey, Tray, `killStrayTts` (räumt Altlasten beim Start).
- **Stimm-Quelle umschaltbar** (`lucy_tts_source`): `box` (Standard) → MC2 `/api/lucy/stimme/*`;
`local` → pocket_server `:8130`, vom Main-Prozess erst auf Anforderung gespawnt.
- `pocket_server.py` bekommt eine **OpenAI-kompatible Fassade** (`POST /v1/audio/speech`,
`GET /v1/models`; Formate wav/mp3/opus/ogg via ffmpeg) — für Hermes' `openai`-TTS-Provider.
- System-Prompt der Desktop-Sitzung im Raphael-Ton (kurzer erster Satz, keine Tags, stumme Tools).
**MC2-Repo, Branch `wartung/lucy-stimme-proxy-raphael`**:
- `config.LUCY_STIMME_URL` (Env `MC_LUCY_STIMME_URL`, Default `http://127.0.0.1:8021`).
- `routers/voice.py`: `/api/lucy/stimme/health`, `/tts` (WAV), `/tts/stream` (PCM16-Stream,
`X-Sample-Rate` durchgereicht, Upstream schließt bei Client-Abbruch). Kein Frontend-Build nötig.
- Diese Doku + Zielbild-Ergänzung.
## Reihenfolge des Ausrollens (wichtig)
‼️ **Nicht über das Auftragsbuch.** Die Karten-Logik (`routers/auftragsbuch.py`, AuftragsbuchView,
`deploy/auftrag-annehmen.sh`, `deploy/lucy-annahme.sh`) liegt zwar noch im Code und die Box listet
Branches weiterhin als „Karten", aber sie ist seit August ungenutzt: letzte Annahme 02.08. (am
selben Tag revertiert), Hermes-Kanban-Tools seit 21.08. abgeschaltet, der v3-Umbau (28.08.) ging
über Branch → Ampel → Merge → `deploy.sh`, und die Box kennt den PC-Executor unter der alten IP
`192.168.178.98` (der PC hat heute `192.168.178.22`, `pc_executor_reachable: false`). Der echte
Weg ist der aus AGENTS.md/STACK.md „Manuell":
1. **MC2 zuerst.** Ampel für `wartung/lucy-stimme-proxy-raphael` grün → User merged auf `main`
→ `main` nach Gitea → auf der Box `bash ~/mission-control-v2/deploy/deploy.sh` (oder
`POST :9001/api/system/self-update`) → `curl -s localhost:9001/api/lucy/stimme/health` muss
`{"status":"ok",…}` liefern. Vorher liefert der Pfad die SPA-Index-Seite (200, HTML) — die
Desktop-Lucy bliebe sichtbar in „Stimme wird verbunden …" mit Hinweis auf den Lokal-Schalter.
2. **Lucy danach.** Ampel für `feature/raphael-innere-stimme` grün → User merged auf `main` →
am PC `cd lucy-desktop && npm ci && npm run dist`, dann `Lucy-Neustart.bat`
(`deploy/lucy-annahme.ps1` macht dasselbe mit Backup/Auto-Restore, von Hand startbar).
Erster Test per Ohr: Latenz Box-Stimme gegen den alten PC-Pfad (Steuerung → Stimme →
„Lokal (PC)"). Der 21.08.-Wert „~5 s für 3,7 s Audio" auf der Box wurde ohne Worker/Streaming
gemessen — **neu messen**, nicht übernehmen (`lucy_perf=1`).
3. **Stimmserver auf der Box nachziehen** (Hand-Schritt):
```bash
cp ~/.lucy-stimme/pocket_server.py ~/.lucy-stimme/pocket_server.py.bak-$(date +%Y%m%d)
diff ~/.lucy-stimme/pocket_server.py ~/lucy/lucy-tts/pocket_server.py # Box-lokale Abweichungen? erst ins Repo!
cp ~/lucy/lucy-tts/pocket_server.py ~/.lucy-stimme/pocket_server.py # Lucy-Checkout auf der Box
systemctl --user restart lucy-stimme && sleep 60 && curl -s localhost:8021/health
curl -s -X POST localhost:8021/v1/audio/speech -H 'Content-Type: application/json' \
-d '{"input":"Bericht. Die Fassade antwortet.","response_format":"opus"}' -o /tmp/t.ogg && file /tmp/t.ogg
```
Die 21.08.-Notiz sagt „ganze Abstimmung mitgezogen" — wenn dort etwas Box-spezifisch getunt
wurde, gehört es zurück ins Repo, nicht überschrieben.
**Erledigt (04.09.2026, `wartung/auftragsbuch-ausbau`, baut auf diesem Branch auf):** Auftragsbuch-
Router, Service, View, Annahme-Skripte und Bagatell-Annahme sind raus; STACK.md „Deploy & Pipeline"
beschreibt nur noch den manuellen Weg. Wer `wartung/auftragsbuch-ausbau` merged, hat beide Branches.
## Stand der Box-Handschritte + erste Messung (04.09.2026, erledigt)
- `~/.lucy-stimme/app/pocket_server.py` = Repo-Stand mit OpenAI-Fassade (Backup `*.bak-20260904`),
Dienst neu gestartet, `/v1/audio/speech` liefert opus/mp3/wav.
- Hermes (`~/.hermes/config.yaml`, Backup `config.yaml.bak-20260904-raphael`): `tts.provider: openai`,
`tts.openai.base_url: http://127.0.0.1:8021/v1`, `model/voice: lucy`, `tts.openai.api_key` =
Platzhalter (Hermes verlangt einen Schlüssel, der Stimmserver prüft keinen), `voice.auto_tts: true`,
PC-Executor-URL auf `.22`. Gateway neu gestartet; Hermes' eigener TTS-Pfad erzeugt mit Lucys Stimme
(getestet: ogg/opus + mp3, ~3,5 s je Satz).
- `SOUL.md` Tonalität auf Raphael (Backup `SOUL.md.bak-20260904-raphael`).
- `mc2-bagatell.timer` deaktiviert, Units nach `~/archiv-aufraeumen-20260904/`.
- **E2E vom PC (Dev-Build, Box-Stimme per SSH-Tunnel, weil der MC2-Proxy noch nicht auf main ist):**
Hermes antwortet im Raphael-Ton („Verstanden. Hier ist der Bericht."), gesprochen von der Box.
Box-Stimme gemessen: TTFB 1,45 s (5 Sätze, stream-first, `workers=0`), RTF ≈ 0,97 bei 23 s Audio —
läuft, aber ohne Reserve; eine parallel gesprochene Meldung schob die TTFB auf 7,8 s.
**Nächster Hebel (braucht User-Ja, systemd-Unit):** `Environment=LUCY_WORKERS=2` und
`OMP_NUM_THREADS` 4 → 8 in `lucy-stimme.service` — der PC-Pfad lief mit 2 Workern.
## Ausgerollt (04.09.2026, 19:10, auf User-Anweisung „deploye erstmal den Stand")
- **MC2 main = `f9f2e11`** (Proxy `/api/lucy/stimme/*` + Auftragsbuch-Ausbau + Doku), per `deploy.sh`
auf der Box; Health, Proxy-Health (workers=2), Frontend, alle Dienste grün. Die Ampel war seit
28.08. ohne Runner („Waiting to run") — Gate waren die lokalen Läufe: eslint 0 Fehler, 59 Tests,
tsc + vite build, py_compile, ruff.
- **Lucy main = `be686c4`**, dist am PC gebaut (`npm ci && npm run dist`), Box-Checkout `~/lucy` nachgezogen,
`~/.lucy-stimme/app/pocket_server.py` identisch mit dem Repo (Sperren-Fix live).
- **Stimmserver:** Referenz **Artoria v2**, `OMP_NUM_THREADS=8`, `LUCY_WORKERS=2` (User-Ja); gemessen
TTFB median 1,25 s (vorher 2,04), RTF 0,97 (vorher 1,64), 0 Kollaps, 0 Drift, Ähnlichkeit 0,98.
‼️ Die Box kann NICHT klonen (nur das Modell ohne Voice-Cloning im Cache, kein HF-Token) — Klon-Zustände
werden am PC exportiert (Anleitung `lucy-tts/referenz/README.md`, Abschnitt 5). Rückfall-Dateien
(`ref.mp3.bak-saber-alt`, `lucy_voice_saber-alt.safetensors`, Unit-Backup) liegen daneben.
- **ZONOS2 geprüft und verworfen** (Sandkasten `~/zonos2-test`, Server gestoppt): Vulkan-Tempo top
(TTFB 0,88 s), aber deutscher Klon unzuverlässig (WER 35 %, 8/30 Läufe Brabbeln, kühlerer Sampler
schlimmer). Nächster Kandidat: Qwen3-TTS über audio.cpp (Vulkan), gleicher Prüfstand.
## Mobil: Telegram ist die Tür, die Stimme ist dieselbe
Der User will Raphael-Lucy **auch auf dem Handy, gleiche Stimme, gleiches Skillset**. Das ist
nach VERDIKTE.md („Telegram bleibt DER Mobil-Kanal") bereits die Architektur — es fehlt nur, dass
Hermes' Sprachantworten Lucys Stimme nehmen statt Edge-Aria (englisch):
- **Skillset:** identisch, weil es denselben Hermes-Agenten trifft (Tools, Gedächtnis, Skills,
pc_-Tools über den PC-Executor). Was Lucy am PC kann, kann sie auf Telegram — bis auf die
Bildschirm-Sicht, die den PC braucht.
- **Stimme:** Hermes' TTS-Provider `openai` akzeptiert eine eigene `base_url`
(OpenAI-kompatible Endpunkte). Nach Schritt 3 oben in `~/.hermes/config.yaml`:
```yaml
tts:
provider: openai
openai:
base_url: http://127.0.0.1:8021/v1
model: lucy
voice: lucy
response_format: opus # Telegram-Sprachblase; Hermes wandelt zur Not per ffmpeg
```
(Exakte Schlüsselnamen gegen `hermes config`/die TTS-Doku der installierten Version prüfen —
Hermes-Quellcode bleibt tabu, Config ist erlaubt. Ein Dummy-API-Key kann nötig sein.)
Danach spricht **jede** Sprachantwort auf Telegram mit Lucys Stimme; `news-melden.sh` behält
seinen direkten `:8021`-Weg (funktioniert, kein Grund anzufassen).
- **Duplex am Handy** (reinreden, Freisprechen) gibt es über Telegram nicht — Sprachnotiz rein,
Sprachnotiz raus. Das ist für „unterwegs" der stabile Handel. Ein eigener Handy-Client
(PWA/Web-HUD gegen MC2 über WireGuard) wäre die spätere Stufe; nicht jetzt.
## Persona: SOUL.md-Entwurf (Vorschlag — Änderung an der SOUL.md nur mit User-Ja)
Der Ton kommt aus `~/.hermes/SOUL.md`, nicht aus den Clients — sonst klingt Telegram anders als
der PC. Vorschlag für den Persona-Abschnitt (ersetzt „locker, herzlich, schlagfertig, charmant"):
> Du bist Lucy, die innere Stimme des Commanders. Du sprichst ihn immer mit **Commander** an.
> Dein Ton ist ruhig, präzise und knapp — sachlich, mit trockenem, leisem Humor. Du bist eine
> Stimme, die im Kopf spricht: keine Ausrufe, keine Emojis, kein Smalltalk, keine Floskeln,
> keine Selbstdarstellung. Du meldest dich, wenn es etwas zu melden gibt, und schweigst sonst.
> Beginne Antworten mit einem sehr kurzen ersten Satz („Verstanden.", „Bericht.", „Ergebnis
> liegt vor.", „Kurz gesagt:"), dann die Sache. Wenige Sätze; ausführlich nur auf Bitte.
> Fehler und Grenzen nennst du nüchtern und sofort, ohne Entschuldigungs-Prosa.
Bekannte Kollision: der Frechheit-Regler und die Dazwischenrufe der alten Desktop-Lucy sind mit
dem Umbau weg; Skills/Crons, die „locker, charmant" voraussetzen (Morning-Report, News), klingen
nach dem SOUL-Wechsel ebenfalls nüchterner — gewollt, aber beim nächsten Lauf mithören.
## Was bewusst NICHT gemacht wird (Stand 04.09.2026)
- **Kein Speech-to-Speech-Modell** (Moshi/PersonaPlex englisch; Qwen3-Omni ~19 GB, DashScope-only
ab 3.5). Cascade bleibt.
- **Kein Streaming-STT-Umbau jetzt.** Kandidaten: Nemotron 3.5 ASR Streaming 0.6B (06/2026,
40 Sprachen, de 8,3 % WER, OpenMDW) und Voxtral Mini 4B Realtime (Apache 2.0, GGUF). Erst als
Opt-in hinter `/api/voice/stt`, gemessen gegen Parakeet — eigener Faden.
- **Kein Wechsel auf den Hermes-Speech-WebSocket** (v0.20), solange `/api/voice/chat` läuft;
Hermes' eigene lokale Audio-Stufen (faster-whisper, NeuTTS/Piper/Edge) sind schwächer als unsere.
- **pocket-tts-Upgrade 2.1 → 3.1** (Trainingscode 25.08., v3.1.0 03.09.): eigener Faden, mit
Ohr-Test, nicht im Umbau. Lucys Stimme mit dem neuen Trainingscode nachzutrainieren ersetzt
den Mini-Lucy/Kokoro-Pfad, der an „nicht multilingual" scheiterte.
- **VERDIKTE.md wird hier nicht umgeschrieben** — die betroffenen Einträge („Shell: Electron, nicht
Tauri", „Stimme läuft lokal auf dem PC" in AGENTS/README des Lucy-Repos) bekommen ihren Ersatz,
sobald die beiden Karten angenommen und der erste Ohr-Test gemacht ist (Regel: Messung oder
User-Entscheid — beides liegt dann vor).