README aktualisiert + Kritiker auf 16k gedeckelt (Prefill-Befund)
Ampel / ampel (push) Successful in 22s

README war auf dem Stand "Final-Version eingefroren" und kannte weder Governor,
Coding-Bahn, CI-Ampel noch den Weg einer Idee. Neu geschrieben mit den echten
Ports/Diensten, den gemessenen Modell-Rollen und den vier Qualitaets-Toren.
Alle Verweise gegen den Baum geprueft.

Dabei aufgefallen: das eigene VERDIKT vom 24.07. ("Devstral bricht beim 32K-Prefill
auf 63 t/s ein") widerlegt meine Begruendung "ein Kritiker liest viel und schreibt
wenig, also stoert die Langsamkeit nicht" — es ist genau das LESEN, das einbricht.
Nachgemessen: Prefill 265-318 t/s (Coder 754). Der Kritiker ist deshalb in
llama-swap UND in beiden opencode.json auf 16384 gedeckelt; schlimmster Fall je
Review jetzt unter einer Minute statt 8+ Minuten.

VERDIKTE um zwei Eintraege ergaenzt: die enge Kritiker-Rolle mit Deckel, und die
llama-swap-Gruppenregel (eine Gruppe resident, persistent:false, OOM-Grenze).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-07-25 22:04:44 +02:00
parent 8b76c0f749
commit c28aa4a6a2
4 changed files with 202 additions and 66 deletions
+128 -50
View File
@@ -1,72 +1,150 @@
# Mission Control 2.0 # Mission Control 2.0
Komponierbarer Local-AI-Stack für den Bosgame M5 (Strix Halo). Läuft **live auf der Box** Steuerzentrale des lokalen KI-Stacks auf dem **Bosgame M5** (AMD Ryzen AI MAX+ 395 „Strix Halo",
als sudo-freier systemd-User-Dienst (`:9001`) und ist als **Final-Version eingefroren** 122 GB Unified Memory, **keine dedizierte GPU** — llama.cpp über **Vulkan/RADV**). Läuft live als
Pflege übernehmen ab jetzt die selbst-wartenden Box-KIs (Auto-Update mit Fangnetz + die sudo-freier systemd-User-Dienst und ist auf **Autonomie** ausgelegt: Die Box wartet sich selbst,
„Werkstatt"), nicht mehr manuelle Releases. prüft sich selbst und meldet sich, wenn etwas nicht stimmt.
**Schichten:** Engine (llama.cpp **Vulkan/RADV** auf Strix Halo) · Router (**llama-swap**, > **100 % lokal.** Kein Cloud-Modell, kein externer Dienst im Datenpfad.
Ko-Residenz-Warm-Set) · **Builtin-Routing-Gateway** in MC2 (`model: auto`, kein externer
LiteLLM — scheitert auf Python 3.14) · Mission Control 2.0 (FastAPI + React/shadcn) ·
**Hermes Agent** (api_server-Gateway :8642, Tools/MCP/Telegram/cron) · auto-lernendes
**Gedächtnis** (Mem0-Sidecar, semantisch). Jede Schicht hinter stabilem Vertrag austauschbar.
> **Sprachassistentin Lucy** (Voice + 3D-Avatar) ist in ein **eigenes Repo** ausgelagert ## Die drei Bahnen
> (`Hitonabi/lucy`) und spricht über den Hermes-Gateway. Aus MC2 selbst sind die Voice-/
> Web-Reste entfernt — MC2 ist die Steuerzentrale, kein Sprach-Frontend.
## Status: **live + eingefroren (MC2 Final)** | Bahn | Was sie tut | Wo |
|---|---|---|
| **Steuerzentrale** | Modelle, Routing, Wartung, Gedächtnis, Ideen-Queue, Auftragsbuch | MC2 `:9001` |
| **Coding** | Zed + OpenCode am Tag, `opencode-lauf.sh` in der Nacht — **ein Regelwerk, zwei Auslöser** | Governor `:8100` |
| **Lucy** | Sprach-Companion mit 3D-Avatar, Augen und Ohren | eigenes Repo `Hitonabi/lucy` |
Der ganze Stack ist auf der Box in Betrieb und auf **Autonomie** ausgelegt (Ziel: läuft auch Lucy holt ihr Hirn über MC2, spricht aber nie durch den Governor — ein Gespräch ist keine
ohne Betreuung monatelang weiter): Bau-Sitzung und wird nie unterbrochen.
- **Modelle & Routing** — Discover (live HF + Fit/Caps), Engine-Write (register, `groups`/ ## Ports & Dienste
Ko-Residenz, vocab-geprüfte Spec-Drafts), Gateway `model: auto` + Fallbacks.
- **System & Wartung** — Status (CPU/RAM/GPU/Disk), **ehrliche Speicher-Zahlen** (echte KV-Bytes
aus GGUF-Architektur), Logs mit Fehler-Filter, Dienst-Neustart (sudo-frei).
- **Updates mit Fangnetz** — OS/Engine/Router/Hermes per Timer: Backup → Update → Postcheck →
bei Fehler **Auto-Rollback + Pin**; verständliche Zusammenfassung („Musst du etwas tun?") in
Lucys Stimme. Eigene Software wird eingefroren, nicht geupdatet.
- **Gedächtnis** — Mem0-Sidecar (auto-lernend, semantisch), 4 Kategorien, Auto-Dedupe.
- **Selbsterhaltung** — Health-Wächter (`sentry`), Warm-Set-Wächter (`warmer`), tägliche
Self-Smokes, Lucy-Watchdog + Alarmkette; **Werkstatt** (Hermes wartet den Stack via Gitea-
Branch → Gate → Deploy selbst).
API: `health · models · discover · fit · models/register · groups · routing · system/* · | Port | Dienst | Erreichbar |
maintenance/* · connect · memory/* · agent/* · voice/announce · reminders/*`. MCP: `mcp/`. |---|---|---|
Box-Runbooks: [`docs/HERMES_SETUP.md`](docs/HERMES_SETUP.md), [`docs/RUNBOOK.md`](docs/RUNBOOK.md), | `9001` | **MC2** (FastAPI + React) — Cockpit, API, Konsole | LAN |
[`docs/BEDIENUNG.md`](docs/BEDIENUNG.md) + `deploy/` (Units, `deploy.sh`, `backup.sh`, `warmup.sh`). | `8100` | **Governor** — Token-Wächter vor dem Gateway | LAN |
| `8080` | **llama-swap** — Modell-Router | LAN |
| `9010` | `mc2-gateway``/v1`-Datenpfad (`model: auto`, Bild-Weiche) | loopback |
| `8642` · `9119` | Hermes-Gateway · Hermes-Web-UI | loopback |
| `8765` · `8650` | Mem0-Sidecar · Voice-Sidecar (STT/TTS) | loopback |
| `7682` | ttyd — Box-Konsole, same-origin unter `/console/` | loopback |
Units in [`deploy/`](deploy/): `mission-control-2` · `mc2-gateway` · `mc2-steward` · `governor` ·
`mem0-service` · `voice-service` · `box-console` · `hermes-builtin-ui` + Timer für Backup,
Auto-Update, Self-Smoke und Bagatell-Annahme. `llama-swap` läuft als System-Unit.
## Der Weg einer Idee
```
Idee in MC2 → Gitea-Repo (mit CI-Ampel + VERIFY) → in Zed bauen → Ampel → main
└── oder nachts: Hermes-Cron → opencode-lauf.sh → dieselben Regeln
```
Jedes neue Repo wird von [`deploy/gitea-repo-create.sh`](deploy/gitea-repo-create.sh) **mit beiden
Wächtern geboren**:
- **`.gitea/workflows/ci.yml`** — die Außen-Prüfung nach dem Push (Gitea Actions)
- **`VERIFY`** — die Innen-Prüfung: eine Zeile, wie man das Projekt testet. Das OpenCode-Plugin
führt sie nach jeder Etappe aus und gibt rote Tests dem Agenten **sofort** zurück, statt sie
erst der CI zu zeigen. Keine `VERIFY`-Datei = Prüf-Tor aus.
## Modelle & Rollen
Gemessen auf der Box (25.07.2026, Vulkan, Q4):
| Rolle | Modell | Tempo | Aufgabe |
|---|---|---|---|
| `coder` | Qwen3-Coder-Next (80B-A3B) | **51,5 t/s** · Prefill **754 t/s** | Plant und baut — Kopf der Coding-Mannschaft |
| `hermes` / `fast` | Qwen3.6-35B-A3B | **69,6 t/s** | Lucys Hirn **und** der Sucher-Subagent. Immer warm |
| `kritiker` | Devstral-Small-2-24B | **15,0 t/s** · Prefill **265318 t/s** | Liest gegen — bewusst **fremde Modellfamilie** (Mistral statt Qwen) |
| `vision` | Qwen3-VL-30B-A3B | auf Abruf | Lucys Augen |
| `heavy` | gpt-oss-120b | nur nachts | Chef-Gutachter (4:30). **Nie tagsüber** — verdrängt das warme Set |
| `embed` · `reranker` | Qwen3 0.6B | immer warm | Gedächtnis + Feinsortierung |
‼️ **Der Kritiker ist bewusst auf 16k Kontext gedeckelt.** Devstral ist ein *dichtes* Modell —
auf dieser bandbreitenbegrenzten Box bricht sein Prefill mit wachsendem Kontext ein (bei 32k
gemessene 63 t/s ≈ **9 Minuten nur zum Lesen**). Mit dem 16k-Deckel bleibt der schlimmste Fall
je Review unter einer Minute. Deshalb ist er der **Gegenleser für Etappen**, nicht der Coder —
als Coder ist er auf dieser Box disqualifiziert (siehe VERDIKTE).
‼️ **Speicher-Regel:** `Warm-Set + größtes On-Demand-Modell ≤ ~115 GB`. Die ko-residente Gruppe
(`groups.brains` in der llama-swap-Config) muss **`persistent: false`** sein — sonst räumt
llama-swap vor einem großen Modell nicht ab und der Kernel schießt Prozesse ab. Details und
Messwerte: [`docs/wissen/VERDIKTE.md`](docs/wissen/VERDIKTE.md).
## Qualitäts-Tore
1. **Werkzeug-Zaun** ([`deploy/opencode/plugin/`](deploy/opencode/plugin/)) — blockt `git push`,
`rm -rf`, `sudo`, `curl | sh` und Fremd-Hosts im Agentenlauf.
2. **Prüf-Tor**`VERIFY` nach jeder Etappe; rot → der Agent repariert selbst weiter (max. 3 Runden).
3. **Governor** ([`deploy/governor/`](deploy/governor/)) — zählt Tokens ehrlich (aus den echten
`usage.prompt_tokens` jeder Antwort, selbstkalibrierend). Bei ~45.000: Savepoint schreiben und
Sitzung sauber beenden. Bei ~50.000: harter Riegel. Sichtbar als Kachel im Cockpit.
4. **CI-Ampel** — Lint (ruff) · Import/Syntax (compileall) · Frontend-Build. Läuft bei jedem Push.
Gemeinsame Lehre dahinter: **Wissen lebt in Datei + git, nicht im schrumpfenden Chat-Kontext.**
Kontext-Komprimierung löscht still die Regeln mit.
## Selbsterhaltung
- **Health-Wächter** (`sentry`) + **Warm-Set-Wächter** (`warmer`, per Env abschaltbar)
- **Updates mit Fangnetz** — Backup → Update → Postcheck → bei Fehler **Auto-Rollback + Pin**
- **Melde-Briefkasten** (`/api/voice/announce`) — alles, was die Box von sich aus sagen will;
Lucy pollt ihn und spricht es. Absender `loop` = Coding-Ereignisse
- **Gedächtnis** — Mem0-Sidecar, auto-lernend, semantisch, mit Auto-Dedupe
- Tägliche Self-Smokes, Zeitmaschine (Snapshot + Ein-Klick-Restore), Chronik der autonomen Taten
## API (Auswahl)
`health · models/* · discover · fit · groups · routing/* · system/* · maintenance/* · connect ·
memory/* · agent/* · **governor** · ideen/* · auftragsbuch/* · chronik · eigenleben · wissen ·
zeitmaschine/* · reminders/* · voice/* · events (SSE)`
OpenAI-kompatibel: `/v1/chat/completions`, `/v1/completions`. MCP-Server: [`mcp/`](mcp/).
## Entwickeln ## Entwickeln
**Backend:**
```bash ```bash
# Backend
cd backend cd backend
python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.txt # Windows python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.txt # Windows
.venv/Scripts/python -m uvicorn app:app --port 9000 .venv/Scripts/python -m uvicorn app:app --port 9000
# Frontend (Dev, proxyt /api → :9000)
cd frontend && npm install && npm run dev # http://localhost:5173
# Frontend (Build → wird vom Backend ausgeliefert)
cd frontend && npm run build # → frontend/dist
``` ```
**Frontend (Dev, proxyt /api → :9000):** `frontend/dist` **wird mitcommittet** — die Box hat kein Node; Deploy ist ein `git pull` plus
```bash Dienst-Neustart. Vor jedem Commit lohnt der Ampel-Vorlauf: `ruff check .` und `npm run build`.
cd frontend
npm install
npm run dev # http://localhost:5173
```
**Frontend (Build → wird vom Backend ausgeliefert):**
```bash
cd frontend && npm run build # → frontend/dist
```
## Env-Vars (Auswahl) ## Env-Vars (Auswahl)
| Variable | Default | Zweck | | Variable | Default | Zweck |
|---|---|---| |---|---|---|
| `MC_LLAMA_SWAP_URL` | `http://127.0.0.1:8080` | Engine | | `MC_PORT` | `9000` | MC-Backend-Port (**die Unit auf der Box setzt `9001`**) |
| `MC_CONFIG_PATH` | `/etc/llama-swap/config.yaml` | llama-swap Config | | `MC_LLAMA_SWAP_URL` | `http://127.0.0.1:8080` | Engine/Router |
| `MC_GATEWAY_URL` | `http://127.0.0.1:$MC_PORT` | Builtin-Gateway (Teil von MC2, kein externer Dienst) | | `MC_CONFIG_PATH` | `/etc/llama-swap/config.yaml` | llama-swap-Config |
| `MC_PORT` | `9000` | MC-Backend-Port | | `MC_V1_UPSTREAM` | | gesetzt → `/v1` geht an `mc2-gateway` (`:9010`) statt in-process |
| `MC_ENGINE_PATH` | `/opt/llamacpp-vulkan` | Aktive Engine-Binary (Vulkan-Build) | | `MC_GOVERNOR_URL` | `http://127.0.0.1:8100` | Token-Wächter für die Cockpit-Kachel |
| `MC_ENGINE_REPO` | `ggml-org/llama.cpp` | Quelle für Engine-Update-Check | | `MC_ENGINE_PATH` | `/opt/llamacpp-vulkan` | aktive Engine (Vulkan-Build) |
| `MC_DRAFTS_DIR` | `$MODELS/drafts` | Spec-Draft-Modelle (vocab-geprüft) | | `MC_REWARM_ENABLED` | `1` | Warm-Set-Wächter (auf der Box bewusst `0`) |
| `MC_SPEC_TYPE` | `draft-simple` | Speculative-Decoding-Typ (llama.cpp) | | `MC_DRAFTS_DIR` · `MC_SPEC_TYPE` | `$MODELS/drafts` · `draft-simple` | Spekulatives Dekodieren |
Governor-eigene Schalter (`GOV_THRESHOLD`, `GOV_HARD_CEILING`, `GOV_EXEMPT_MODELS`, …):
[`deploy/governor/README.md`](deploy/governor/README.md).
## Weiterlesen
| Dokument | Inhalt |
|---|---|
| [`docs/BEDIENUNG.md`](docs/BEDIENUNG.md) | Wie man MC2 benutzt |
| [`docs/RUNBOOK.md`](docs/RUNBOOK.md) · [`docs/DISASTER_RECOVERY.md`](docs/DISASTER_RECOVERY.md) | Betrieb, Störungen, Wiederherstellung |
| [`docs/HERMES_SETUP.md`](docs/HERMES_SETUP.md) | Hermes-Agent, Profile, Crons |
| [`docs/AUFTRAGSBUCH.md`](docs/AUFTRAGSBUCH.md) | Vorschlags-Inbox und das Ein-Klick-Gate |
| [`docs/wissen/VERDIKTE.md`](docs/wissen/VERDIKTE.md) | **Finale Technik-Entscheide — nicht neu aufrollen** |
| [`docs/wissen/FALLEN.md`](docs/wissen/FALLEN.md) · [`docs/wissen/OFFENE-FAEDEN.md`](docs/wissen/OFFENE-FAEDEN.md) | Stolpersteine · offene Punkte |
| [`deploy/opencode/README.md`](deploy/opencode/README.md) | Coding-Bahn: Mannschaft, Verteilung, Fallen |
| [`AGENTS.md`](AGENTS.md) | Arbeitsregeln für Agenten in diesem Repo |
+29 -8
View File
@@ -11,19 +11,31 @@
"models": { "models": {
"coder": { "coder": {
"name": "coder — Bauen + Planen (Qwen3-Coder-Next, 51,5 t/s)", "name": "coder — Bauen + Planen (Qwen3-Coder-Next, 51,5 t/s)",
"limit": { "context": 131072, "output": 16384 } "limit": {
"context": 131072,
"output": 16384
}
}, },
"hermes": { "hermes": {
"name": "hermes — Suchen (Qwen3.6-35B, immer warm, 69,6 t/s)", "name": "hermes — Suchen (Qwen3.6-35B, immer warm, 69,6 t/s)",
"limit": { "context": 65536, "output": 8192 } "limit": {
"context": 65536,
"output": 8192
}
}, },
"kritiker": { "kritiker": {
"name": "kritiker — Gegenlesen (Devstral-2, Mistral, 15,0 t/s)", "name": "kritiker — Gegenlesen (Devstral-2, Mistral, 16k gedeckelt)",
"limit": { "context": 65536, "output": 8192 } "limit": {
"context": 16384,
"output": 4096
}
}, },
"heavy": { "heavy": {
"name": "heavy — Nacht-Gutachter (gpt-oss-120b, verdraengt das warme Set!)", "name": "heavy — Nacht-Gutachter (gpt-oss-120b, verdraengt das warme Set!)",
"limit": { "context": 32768, "output": 8192 } "limit": {
"context": 32768,
"output": 8192
}
} }
} }
} }
@@ -33,7 +45,10 @@
"agent": { "agent": {
"plan": { "plan": {
"model": "aibox/coder", "model": "aibox/coder",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
}, },
"build": { "build": {
"model": "aibox/coder", "model": "aibox/coder",
@@ -55,13 +70,19 @@
"mode": "subagent", "mode": "subagent",
"description": "Codebase schnell durchsuchen, Dateien finden, Fragen zum Code beantworten — nur lesen, laeuft auf dem immer warmen Hirn", "description": "Codebase schnell durchsuchen, Dateien finden, Fragen zum Code beantworten — nur lesen, laeuft auf dem immer warmen Hirn",
"model": "aibox/hermes", "model": "aibox/hermes",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
}, },
"review": { "review": {
"mode": "subagent", "mode": "subagent",
"description": "Kritischer Code-Review nach jeder Etappe (Pflicht laut AGENTS.md): sucht erfundene APIs/CLI-Flags, stille Abweichungen vom KONZEPT, fehlende Tests, toten Code — meldet Befunde, aendert nichts. Laeuft bewusst auf einer FREMDEN Modellfamilie (Mistral/Devstral statt Qwen), damit er andere blinde Flecken hat als der Coder.", "description": "Kritischer Code-Review nach jeder Etappe (Pflicht laut AGENTS.md): sucht erfundene APIs/CLI-Flags, stille Abweichungen vom KONZEPT, fehlende Tests, toten Code — meldet Befunde, aendert nichts. Laeuft bewusst auf einer FREMDEN Modellfamilie (Mistral/Devstral statt Qwen), damit er andere blinde Flecken hat als der Coder.",
"model": "aibox/kritiker", "model": "aibox/kritiker",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
} }
} }
} }
+29 -8
View File
@@ -11,19 +11,31 @@
"models": { "models": {
"heavy": { "heavy": {
"name": "heavy — Planer (gpt-oss-120b, 32k)", "name": "heavy — Planer (gpt-oss-120b, 32k)",
"limit": { "context": 32768, "output": 8192 } "limit": {
"context": 32768,
"output": 8192
}
}, },
"coder": { "coder": {
"name": "coder — Bauen (Qwen3-Coder-Next, 131k)", "name": "coder — Bauen (Qwen3-Coder-Next, 131k)",
"limit": { "context": 131072, "output": 16384 } "limit": {
"context": 131072,
"output": 16384
}
}, },
"hermes": { "hermes": {
"name": "hermes — Erkunden (Qwen3.6, immer warm, 69,6 t/s)", "name": "hermes — Erkunden (Qwen3.6, immer warm, 69,6 t/s)",
"limit": { "context": 65536, "output": 8192 } "limit": {
"context": 65536,
"output": 8192
}
}, },
"kritiker": { "kritiker": {
"name": "kritiker — Gegenlesen (Devstral-2, Mistral, 15,0 t/s)", "name": "kritiker — Gegenlesen (Devstral-2, Mistral, 16k gedeckelt)",
"limit": { "context": 65536, "output": 8192 } "limit": {
"context": 16384,
"output": 4096
}
} }
} }
} }
@@ -33,7 +45,10 @@
"agent": { "agent": {
"plan": { "plan": {
"model": "aibox/coder", "model": "aibox/coder",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
}, },
"build": { "build": {
"model": "aibox/coder", "model": "aibox/coder",
@@ -55,13 +70,19 @@
"mode": "subagent", "mode": "subagent",
"description": "Codebase schnell durchsuchen, Dateien finden, Fragen zum Code beantworten — nur lesen, läuft auf dem immer warmen Hirn", "description": "Codebase schnell durchsuchen, Dateien finden, Fragen zum Code beantworten — nur lesen, läuft auf dem immer warmen Hirn",
"model": "aibox/hermes", "model": "aibox/hermes",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
}, },
"review": { "review": {
"mode": "subagent", "mode": "subagent",
"description": "Kritischer Code-Review nach jeder Etappe (Pflicht laut AGENTS.md): sucht erfundene APIs/CLI-Flags, stille Abweichungen vom KONZEPT, fehlende Tests, toten Code — meldet Befunde, ändert nichts. Läuft bewusst auf einer FREMDEN Modellfamilie (Mistral/Devstral statt Qwen), damit er andere blinde Flecken hat als der Coder.", "description": "Kritischer Code-Review nach jeder Etappe (Pflicht laut AGENTS.md): sucht erfundene APIs/CLI-Flags, stille Abweichungen vom KONZEPT, fehlende Tests, toten Code — meldet Befunde, ändert nichts. Läuft bewusst auf einer FREMDEN Modellfamilie (Mistral/Devstral statt Qwen), damit er andere blinde Flecken hat als der Coder.",
"model": "aibox/kritiker", "model": "aibox/kritiker",
"permission": { "edit": "deny", "bash": "deny" } "permission": {
"edit": "deny",
"bash": "deny"
}
} }
} }
} }
+16
View File
@@ -130,3 +130,19 @@ Gemessen mit llama-bench (Vulkan/RADV, Q4_K_M, -fa on) auf der Box (Ryzen AI Max
Speed- und kein Backend-Problem und wird weder durch Modelltausch noch ROCm geloest. Es Speed- und kein Backend-Problem und wird weder durch Modelltausch noch ROCm geloest. Es
ist Reliabilitaet = Modellklasse + Harness. Naechster Hebel: Post-Edit-Verify-Hook, ist Reliabilitaet = Modellklasse + Harness. Naechster Hebel: Post-Edit-Verify-Hook,
kleine Etappen/frische Threads, Eskalation der harten 20% an Frontier. kleine Etappen/frische Threads, Eskalation der harten 20% an Frontier.
- **Devstral Small 2 ist der KRITIKER, nicht der Coder — mit hartem 16k-Deckel (25.07.).**
Das Verdikt „als Coder disqualifiziert" (24.07.) bleibt unveraendert richtig. Neu ist nur die
ENGE Rolle: Gegenlesen einer Etappe. Gemessen am 25.07. auf der Box: Generierung 15,0 t/s
(Coder 51,5), Prefill 265-318 t/s (Coder 754). Der Prefill bricht mit der Kontextlaenge ein
(32k -> 63 t/s = ~9 min nur zum Lesen), deshalb ist der Kritiker in llama-swap UND in beiden
opencode.json auf **16384** gedeckelt: schlimmster Fall je Review bleibt unter einer Minute.
Der Nutzen liegt nicht im Tempo, sondern in der FREMDEN Modellfamilie — ein Mistral-Modell hat
andere blinde Flecken als der Qwen-Coder. Alternative GLM-4.7-Flash (MoE, schnellerer Prefill)
bleibt eine Zeile Config entfernt, kostet aber ~9 Punkte SWE-bench (59,2 vs. 68,0).
- **llama-swap haelt nur EINE Gruppe resident, und `persistent: true` ist gefaehrlich (25.07.).**
Zwei ko-residente Gruppen verdraengen sich gegenseitig — alles, was gleichzeitig warm sein muss,
gehoert in DIESELBE Gruppe (`brains`). `persistent: true` hindert llama-swap daran, vor einem
grossen On-Demand-Modell abzuraeumen: mit 107 GB Warm-Set + Vision (20 GB) folgte ein
**Kernel-OOM** (llama-server abgeschossen). Regel: `Warm-Set + groesstes On-Demand-Modell
<= ~115 GB` UND `persistent: false`. Danach lud vision in 10 s statt 117 s + Absturz.
Kontext-Halbierung spart bei Qwen3-Next uebrigens **0 GB** (Hybrid-Attention, winziger KV).