# Claude-Code-Auftrag: „Brain"-Rolle für Lucy (Front- + Backend-Umbau)

> Ziel: Lucys Hirn (aktuell `gemma-4-26B-A4B-it`) als **erstklassige, dauer-warme Rolle** im MC2-Stack
> verankern — statt es als `scout` zu führen, das nach `ttl` entladen wird. Features (Sehen/Hören/
> Sprechen/Embedding) dürfen NICHT verloren gehen, KO-Residenz + Budget müssen sauber bleiben.

## Kontext / Architektur (Ist-Zustand, verifiziert 30.06.)
- **Engine:** llama-swap (config: `/etc/llama-swap/config.yaml` auf der Box, läuft mit `-watch-config`).
  Rollen werden als llama-swap **`aliases`** gesetzt; Warm-Bleiben über `groups:` (eine Gruppe
  `brains: { swap: false }`) + `ttl`. Installierte Modelle: `Qwen3.6-35B-A3B` (fast, ttl 0),
  `Qwen3.5-122B-A10B` (heavy, ttl 600), `Qwen3-Coder-Next` (coder, ttl 600),
  `Qwen3-Coder-30B-A3B-Instruct` (coder_lite, ttl 300), `Qwen3-VL-8B-Instruct` (vision, ttl 300),
  `Qwen3-Embedding-0.6B` (ttl 0 = immer warm), `gemma-4-26B-A4B-it` (ttl 180).
- **Gateway:** MC2 builtin auf `:9001/v1` mit virtuellen Lanes `chat` (→ fast/heavy) und
  `coding` (→ coder_lite/coder). Code: `backend/services/router_logic.py`, `routing_policy.py`.
  **Lucy nutzt die Lanes NICHT** — sie ist der Hermes-Agent.
- **Lucy-Hirn:** Hermes-Agent (`:8642`), Brain = `~/.hermes/config.yaml` → `model.default`
  (jetzt `gemma-4-26B-A4B-it`), Delegation = `heavy`. Persona/Prompt kommt aus dem **Client**
  (`client/lucy-desktop/src/renderer/src/config.ts`), nicht aus der Box-Config.
- **Hardware:** Strix Halo (Ryzen AI Max+ 395), 122 GB, GTT ~124 GB, bandbreitenlimitiert →
  MoE mit wenig aktiven Params ist schnell, dichte Modelle langsam.

