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

6.8 KiB
Raw Permalink Blame History

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.