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-nested-child-intents.md
pijukka fae170e9ad board-agent: nested child cards + opt-in run-metrics pilot
- board.html: a card whose parent_id resolves to an existing card is
  rendered nested inside that parent instead of as a detached top-level
  column card, and stays fully draggable there
  (docs/intent/board-nested-child-intents.md).
- metrics.py (new) + hooks in worker.py/completion_watcher.py: opt-in
  run_history logging gated by BOARD_METRICS_SLUGS, exposed as a compact
  per-card summary via trigger.py/board.html.
- metrics_baseline.py (new) + worker.run_baseline(): manual CLI to send
  an intent straight to a model with no board pipeline, no repo access,
  as the comparison point for the run-metrics pilot
  (docs/intent/board-intent-run-metrics-baseline.md).
- 16 new tests, 148/148 total passing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UeyiEf4XmoPgxkarAXamGe
2026-09-09 13:56:04 +02:00

4 KiB

Intent: Kind-Intents bleiben in der Parent-Karte verschachtelt statt eigene Board-Karten zu werden

Korrektur gegenüber der ursprünglichen Fassung

Diese Karte wurde ursprünglich vor der neuen Operator-Orchestrierung entworfen (orchestration.py, Commit 1b805c0, board-intent-operator-orchestration.md) und ging fälschlich davon aus, dass Kind-Tags (Reihenfolge, empfohlenes Modell/Runtime, Iterationslimit) und automatischer Parent-Fortschritt noch fehlen. Beides existiert inzwischen serverseitig vollständig: orchestration.pys wave, recommended_lane, recommended_profile (Runtime/Modell/Reasoning/Iterationslimit), write_scope, acceptance_criteria sowie progress_all()s automatischer Parent-Fortschritt über geplant → wartet_auf_kinder → bereit_fuer_deployment/durch_kinder_blockiert. board.htmls appendOrchestrationBadges() zeigt diese Werte bereits als Badges. Der tatsächlich verbleibende Rest dieser Karte ist rein visuell: Kinder erscheinen weiterhin als eigene Karten in ihrer jeweiligen Spalte statt in der Parent-Karte eingebettet zu sein -- genau das war der ursprüngliche Kern des Wunsches ("Kind-Karten dürfen sich nicht lösen") und ist jetzt der einzige noch offene Punkt.

Ziel

Eine Karte mit gesetztem parent_id, deren Parent-Karte noch existiert, erscheint nicht mehr als eigene Karte in ihrer Spalte, sondern eingebettet innerhalb der Parent-Karte -- unabhängig davon, ob die Verknüpfung über die manuelle Fan-out-API (PATCH .../parent) oder über einen Operator-Split entstanden ist.

Umsetzung (board.html, reine Frontend-Änderung)

  • render(): die Spaltenfüllung überspringt jede Karte, deren parent_id auf eine noch existierende Karte zeigt (isNestedChild()). Existiert die Parent-Karte nicht mehr (gelöscht/archiviert-und-entfernt), fällt das Kind zurück auf die normale Anzeige in seiner eigenen Spalte, statt vom Board zu verschwinden.
  • renderCard(): rendert am Ende jeder Karte rekursiv ihre direkten Kinder (cards.filter(c => c.parent_id === card.id)) in einem eingerückten .children-Container -- jedes Kind bleibt dabei die gleiche, vollständige Karte inklusive aller Badges, Links und Dialoge.
  • Jedes eingebettete Kind bleibt einzeln draggable: die Drop-Handler hängen an der Spalten-Section, nicht an der DOM-Position der Karte, also funktioniert Ziehen eines eingebetteten Kindes in eine andere Spalte unverändert wie zuvor. Für Operator-Kinder ist das ohnehin irrelevant, da progress_all() sie bereits vollautomatisch durch die Phasen schiebt; für manuell per Fan-out verknüpfte Kinder (die weiterhin von Hand geplant -> in_umsetzung gezogen werden) bleibt der bisherige Bedienweg dadurch erhalten.
  • Zyklenschutz: ein ancestry-Set verhindert eine Endlosrekursion, falls parent_id (per manuellem PATCH .../parent, das nur "nicht sein eigener Parent" prüft) versehentlich einen Kreis bildet.

Ausgeschlossen

  • Keine Änderung an fanout.py, orchestration.py oder trigger.py -- das Datenmodell reicht bereits aus.
  • Kein neues display_mode-Feld -- Nesting gilt einheitlich für jede Karte mit gültigem parent_id, kein Opt-in nötig.
  • Kein automatischer Parent-Abschluss nach "Deployed" -- progress_all() landet bei erfolgreicher Synthese bereits bei bereit_fuer_deployment, das bleibt unverändert; "Deployed" bleibt ein manuelles Gate.
  • Keine neue "Dauer"-Anzeige pro Kind -- echte Lauf-/Kostenmetriken sind Gegenstand von board-intent-run-metrics-baseline.md, nicht dieser Karte.

Erfolgskriterien (verifiziert)

  • test_board_agent.py::NestedChildCardTests (4 neue Tests) plus alle 128 vorher bestehenden Tests laufen grün (nix shell nixpkgs#python3 -c python3 -m unittest test_board_agent, 132/132 OK).
  • Eine Karte mit parent_id auf eine existierende Karte erscheint nicht mehr zusätzlich in ihrer eigenen Spalte.
  • Eine Karte mit parent_id auf eine nicht mehr existierende Karte erscheint weiterhin normal in ihrer eigenen Spalte.