Implements Phase 1 of docs/intent/git-intent-board-feedback.md: the kanban board pilot (board-agent) gains a job_type field and now drives the real Builder and Reviewer roles instead of only ever running admin.md. - board-agent/trigger.py: jobs carry job_type (default "builder"). - board-agent/worker.py: "builder" jobs translate and hand off into agent-codex's existing builder-inbox queue (sender=requested_by= Builder owner, so they run immediately) instead of duplicating builder.py's atomic-session/iteration-limit/stash-commit logic here. "review" jobs run `codex exec --sandbox read-only` against agents/reviewer.md and extract a ===REVIEW-REPORT=== marker block to write docs/review/<slug>.md themselves, outside Codex's sandbox -- corrected after live-testing this environment's codex-cli build showed `--sandbox workspace-write --add-dir <dir>` does NOT scope writes to that directory as the intent document assumed (a write outside it still succeeded); `--sandbox read-only` is a real, verified restriction, so the "Codex proposes, wrapper applies" marker pattern (already used for builder.py's ===COMMIT-MESSAGE===) replaces the originally planned sandbox scoping. - board-agent/completion_watcher.py (new): reacts to a finished board-triggered Builder run and auto-queues the follow-up review job, or just records the outcome if nothing was committed. - agent-codex/builder.py: opt-in completion-hook (on_complete_dir) so board-triggered jobs can be observed asynchronously; a no-op for ordinary XMPP-driven jobs, which never set that field. - Nix wiring for the new completion-watcher service/path unit and the cross-service ReadWritePaths it needs. Two of the intent document's assumptions didn't hold and were changed rather than implemented as originally specified (documented in the intent doc's Status note and this repo's READMEs): no reusable oauth2-proxy/Dex mechanism exists for internal routes, so auth stays Traefik BasicAuth for this phase; and board-triggered Builder jobs reuse the existing shared-checkout/stash execution model instead of new isolated git worktrees. 68 agent-codex tests + 15 new board-agent tests pass; blunix toplevel builds clean. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ANg2L2xUmNJ45t9mcv6HVT
229 lines
13 KiB
Markdown
229 lines
13 KiB
Markdown
# Intent: Git-natives Intent-Board mit Reviewer-Feedback
|
|
|
|
## Ziel
|
|
|
|
Ein Git-natives Intent-Board ersetzt Vikunja für den Lebenszyklus
|
|
`Idee/Backlog → Geplant → In Umsetzung → Review → bereit für Deployment →
|
|
Deployed` mit kontrolliertem Rückfluss `Review → Planung mit Feedback`.
|
|
Ein Web-UI auf blunix visualisiert den Zustand und löst zwei Übergänge
|
|
aktiv aus. Löst und ersetzt `docs/intent/kanban-board-admin-trigger.md`.
|
|
|
|
**Konsolidierung (2026-09-06):** dieses Dokument ist jetzt auch die
|
|
alleinige Fortsetzung von
|
|
`docs/intent/builder-pipeline-git-intent-board-feedback.md`, das
|
|
dieselbe Ausbaustufe in einer früheren, allgemeineren Fassung
|
|
beschrieben hatte, ohne sie explizit abzulösen. Beide Dokumente
|
|
entstanden im selben Planungsschritt (Commit `3909cbf`); die
|
|
Iterationslimit-Hälfte davon wurde als eigener, engerer Intent
|
|
ausgekoppelt (`docs/intent/builder-iterationslimit.md`, umgesetzt und
|
|
deployed 2026-09-06, Commit `e8983e4`) und ist damit erledigt, nicht mehr
|
|
offen. Die verbleibende Board-Hälfte lebt ab jetzt ausschließlich hier;
|
|
`builder-pipeline-git-intent-board-feedback.md` bleibt als historisches
|
|
Dokument liegen, wird aber nicht mehr separat umgesetzt (gleiches Muster
|
|
wie bei `kanban-board-admin-trigger.md` oben). Inhalte aus dem
|
|
abgelösten Dokument, die hier noch fehlten, sind unten eingearbeitet
|
|
(Modellwahl-Abschnitt, zwei zusätzliche offene Risiken).
|
|
|
|
**Status: Phase 1 umgesetzt und deployed (2026-09-06).** Kern des
|
|
Job-getypten Queue-/Watcher-Mechanismus, Builder-Wiederverwendung über
|
|
`agent-codex`s bestehende `builder-inbox/`, headless Reviewer-Runner und
|
|
automatische Phasenübergänge stehen (`hosts/blunix/localServices/agent-codex/builder.py`
|
|
Completion-Hook, `hosts/blunix/localServices/board-agent/worker.py` +
|
|
`completion_watcher.py`). Zwei Annahmen unten stimmten nicht mit der
|
|
Realität überein und wurden dabei bewusst geändert statt umgesetzt wie
|
|
ursprünglich spezifiziert:
|
|
|
|
- **Auth bleibt vorerst Traefik-BasicAuth**, nicht OIDC/Dex — es gibt im
|
|
Repo keinen wiederverwendbaren `oauth2-proxy`/Dex-Mechanismus für
|
|
interne Routen (verifiziert 06.09.2026: `oauth2-proxy` ist eine
|
|
Singleton-Instanz vor einem einzigen, aktuell deaktivierten Backend).
|
|
OIDC-Self-Check (wie Forgejo/GoToSocial/Headscale) bleibt ein
|
|
eigenständiger Folge-Intent.
|
|
- **Builder-Artefakt: bestehendes Stash-Modell wiederverwendet, keine
|
|
isolierten Worktrees.** Board-Jobs laufen über den bereits gebauten,
|
|
getesteten `agent-codex`-Builder (Lock + `git stash` im geteilten
|
|
Checkout) statt über neue Worktree-Infrastruktur — bewusste
|
|
Entscheidung, siehe "Offene Risiken" unten.
|
|
- Zusätzlicher Fund: Reviewer läuft `--sandbox read-only`, nicht
|
|
`workspace-write --add-dir docs/review` — Letzteres scoped
|
|
Schreibrechte in diesem `codex-cli`-Build nachweislich NICHT
|
|
pfadgenau (live getestet). Reviewer liefert seinen Bericht stattdessen
|
|
als `===REVIEW-REPORT===`-Marker-Block, den der Wrapper außerhalb der
|
|
Sandbox schreibt.
|
|
|
|
**Weiterhin nicht Teil dieser Phase** (unverändert offen):
|
|
`docs/board/<slug>.yaml` mit automatischen lokalen Git-Commits (Board
|
|
bleibt bei `state.json`) und die Planner-Modellwahl-Eskalation aus dem
|
|
Umfang-Abschnitt unten (kein Planner-Handoff-Mechanismus für
|
|
Board-Karten vorhanden, der strukturierte Metadaten liefern könnte).
|
|
|
|
## Umfang
|
|
|
|
- `docs/intent/<slug>.md` bleibt der fachliche Auftrag; pro Intent eine
|
|
versionierte `docs/board/<slug>.yaml` mit Phase, Job-ID, Modellprofil +
|
|
Begründung, Iterationslimit/verbrauchte Iterationen (aus
|
|
`docs/intent/builder-iterationslimit.md`), Worktree-/Branch-Referenz,
|
|
Prüf-Commit, Reviewer-Bericht(e), Review-Entscheidung, Zeitpunkte,
|
|
Fehlerstatus.
|
|
- **Modellwahl** (aus `builder-pipeline-git-intent-board-feedback.md`
|
|
übernommen, dort wie in `builder-iterationslimit.md` bereits
|
|
spezifiziert): Standard ist ein günstiges Modellprofil. Der Planner
|
|
darf pro Auftrag ein stärkeres, individuell begründetes Profil
|
|
anfordern — ausschließlich aus den bekannten, konfigurierten
|
|
Profilen, niemals aus Freitext innerhalb eines Intent- oder
|
|
Reviewer-Textes heraus. Modellprofil und Begründung werden als
|
|
strukturierte Auftragsmetadaten übergeben und landen als eigene
|
|
Felder in der Board-Metadatei (siehe oben). Das Iterationslimit gilt
|
|
unabhängig vom gewählten Modell. Der Planner darf zusätzlich ein
|
|
aufgabenspezifisches Iterationsbudget vorschlagen; die Plattform
|
|
validiert es gegen die globale Obergrenze (20, siehe
|
|
`builder-iterationslimit.md`) — der genaue Validierungsmechanismus ist
|
|
Sache der Umsetzung.
|
|
- Web-UI (Tailnet-only, ausschließlich blunix) hinter der **bestehenden**
|
|
`oauth2-proxy`/Dex-Grenze für interne Dienste — keine eigene
|
|
Auth-Implementierung. Nur du (lukas) erfüllst den geforderten
|
|
OIDC-Gruppenclaim/Identität für die auslösende Aktion.
|
|
- **Ein generischer, parametrisierter Queue-/Watcher-Mechanismus**: ein
|
|
`systemd.paths`-Unit beobachtet ein Queue-Verzeichnis, Jobs tragen ein
|
|
Feld „Job-Art" (`builder` oder `review`) und werden davon abhängig an
|
|
die passende Rolle headless übergeben. Der zugehörige Dienst verarbeitet
|
|
Jobs mit **Concurrency=1** streng seriell — dadurch strukturell keine
|
|
parallelen Schreiber auf dieselbe Board-Datei, kein separates
|
|
Git-Lock-Konzept nötig.
|
|
- Aktiv steuerbar sind genau zwei Übergänge über denselben Mechanismus:
|
|
1. **Geplant → In Umsetzung**: durch dich im Web-UI ausgelöst, legt
|
|
einen `builder`-Job in die Queue. Dieser ruft die **bestehende
|
|
Builder-Rolle** headless auf (ihr bereits vorgesehener Start
|
|
`xmpp-worker` deckt das ab) — nicht den Administrator. Das
|
|
entspricht dem bestehenden Builder-Vertrag (Schreibzugriff,
|
|
Commit/Push erlaubt, kein Deploy) und weicht nicht von der
|
|
„Orchestrator ist einzige Dialogschnittstelle"-Regel für sichtbare
|
|
Spezialisten ab, weil der Builder ohnehin schon headless/direkt
|
|
ansprechbar ist.
|
|
2. **Erfolgreicher Builder-Prüf-Commit → Review**: vollautomatisch,
|
|
legt einen `review`-Job in dieselbe Queue.
|
|
- Builder-Artefakt: isolierter lokaler Git-Worktree/Job-Branch, bei Erfolg
|
|
ein lokaler Prüf-Commit, Board referenziert Commit-Hash/Branch/
|
|
Diff-Basis; Haupt-Checkout bleibt frei von halbfertigen Änderungen; bei
|
|
Limitüberschreitung (siehe `builder-iterationslimit.md`) bleibt
|
|
Zwischenstand im Worktree, gilt nicht als fertiger Prüfstand.
|
|
- Reviewer: **keine neue Aufgabenart** — die bestehende freie Diff-Review
|
|
in `reviewer.md` bekommt einen zusätzlichen, klar markierten Absatz: bei
|
|
Auslösung durch den Board-Trigger mit festem Commit-Scope schreibt sie
|
|
zusätzlich einen Bericht nach `docs/review/<slug>.md` (Intent-Slug,
|
|
geprüfter Commit, Scope/Prüfmethoden, priorisierte Befunde,
|
|
Unsicherheiten, Entscheidung, Empfehlungen) und trifft eine der zwei
|
|
Entscheidungen unten. Dieser Lauf darf headless statt `herdr-visible`
|
|
laufen (Abweichung vom sonstigen Start-Modus der Reviewer-Rolle, nur für
|
|
diesen Trigger).
|
|
- Review-Entscheidungen: `bereit für Deployment` (Board → Wartephase,
|
|
Mensch entscheidet über Push/Merge/Deployment) oder `zurück zur
|
|
Planung` (Board → Feedback-/Planungsphase, Bericht bleibt dauerhaft,
|
|
**keine** automatische neue Planner-Session — du startest sie bewusst
|
|
mit Intent+Bericht als Kontext). Nach manuellem Deployment setzt du die
|
|
Karte selbst auf `Deployed`.
|
|
|
|
## Explizit ausgeschlossen
|
|
|
|
- Ersetzt `docs/intent/kanban-board-admin-trigger.md` und
|
|
`docs/intent/builder-pipeline-git-intent-board-feedback.md` fachlich;
|
|
beide Dateien bleiben als historische Dokumente liegen, werden aber
|
|
nicht mehr separat umgesetzt.
|
|
- Kein automatischer Git-Push, kein automatisches Merge/Deployment/
|
|
Aktivierung.
|
|
- Keine automatische Planner-Session, keine automatische
|
|
Builder-Korrektur direkt aus dem Reviewer.
|
|
- Keine Verwendung/Integration von Vikunja, keine neue externe
|
|
Datenbank/SaaS-Abhängigkeit.
|
|
- Keine Änderung an `tnix`/`pinix`, keine Änderung am bestehenden
|
|
Dashboard-Stack.
|
|
- Kein öffentlicher Zugriff auf das Web-UI, kein roher API-Key für
|
|
Agentenläufe.
|
|
- Keine eigene Identitätsprüfung außerhalb des bestehenden
|
|
Dex/oauth2-proxy-Musters.
|
|
- Kein separates Git-Level-Lock-Konzept (ersetzt durch
|
|
Concurrency-1-Queue).
|
|
- Keine neue, eigenständig dokumentierte Reviewer-Aufgabenart.
|
|
- Kein neuer Rollenkatalog-Eintrag für die reine Plattforminfrastruktur
|
|
(Web-UI-Dienst, Queue-Verzeichnis, `systemd.paths`-Watcher,
|
|
`oauth2-proxy`-Route) — analog zu `agent-codex` reine NixOS-Dienste
|
|
ohne eigenen Agent-Rolleneintrag.
|
|
|
|
## Annahmen
|
|
|
|
- Primärer Ausführungspunkt bleibt `blunix`; Git ist der dauerhafte
|
|
Audit-Trail.
|
|
- `docs/intent/builder-iterationslimit.md` ist umgesetzt und deployed
|
|
(2026-09-06, Commit `e8983e4`) — dieses Dokument definiert das Limit
|
|
nicht neu, referenziert dessen Daten (Limit 20, verbrauchte
|
|
Iterationen) nur im Board.
|
|
- Reviewer bleibt read-only gegenüber Code/Konfiguration; einzige neue
|
|
Schreibausnahme ist der Bericht unter `docs/review/`.
|
|
- „Builder" umfasst auch den Administrator bei technischen
|
|
Plattformänderungen; der `builder`-Job-Typ aus der Queue ruft aber
|
|
konkret die Builder-Rolle auf, nicht den Administrator.
|
|
- Der bestehende `oauth2-proxy`/Dex-Mechanismus lässt sich analog zu
|
|
anderen internen Diensten auf dieses Web-UI anwenden.
|
|
- Die Umsetzung ändert `agents/reviewer.md` (neuer Absatz für
|
|
board-getriggerten Review), `agents/catalog.json` und
|
|
`agents/claude-settings/reviewer.json` (Versionsbump, Klarstellung des
|
|
headless-Starts für diesen Trigger).
|
|
|
|
## Offene Risiken
|
|
|
|
- **Entschieden und umgesetzt (2026-09-06):** Board-Jobs verwenden den
|
|
bestehenden, geteilten Builder-Checkout (Lock + `git stash`,
|
|
`locked_repos()`/`stash_foreign_changes()`) statt eines isolierten
|
|
Worktrees/Job-Branches — die "Builder-Artefakt"-Formulierung oben gilt
|
|
fachlich als entsprechend abgeschwächt für diese Phase. Wiedervorlage,
|
|
falls echte Parallelität mehrerer gleichzeitiger Board-Jobs mal
|
|
gebraucht wird.
|
|
- **Neu, aus der Konsolidierung:** ein lokaler Commit ohne Push kann auf
|
|
einem anderen Checkout (z. B. dem Recovery-Checkout auf pinix)
|
|
unsichtbar bleiben. Der manuelle Veröffentlichungsweg (wer pusht wann,
|
|
von welchem Checkout aus) muss dokumentiert sein, bevor das Board
|
|
produktiv genutzt wird.
|
|
- **Bereits gelöst, nicht mehr offen:** zuverlässiges Zählen der
|
|
Codex-JSON-Ereignisse für das Iterationslimit — erledigt in
|
|
`common.run_streaming()`/`builder.py` (`item.completed`-Events, live
|
|
gegen `codex-cli` verifiziert). Ebenso bereits gelöst: der
|
|
board-getriggerte Reviewer-Absatz existiert schon in
|
|
`agents/reviewer.md` (Commit `3909cbf`), muss also bei der Umsetzung
|
|
nur noch tatsächlich aufgerufen werden, nicht neu entworfen.
|
|
- Selbst-Trigger-Vermeidung: auch mit Concurrency-1-Queue muss der
|
|
Watcher-Mechanismus so gebaut sein, dass er nicht auf eigene
|
|
Status-Update-Schreibvorgänge in der Board-Datei reagiert (Trigger
|
|
sollte an neue Job-Dateien in der Queue gebunden sein, nicht an jede
|
|
Änderung der YAML-Datei selbst) — Detailkonstruktion ist Sache der
|
|
Umsetzung.
|
|
- Abgebrochener Worktree braucht Aufräum-, Wiederaufnahme- und
|
|
Verwerfungsregeln.
|
|
- Exaktes Job-/Queue-Schema für beide Job-Arten, Fehlerbehandlung bei
|
|
abstürzendem/unterbrochenem Lauf (z. B. durch einen Deploy, der den
|
|
Worker-Dienst neu lädt).
|
|
- Automatische lokale Board-Commits brauchen eine technische
|
|
Git-Identität.
|
|
- **Vertagt (2026-09-06):** genaue OIDC-Gruppen-/Claim-Anforderung für den
|
|
Trigger-Endpunkt — Auth bleibt für diese Phase BasicAuth (siehe
|
|
Status-Notiz oben), wird also erst mit dem OIDC-Folge-Intent relevant.
|
|
## Erfolgskriterien
|
|
|
|
- Board aktualisiert Zustand ausschließlich über versionierte
|
|
Metadateien und lokale Git-Commits, kein automatischer Push/Deploy.
|
|
- Eine fertige Intent-Karte lässt sich im Web-UI nur von dir (verifiziert
|
|
über die bestehende OIDC-Grenze) von „Geplant" nach „In Umsetzung"
|
|
bewegen und löst nachweisbar einen echten headless Builder-Lauf aus.
|
|
- Jeder erfolgreiche Builder-Commit startet automatisch genau einen
|
|
Reviewer-Lauf über denselben generischen Mechanismus, der einen
|
|
Bericht unter `docs/review/` erzeugt.
|
|
- Zu keinem Zeitpunkt schreiben zwei Prozesse gleichzeitig dieselbe
|
|
Board-Datei (verifiziert durch Concurrency-1-Queue-Verhalten).
|
|
- Positiver Review → `bereit für Deployment`; negativer Review →
|
|
`zurück zur Planung` mit Bericht im Planner-Kontext verfügbar.
|
|
- Web-UI läuft ausschließlich Tailnet-erreichbar hinter bestehender
|
|
OIDC-Grenze, kein öffentlicher Zugriff, kein roher API-Key.
|
|
- Ablauf funktioniert ohne Vikunja, ohne neue externe Datenbank, ohne
|
|
Änderungen an `tnix`/`pinix`/Dashboard-Stack.
|
|
- `docs/intent/kanban-board-admin-trigger.md` und
|
|
`docs/intent/builder-pipeline-git-intent-board-feedback.md` gelten als
|
|
durch diesen Intent abgelöst.
|