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
133 lines
6.8 KiB
Markdown
133 lines
6.8 KiB
Markdown
# 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, damit
|
||
`common.append_model_options()`/`append_claude_model_options()`
|
||
weiterhin ihren `model=None`-Fallback auf die bestehenden Env-Vars
|
||
nehmen).
|
||
- `board-agent/trigger.py`, neben dem bestehenden `board_runtime()`/
|
||
`set_board_runtime()` (Zeile 93-103, bleibt unverändert):
|
||
- `validate_column_config_value(column, payload)`: validiert
|
||
`runtime` (wiederverwendet `validate_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 bei `column == "in_umsetzung"` zusätzlich
|
||
`iteration_limit` (Integer, gültiger Bereich 5–40 inklusive).
|
||
- `load_column_config()`: liest `state.json["column_config"]`,
|
||
füllt fehlende Spalten/Felder mit den Default-Werten aus dem
|
||
Schema oben auf (Rückwärtskompatibilität für `state.json`-Dateien,
|
||
die den Schlüssel noch nicht kennen).
|
||
- `set_column_config(column, updates)`: merged validierte `updates`
|
||
in die bestehende gespeicherte Konfiguration der genannten Spalte
|
||
und persistiert via `save_state()` (Zeile 128) unter demselben
|
||
`STATE_LOCK` (Zeile 83) wie `set_board_runtime()`.
|
||
- `GET /api/board/column-config` → gibt das vollständige,
|
||
default-aufgefüllte `column_config`-Objekt aller drei Spalten
|
||
zurück.
|
||
- `POST /api/board/column-config/<column>` (Pfad-Parameter `column`
|
||
∈ `{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ür
|
||
`validate_column_config_value()`/`load_column_config()`/
|
||
`set_column_config()` sowie für die beiden neuen HTTP-Endpunkte
|
||
(gültige/ungültige `runtime`/`model`/`reasoning_effort`/
|
||
`iteration_limit`, unbekannte Spalte → 404, Default-Werte bei leerem
|
||
`state.json`).
|
||
- `board-agent/README.md`: neuen Abschnitt für
|
||
`GET/POST /api/board/column-config[/<column>]` ergänzen, analog zum
|
||
bestehenden Eintrag für `POST /api/board/runtime` (Zeile 55).
|
||
|
||
## Explizit ausgeschlossen
|
||
|
||
- Keine UI-Änderung — `board.html` bleibt in diesem Kind unangetastet
|
||
(eigenes Geschwister-Intent).
|
||
- Kein Umstellen der bestehenden Job-Trigger-Stellen
|
||
(`in_umsetzung`-Trigger, Research-Trigger, Review-Completion) auf
|
||
`column_config` — die lesen weiterhin `board_runtime()` wie bisher
|
||
(eigene Geschwister-Intents).
|
||
- Kein Entfernen von `board_runtime()`/`set_board_runtime()` oder der
|
||
bestehenden `GET/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.json` ohne den Schlüssel `column_config` ist 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.json` synchron 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_LOCK` schützt nur Schreiboperationen innerhalb dieses
|
||
Prozesses; das bestehende Nebenläufigkeitsmodell (ThreadingHTTPServer)
|
||
bleibt unverändert und war bereits vor diesem Intent so.
|
||
|
||
## Erfolgskriterien
|
||
|
||
- `state.json` ohne `column_config`-Schlüssel liefert bei
|
||
`GET /api/board/column-config` die dokumentierten Default-Werte.
|
||
- `POST /api/board/column-config/in_umsetzung` mit gültigem Body
|
||
persistiert `runtime`/`model`/`reasoning_effort`/`iteration_limit`
|
||
und ein nachfolgendes GET liefert exakt diese Werte.
|
||
- `POST /api/board/column-config/review` mit `iteration_limit` im 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/board` enthä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.
|