## Root-Cause des Bugs
1. Kanonische Rollen `ROLE_IDS = {fast, heavy, coder, vision, scout}` — **keine `brain`/Agent-Rolle**.
   (Kommentar im Code: „kein agent/reasoning mehr".)
2. Es gibt keine Verknüpfung „Hirn-Modell ⇒ muss warm bleiben". gemma trägt den Alias `scout`,
   ist NICHT in der `brains`-Gruppe, `ttl 180` → entlädt im Leerlauf → Lucy lädt kalt nach (~5–10 s).
3. `roles.py` referenziert noch eine `hermes`-Rolle, die in `ROLE_IDS` nicht existiert → Inkonsistenz.

## Aufgabe

### Backend (`backend/`)
1. **Neue erstklassige Rolle `brain` einführen** (oder `hermes` reaktivieren) und in ALLEN
   Quellen synchronisieren (heute dupliziert!):
   - `services/llamaswap.py` → `ROLE_IDS`
   - `services/sources.py` → `ROLE_IDS` + Titel/Icon (analog `scout: {title, icon}`)
   - `services/maintenance.py` (Modell-Upgrade-Rollenliste)
   - `services/roles.py` → `_capability_suit`/`_pref`/`_reason` für `brain` (Tools Pflicht,
     mittlere Größe + MoE bevorzugt, niedrige Latenz). `hermes`-Altlast bereinigen.
2. **Rolle `brain` ⇒ automatisch warm + ko-resident.** Beim Zuweisen der `brain`-Rolle
   (`POST /api/models/{model_id}/role`, `routers/models.py`):
   - Modell via `set_group("brains", members=[...], swap=False, persist=True)` in die Warm-Gruppe
     aufnehmen (bestehender Helper in `llamaswap.py`).
   - `ttl: 0` setzen (oder hoch), vorheriges Brain-Modell aus `brains` entfernen + ttl entspannen.
   - Embedding (`Qwen3-Embedding-0.6B`, ttl 0) MUSS warm bleiben — nicht verdrängen.
3. **Single Source of Truth für „Lucys Hirn":** beim Setzen der `brain`-Rolle auch Hermes'
   `~/.hermes/config.yaml` → `model.default` auf das Modell setzen + `systemctl --user restart
   hermes-gateway` (mit Backup der config). So bleibt MC2-UI-Auswahl ↔ Hermes-Brain konsistent.
4. **Budget/KO-Residenz-Safety:** Brain(warm) + Embedding(warm) + on-demand Vision + Coder müssen
   in GTT (~124 GB) passen. `services/budget.py`/`fit.py` nutzen, bei OOM warnen (nicht hart laden).
5. **Lanes/IDEs unangetastet lassen:** chat/coding-Routing (`router_logic.py`) bleibt wie es ist;
   `fast` bleibt für die chat-Lane warm.

### Frontend (`frontend/src/`)
1. **Rollen-Taxonomie** um `brain` erweitern (Badges/Titel/Icon) — Duplikat zur Backend-Liste
   finden & angleichen (`components/models/*`, `views/ModelsView.tsx`, evtl. `ModelBadges.ROLES`).
   gemma darf NICHT mehr als `scout` erscheinen.
2. **Rollen-Zuweisungs-Modal:** `brain` auswählbar; Warm-/KO-Residenz-Status anzeigen
   (ist das Brain in `brains`? warm? ttl?). Empfehlung via bestehendem `/api/roles/{role}/recommend`.
3. **Warm-Set / GTT-Budget sichtbar machen** (Dashboard/Models): was ist gerade ko-resident,
   passt es ins Budget? (nutzt `/api/models` `running` + budget-Infos).
4. Optional: „Lucy-Hirn"-Selector, der die `brain`-Rolle setzt (treibt Backend #2 + #3).

### Zusatz: MTP-Speculative-Decoding für Gemma (Durchsatz für agentische Arbeit)
Lucy ist ein **voller Agent** (Tools/MCP/PC-Control/Vision/Delegation) — Durchsatz zählt, nicht nur
TTFB. Gemma 4 bringt **MTP** (Multi-Token-Prediction) mit → 1,5–2× schneller bei null Qualitätsverlust.
- **Engine kann es bereits:** `llama-server` v9843 listet `--spec-type … draft-mtp …`. ✓
- **Vocab-kompatibler „Draft" = Gemmas eigener MTP-Kopf** `gemma-4-26B-A4B-it-assistant` (~0,4B,
  identischer Tokenizer per Konstruktion). Quelle z.B. `unsloth/gemma-4-26B-A4B-it-GGUF` (enthält den
  MTP-Drafter, PR ggml-org/llama.cpp#23398). Muss nach `/srv/models/...` geladen werden (noch nicht da).
- **Flag-Änderung beachten:** `--draft-max/--draft-min` sind ENTFERNT → `--spec-draft-n-max` /
  `--spec-draft-n-min`. Drafter laden via `-md <assistant.gguf> --spec-type draft-mtp`. Exakte Flags
  des Builds mit `llama-server --help` gegenprüfen.
- **MC2-Bug:** die Spec-Draft-Auswahl (UI + Backend) kennt **nur klassische Drafts** (vergleicht stur
  `n_vocab`/`pre`) und bot fälschlich nur den Qwen-Draft an („Vocab ?"). **Erweitern:** MTP-Drafter
  (`gemma4_assistant`-Arch) als gültigen, vocab-kompatiblen Draft erkennen, den passenden `-assistant`-
  GGUF anbieten, und beim Aktivieren `-md … --spec-type draft-mtp --spec-draft-n-max/-n-min` in die
  llama-swap-cmd schreiben. Co-Residenz: Drafter ~0,4B → vernachlässigbar.

## Akzeptanzkriterien
- [ ] `gemma-4-26B-A4B-it` wird in der UI als **`brain`** geführt (nicht `scout`).
- [ ] Es bleibt **warm**: in `brains: swap:false`, `ttl 0`; überlebt > alter ttl Leerlauf
      (Verifikation: `curl :8080/running` nach >5 Min Idle zeigt das Modell weiterhin `ready`).
- [ ] Lucy antwortet ohne Kalt-Nachladen nach Leerlauf.
- [ ] Vision (`Qwen3-VL-8B`), Embedding (`Qwen3-Embedding-0.6B`), Coder bleiben funktionsfähig &
      ko-resident; **kein OOM**; IDE-Lanes (chat/coding) unverändert.
- [ ] Brain-Wechsel in der UI aktualisiert llama-swap (Warm-Gruppe) UND Hermes `model.default`
      (+ Restart), reversibel (Backup).

## Sofort-Hotfix (unabhängig vom Umbau — macht Lucy JETZT warm)
Auf der Box, bis der saubere Umbau steht:
```bash
# gemma als immer-warm + in die brains-Gruppe (Backup zuerst!)
cp /etc/llama-swap/config.yaml /etc/llama-swap/config.yaml.bak
# gemma ttl 180 -> 0  und  groups.brains.members um gemma-4-26B-A4B-it ergänzen
# (manuell editieren oder via MC2 set_group), dann:
# llama-swap reloadt per -watch-config automatisch.
```

## Wichtige Dateien (Einstieg)
- Backend: `services/llamaswap.py` (Rollen=aliases, `set_role_alias`, `set_group`, `register_model`),
  `services/roles.py`, `services/sources.py`, `services/routing_policy.py`,
  `services/router_logic.py`, `services/budget.py`, `services/fit.py`, `routers/models.py`,
  `routers/routing.py`.
- Frontend: `views/ModelsView.tsx`, `components/models/*`, `components/SystemDrawer.tsx`.
- Box (nicht im Repo): `/etc/llama-swap/config.yaml`, `~/.hermes/config.yaml`.
