Implements docs/intent/board-subintent-fanout-synthesis.md. Any two known
cards can be linked as parent/child via a new board-UI-free endpoint
(PATCH /api/board/cards/<child>/parent, body {"parent_id": "..."}), which
sets parent_id on the child and appends it to depends_on on the parent
(state.json overlay only, same pattern as every other per-card field this
board tracks). Once every child linked to a parent has reached a terminal
state (success or failure -- see fanout.child_terminal()'s per-source-type
definition), the board automatically writes a new
docs/intent/<parent>-synthese.md summarizing each child's outcome and
result link, and marks the parent so this only fires once. The synthesis
card starts in "Geplant" like any other new intent file -- no automatic
trigger, no automatic quality judgment.
fanout.py is shared by trigger.py, worker.py and completion_watcher.py
(same sibling-module import pattern as completion_watcher's existing
"import worker") and salvaged, reviewed, and wired up from an orphaned
draft an earlier automated attempt at this same intent had left behind
uncommitted after hitting its own iteration limit -- the draft's logic
checked out on review, only the integration (nix wiring, call sites,
board.html display, tests) was missing.
Also grants board-agent-trigger.service write access to docs/intent/: the
common case for a Builder-flow child (a human dragging a reviewed card to
bereit_fuer_deployment/planung_mit_feedback/deployed) only ever happens
through this always-on service, never through the oneshot worker, so it is
the only process that can run maybe_synthesize() for that transition.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F51W1LEGuSvNroZNj7vXqC
4.9 KiB
4.9 KiB
Intent: Parent-/Child-Fan-out und automatische Synthese für das Board
Ziel
Ein Parent-/Child-Kompositionsmodell für Board-Karten einführen, das
Fan-out in unabhängige Research- und/oder Builder-Unter-Intents erlaubt,
sowie die automatische Erzeugung eines Synthese-Intents, sobald alle
Kinder einen Endzustand erreicht haben — der im Bericht beschriebene
Zyklus Parent-Intent → Unter-Intents → parallele Agenten → Resultate → Synthese → Evaluation → nächste Iteration wird damit technisch
abgebildet.
Umfang
- Erweiterung des Runtime-Overlays in
state.jsonumparent_id(optional),depends_on/blocked_by(Liste von Kind-Slugs) undresult_ref(Commit-Hash bei Builder-Kindern, Berichtspfad bei Research-Kindern). - Der Worker verfolgt für jede Parent-Karte, ob alle verknüpften Kinder
einen Endzustand erreicht haben (
geprüft/archiviertbzw. Fehlerzustand für Builder-Kinder;recherche_fertig/recherche_fehlgeschlagenfür Research-Kinder). - Sind alle Kinder fertig, erzeugt das Board automatisch eine neue
Synthese-Intent-Datei (
docs/intent/<slug>.md), die jedes Kind mit Ergebnis/Ergebnislink zusammenfasst, und legt die zugehörige Karte in Phase „Geplant" an — kein automatischer Start der Umsetzung. - Builder-Kinder nutzen die Worktree-Parallelität aus
board-builder-worktree-parallelism.md. Research-Kinder laufen weiterhin unter dem bestehenden gemeinsamen Research-Lock (ggf. weiterhin seriell, auch wenn sie gemeinsam als Kinder eines Parents dispatcht werden). - Sowohl Research- als auch Builder-Unter-Intents zählen als gültige Kinder eines Parents.
Explizit ausgeschlossen
- Keine neue Evaluator-Rolle und keine automatische Qualitätsbewertung — der Synthese-Intent wird zwar automatisch angelegt, seine eigentliche Umsetzung (und jede inhaltliche Bewertung, ob das Parent-Ziel erreicht wurde) bleibt ein normaler, manuell angestoßener Intent-Durchlauf.
- Keine Board-UI-Änderung (Parent-/Child-Anzeige, Baumdarstellung) — das ist Teil der bereits vorgeschlagenen UX-Folgeintents.
- Keine Konfliktbehandlung/Merge-Logik zwischen überlappenden Kind-Intents — Fan-out gilt weiterhin nur für unabhängige Kinder, wie beim Worktree-Intent.
- Keine Änderung am Locking-/Serialisierungsmodell von Research selbst.
- Keine neue geführte Planner-Rolle/Ablaufänderung, um ein
Parent-mit-Kindern-Set in einem Schritt anzulegen — das würde selbst die
Rollen-/Katalog-Grenze für
planner.mdberühren und ist nicht Teil dieses Intents.
Annahmen
- Kinder werden ganz normal als eigene Intent-/Research-Intent-Dateien vom
Nutzer/Planner erstellt; die Verknüpfung zu einem
parent_iderfolgt über einen leichtgewichtigen Mechanismus (z. B. eine kleine API-Ergänzung oder einen manuellen State-Eintrag), ohne dass dafür Board-UI-Arbeit nötig ist. - „Alle Kinder fertig" bedeutet: jedes Kind hat irgendeinen Endzustand erreicht — erfolgreich oder fehlgeschlagen; die Synthese soll auch über Teilfehlschläge berichten können, statt auf eine manuelle Wiederholung zu warten.
board-builder-worktree-parallelism.mdist umgesetzt, bevor Builder-Kinder in der Praxis genutzt werden.
Offene Risiken
- Der genaue Mechanismus zum initialen Verlinken von Kindern mit einem
parent_idist noch nicht festgelegt (kleine API vs. manueller State-Eintrag) — muss in der Umsetzung konkretisiert werden. - Unklar, ob die Synthese bei einem fehlgeschlagenen Kind sofort auslösen soll (mit dokumentiertem Teilfehlschlag) oder auf eine manuelle Wiederholung warten sollte — diese Rohfassung geht von „sofort, auch bei Fehlschlag" aus, das sollte beim Bauen noch einmal bestätigt werden.
- Ein automatisch erzeugter Intent umgeht den normalen Planner-Dialog (Rückfragen, Nutzerbestätigung) — sein Inhalt ist zwangsläufig weniger durchdacht als ein von Hand erarbeiteter Intent; ein Review-/Bearbeitungsschritt vor dem eigenen „In Umsetzung" ist essenziell und darf nicht übersprungen werden.
- Gemischte Research- und Builder-Kinder unter einem Parent bringen zwei unterschiedliche Lock-/Nebenläufigkeitsmodelle zusammen — vor produktivem Mischbetrieb lohnt sich ein Pilot mit nur einer Kind-Art.
Erfolgskriterien
- Eine Parent-Karte kann N Kinder (Research und/oder Builder) über
parent_id/depends_oninstate.jsonreferenzieren. - Sobald alle Kinder eines Parents einen Endzustand erreicht haben, erzeugt das Board automatisch einen Synthese-Intent mit Zusammenfassung und Ergebnislinks je Kind, in Phase „Geplant".
- Der Synthese-Intent braucht den normalen manuellen „Geplant → In Umsetzung"-Trigger — keine automatische Weiterverkettung über seine Erzeugung hinaus.
- Builder-Kinder laufen über die Worktree-Parallelität, Research-Kinder über das bestehende Research-Lock.
- Bestehende Einzelkarten ohne
parent_idfunktionieren unverändert weiter.