This repository has been archived on 2026-09-17. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
nixos-config/docs/intent/board-column-config-backend-state.md
pijukka 05575df408 docs: commit backlog of already-resolved intent/review corpus files
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
2026-09-10 12:06:53 +02:00

133 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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