- 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
74 lines
4 KiB
Markdown
74 lines
4 KiB
Markdown
# 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.py`s `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.html`s
|
|
`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.
|