board-agent's own README documents docs/intent/ and docs/research-intent/ as tracked corpus directories, and docs/review/<slug>.md as the reviewer's persisted report per card - but the pipeline only writes these files to the checkout, it never commits them itself. This had built up a backlog of intent/review docs for cards already marked deployed or archiviert in the live board state, which were sitting uncommitted in the working tree. Adds that backlog as-is: the originating intents, their reviewer reports, the research-intent/research pair for the board UX evaluation, and one standalone process-retrospective report (board-review-pipeline-context- overhead.md, same genre as the two already-tracked audit reports in docs/review/). No code changes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T7UVrKsttMP9a6FiGFna9b
6.8 KiB
6.8 KiB
Intent: Spaltenweite Modell-/Iterations-Konfiguration — Backend-Speicher und API
Ziel
Ein neuer, additiver State-Bereich column_config in state.json sowie
zugehörige GET/POST-HTTP-Endpunkte in board-agent/trigger.py
speichern für jede der drei job-auslösenden Spalten (in_umsetzung,
review, recherche_laeuft) eine eigene Konfiguration aus Runtime,
Modell und Reasoning-Effort — bei in_umsetzung zusätzlich ein
Iterationslimit. Dies ist reine Speicher-/API-Infrastruktur; noch keine
UI und noch kein Verbraucher (Job-Trigger) liest diese Werte — das
bestehende Verhalten (globaler board_runtime()) bleibt unverändert
und unangetastet bestehen, bis Geschwister-Intents darauf umstellen.
Umfang
- Festgelegtes Schema (verbindlicher Vertrag für alle Geschwister-
Intents dieses Splits — Feldnamen exakt so übernehmen):
column_config = { "in_umsetzung": {"runtime": "codex", "model": "", "reasoning_effort": "", "iteration_limit": 20}, "review": {"runtime": "codex", "model": "", "reasoning_effort": ""}, "recherche_laeuft": {"runtime": "codex", "model": "", "reasoning_effort": ""}, }model/reasoning_effort=""bedeutet „kein Override, bestehender Env-Var-Default greift downstream weiter" — diese Semantik ist wichtig für die Geschwister-Intents, die daraus Job-Payloads bauen (dort muss""beim Zusammenbau des Payloads als fehlendes Feld behandelt werden, nicht als explizite leere Zeichenkette, damitcommon.append_model_options()/append_claude_model_options()weiterhin ihrenmodel=None-Fallback auf die bestehenden Env-Vars nehmen). board-agent/trigger.py, neben dem bestehendenboard_runtime()/set_board_runtime()(Zeile 93-103, bleibt unverändert):validate_column_config_value(column, payload): validiertruntime(wiederverwendetvalidate_runtime(), Zeile 86-90),model(Regex[A-Za-z0-9][A-Za-z0-9._:+-]*, max. 128 Zeichen, leer erlaubt),reasoning_effort(Regex[A-Za-z0-9_-]{1,32}, leer erlaubt), sowie beicolumn == "in_umsetzung"zusätzlichiteration_limit(Integer, gültiger Bereich 5–40 inklusive).load_column_config(): lieststate.json["column_config"], füllt fehlende Spalten/Felder mit den Default-Werten aus dem Schema oben auf (Rückwärtskompatibilität fürstate.json-Dateien, die den Schlüssel noch nicht kennen).set_column_config(column, updates): merged validierteupdatesin die bestehende gespeicherte Konfiguration der genannten Spalte und persistiert viasave_state()(Zeile 128) unter demselbenSTATE_LOCK(Zeile 83) wieset_board_runtime().GET /api/board/column-config→ gibt das vollständige, default-aufgefülltecolumn_config-Objekt aller drei Spalten zurück.POST /api/board/column-config/<column>(Pfad-Parametercolumn∈{in_umsetzung, review, recherche_laeuft}, sonst 404) → Body ist ein JSON-Objekt mit einer beliebigen Teilmenge der erlaubten Felder dieser Spalte; bei Validierungsfehler 400 mit{"error": "..."}; bei Erfolg 200 mit der aktualisierten Konfiguration dieser einen Spalte.GET /api/board(bestehender Handler, Zeile 717) bekommt zusätzlich den Schlüssel"column_config"in der Antwort, additiv neben dem bestehenden"runtime"-Schlüssel — Letzterer bleibt unverändert bestehen (wird von keinem Geschwister-Intent dieses Kindes entfernt).
board-agent/test_board_agent.py: Tests fürvalidate_column_config_value()/load_column_config()/set_column_config()sowie für die beiden neuen HTTP-Endpunkte (gültige/ungültigeruntime/model/reasoning_effort/iteration_limit, unbekannte Spalte → 404, Default-Werte bei leeremstate.json).board-agent/README.md: neuen Abschnitt fürGET/POST /api/board/column-config[/<column>]ergänzen, analog zum bestehenden Eintrag fürPOST /api/board/runtime(Zeile 55).
Explizit ausgeschlossen
- Keine UI-Änderung —
board.htmlbleibt in diesem Kind unangetastet (eigenes Geschwister-Intent). - Kein Umstellen der bestehenden Job-Trigger-Stellen
(
in_umsetzung-Trigger, Research-Trigger, Review-Completion) aufcolumn_config— die lesen weiterhinboard_runtime()wie bisher (eigene Geschwister-Intents). - Kein Entfernen von
board_runtime()/set_board_runtime()oder der bestehendenGET/POST /api/board/runtime-Endpunkte — die bleiben vollständig funktionsfähig, bis das Frontend-Geschwister-Intent sie ablöst. - Keine dynamische Modell-Liste aus
agents/catalog.json— Validierung bleibt reine Regex-/Bereichsprüfung, keine Whitelist-Abfrage gegen eine externe Quelle. - Kein Pro-Karte-Override — Konfiguration ist ausschließlich spaltenweit.
Annahmen
- Der oben dokumentierte
column_config-Schema-Vertrag (Feldnamen, Default-Werte, Bedeutung von"") ist für alle Geschwister-Intents dieses Splits verbindlich und wird dort unverändert vorausgesetzt. state.jsonohne den Schlüsselcolumn_configist ein gültiger, häufiger Zustand (frischer Rollout) und muss transparent auf die Default-Werte zurückfallen, ohne einen Fehler zu werfen.- Spaltenweiter statt Pro-Karte-Scope ist die gewünschte Granularität.
Offene Risiken / offene Fragen
- Modell-Whitelist im späteren Dropdown muss von Hand mit
agents/catalog.jsonsynchron gehalten werden (kein automatischer Sync) — Drift-Risiko, betrifft aber primär das Frontend-Geschwister. - Das Iterationslimit-Feld hat hier bereits eine Obergrenze (5–40) als Ressourcenschutz — falls ein anderer Wertebereich gewünscht wird, muss das hier und im Frontend-Geschwister-Intent synchron geändert werden.
STATE_LOCKschützt nur Schreiboperationen innerhalb dieses Prozesses; das bestehende Nebenläufigkeitsmodell (ThreadingHTTPServer) bleibt unverändert und war bereits vor diesem Intent so.
Erfolgskriterien
state.jsonohnecolumn_config-Schlüssel liefert beiGET /api/board/column-configdie dokumentierten Default-Werte.POST /api/board/column-config/in_umsetzungmit gültigem Body persistiertruntime/model/reasoning_effort/iteration_limitund ein nachfolgendes GET liefert exakt diese Werte.POST /api/board/column-config/reviewmititeration_limitim Body wird abgelehnt (400) oder das Feld wird ignoriert — Review kennt kein Iterationslimit.- Ungültiger Spaltenname im Pfad → 404. Ungültiges
model/reasoning_effort/iteration_limit→ 400 mit Fehlermeldung. GET /api/boardenthält weiterhin den bisherigen"runtime"- Schlüssel unverändert, zusätzlich den neuen"column_config"- Schlüssel.- Bestehende
board_runtime()/set_board_runtime()-Tests und die bestehenden/api/board/runtime-Endpunkte bleiben unverändert grün. - Neue Tests für Validierung, Defaults und beide neuen Endpunkte sind grün.