# Bericht: Aufwand zur Kontextbeschaffung in dieser Session Deine Ausgangsnachricht war ein einziger Satz, ohne Job-ID, ohne Fehlermeldung, ohne Dateiverweis: > „ein review ist auf fehlgeschlagen im intent board pipeline Intent: Isolierte Worktrees und parallele Builder-Jobs für das Board" Alles Weitere musste ich mir selbst erarbeiten. Grobe Zählung der tatsächlichen Tool-Aufrufe (Bash/Read/Grep/Edit/Write/etc.) über die gesamte Session: **rund 80**, davon der überwiegende Teil reine Kontextbeschaffung, bevor überhaupt eine Korrektur möglich war. ## Phase 1 — Wo ist die Karte, wo ist der Fehler? (~9 Aufrufe) - `git status` + Intent-Dokument lesen, um den Slug zu identifizieren - Verzeichnisstruktur suchen (`find -iname "*board*"`) — der Prompt nannte keinen Pfad - `hostname` prüfen, ob überhaupt auf blunix gearbeitet wird (wo der Live-State liegt) - `/var/lib/board-agent/{inbox,processing,failed,done}` durchsuchen, bis die passende JSON-Datei auftauchte - Die eigentliche Fehlermeldung stand am Ende in einer einzelnen Zeile: „Reviewer lieferte keinen ===REVIEW-REPORT===-Block." ## Phase 2 — Code lesen, um die Fehlermeldung überhaupt einzuordnen (~20 Aufrufe) Die Fehlermeldung allein sagt nichts darüber, *warum* der Marker fehlte. Nötig war: - `worker.py` komplett lesen (Prompt-Templates, `parse_claude_response`, `extract_review_report`, `run_review`, `process_job`) — ~460 Zeilen - `trigger.py` und `README.md` gegenlesen, um zu verstehen, welche Phasen/Spalten es gibt und ob es einen „Retry"-Mechanismus gibt (gibt es nicht) - `test_board_agent.py` an mehreren Stellen lesen, um zu verifizieren, ob `phase="review"` nach einem Review absichtlich stehen bleibt oder ein Bug ist (war Absicht — steht so in den Tests) - Mehrere `journalctl`-Läufe mit falschen Zeitfenstern (leere Ergebnisse), bis das richtige Zeitfenster und die richtige Journal-Zeile gefunden waren — der Log-Eintrag selbst enthielt aber nur dieselbe knappe Fehlermeldung, keine Rohausgabe des Modells ## Phase 3 — Root Cause: die eigentliche Modellantwort rekonstruieren (~15 Aufrufe) `worker.py` druckt die Modellantwort nur bei Erfolg — bei einem Fehler ist sie nirgends gespeichert außer im Claude-Transkript selbst. Also: - `~/.claude/projects/-home-drone-nixos-config-agents/` durchsuchen nach der passenden `.jsonl`-Sitzung anhand des Zeitfensters - Mehrfach mit `grep -o`/`wc -l` die Anzahl von `===REVIEW-REPORT===` vs. `===END-REVIEW-REPORT===` gezählt, um zu verifizieren, ob der Marker überhaupt geschrieben wurde - `python3`/`python`/`node` waren auf blunix gar nicht im Pfad verfügbar — Umstieg auf `jq`, um JSON aus der Transkript-Datei zu extrahieren - damit die tatsächliche, vollständige, aber unabgeschlossene Review-Antwort wiederhergestellt ## Phase 4 — Erster Recovery-Versuch, Blockade, Rückfrage (~5 Aufrufe) - Bericht manuell nach `docs/review/…md` geschrieben - Versuch, `state.json` per `jq` zu korrigieren → **vom Auto-Mode-Classifier blockiert** (Live-Service-State außerhalb des Repos) - Rückfrage per `AskUserQuestion` → Entscheidung für einen echten Retry über die Pipeline statt manueller Reparatur ## Phase 5 — Retry #1, gleicher Fehler, zweite Fehleranalyse (~8 Aufrufe) - Neuen Job in `/var/lib/board-agent/inbox/` geschrieben - **Fehlgeschlagene Monitor-Bedingung** (systemd meldet bei Oneshot-Services nie „active", sondern „activating" → falsches „DONE" nach 3 Sekunden, während der Job noch lief) — Wartelogik musste korrigiert und neu aufgesetzt werden - Zweites Transkript gefunden und ausgewertet → **exakt derselbe Fehler**, damit als reproduzierbar (2/2) bestätigt - Erneute Rückfrage → Entscheidung, den Root Cause im Code zu fixen ## Phase 6 — Fix, Test, Deploy, Verifikation (~15 Aufrufe) - `extract_review_report()` in `worker.py` robuster gemacht (Fallback ohne Closing-Marker) - Regressionstest ergänzt, volle Testsuite (58 Tests) über `nix-shell` laufen lassen - `predeploy-check`-Skill für blunix gestartet → `nix eval` scheiterte zunächst mit `path:`-Präfix, Umstellung auf `.` - `nix build` + `nix store diff-closures` → Diff zeigte **keine** Änderung an, obwohl der Code sich geändert hatte (bekannte Einschränkung von `diff-closures` bei unversionierten eigenen Skript-Derivationen — falscher Alarm, erst über `ExecStart`-Pfad-Vergleich aufgelöst) - Deploy erfolgte durch den Nutzer selbst („switched") — verifiziert über den geänderten `ExecStart`-Store-Pfad und einen `grep` auf den neuen Code-Kommentar, da `/run/current-system` textuell gleich aussah ## Phase 7 — Retry #2, endlich sauber (~4 Aufrufe) - Dritten Job requeued, korrekt auf „fertig" gewartet, Ergebnis geprüft → lief durch, mit einem echten (neuen) Befund: fehlende Testabdeckung für die neue Concurrency-Logik in `trigger.py`. ## Fazit Von den ~80 Aufrufen entfielen **grob 45–50 allein auf Kontextbeschaffung und Root-Cause-Diagnose**, bevor überhaupt eine Korrektur möglich war — das liegt vor allem daran, dass die Pipeline keine zentrale, aussagekräftige Fehlerquelle hat: die Fehlermeldung in `state.json`/journal ist bewusst knapp gehalten, die eigentliche Modellantwort landet nur bei Erfolg irgendwo, und bei einem Fehler existiert sie ausschließlich verstreut im Claude-Session-Transkript. Zwei zusätzliche Reibungspunkte kosteten weitere Zyklen: kein `python3` im Pfad auf blunix, und eine falsche Annahme über `systemctl is-active`-Semantik bei Oneshot-Services, die zu einer verfrühten Fehlmeldung führte.