# 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.
