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-interactive-planner-intake.md
pijukka 7c8c8c8f77 board: pin Agents column, fix smoke-test cleanup sandbox, add interactive Planner intake
- board.html: replace the collapsible "Agent profiles" <details> panel
  (which re-collapsed on every 5s refresh) with a fixed, always-visible
  Agents column on the left, plus a bulk "apply to all" runtime dropdown
  and per-phase links to view each role's agents/*.md prompt in the
  existing Intent-dialog mechanism.
- board-agent.nix/trigger.py: fix the "Smoke-Tests entfernen" 502 --
  board-agent-trigger's sandbox only had docs/intent writable, not
  docs/review/research(-intent); widened ReadWritePaths and made the
  delete loop tolerate a per-file OSError instead of dying mid-request.
- board.html: pause the periodic 5s render() while any board input/
  select/textarea has focus, instead of unconditionally rebuilding the
  DOM and stealing keystrokes out of whatever the operator was typing.
- New job_type="draft" (worker.py/trigger.py): an interactive,
  multi-turn Planner intake dialogue ("+ Karte (interaktiv)") that
  starts a card from a topic instead of a hand-written intent document.
  Each turn resends the conversation so far to a read-only, repo-less
  Planner call and gets back either a follow-up question (with
  quick-reply options) or a finished intent, which the wrapper -- never
  the model -- writes to docs/intent/<slug>.md before replacing the
  draft card with a normal "geplant" one. See
  docs/intent/board-interactive-planner-intake.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016w25covboHfcYuLXBAvX3g
2026-09-10 18:00:40 +02:00

120 lines
6.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Intent: Interaktive Intent-Erstellung über eine Planner-Konversation im Board
## Ziel
Eine dritte Art, eine Karte auf dem Intent-Board anzulegen, neben dem
manuellen Schreiben eines `docs/intent/<slug>.md`-Dokuments von Hand und
dem einfachen "+ Karte"-Backlog-Eintrag: ein Button auf dem Backlog
("+ Karte (interaktiv)"), der ein Thema entgegennimmt und daraus eine
mehrrundige Rückfrage-Konversation mit der Planner-Rolle startet, bis
genug Kontext für einen vollständigen, eigenständigen Intent vorliegt.
Motivation aus einer Live-Diskussion auf dem Board selbst (10.09.2026):
die Operator-typische Vorarbeit ("mit einem Planner reden, bis der
Auftrag klar ist") sollte auch ohne separate Chat-Session möglich sein,
direkt im Board, mit Buttons statt Freitext wo sinnvoll.
## Umfang
- Neue Karten-Quelle `"draft"` (parallel zu `"idea"`): lebt ausschließlich
in `state.json`, keine Backing-Datei, bis die Konversation
abgeschlossen ist. `create_draft(topic)` legt sie an (`draft-<uuid>`)
und queued sofort die erste Planner-Runde mit dem Thema als einziger
Nachricht.
- Neuer `job_type="draft"` in `worker.py`: `run_draft()` ruft die
Planner-Rolle **ohne jeden Repo-Zugriff** auf (kein `-C` in den
Checkout, kein `--add-dir`) — ein Entwurf hat noch keine existierenden
Dateien zu lesen, und Lesezugriff auf einen noch unfertigen,
ungescopten Intent hätte hier keinen Nutzen. Jede Runde bekommt die
vollständige bisherige Konversation als Text mitgegeben; es gibt keine
persistente Modell-Session, Kontinuität lebt ausschließlich in
`state.json`s `draft_conversation`.
- Antwortformat: pro Runde **genau ein** Marker-Block, nie beide, nie
keiner:
- `===DRAFT-QUESTION===` / `===END-DRAFT-QUESTION===`: eine konkrete
Rückfrage plus optional bis zu vier kurze Antwortvorschläge
(`optionen: a | b | c | d` oder `optionen: keine`) — das Frontend
rendert sie als Buttons, zusätzlich zu einem freien Textfeld.
- `===DRAFT-INTENT===` / `===END-DRAFT-INTENT===`: `slug:`-Kopfzeile
plus vollständiger Intent-Dokumentinhalt, exakt das
`slug: ... / --- / Inhalt`-Format, das `run_split()` für seine
`===CHILD===`-Unterblöcke bereits verwendet.
- Eine Rückfrage aktualisiert nur `draft_conversation` und setzt die
Karte auf `entwurf_frage` — kein Repo-Zugriff, kein Lock, läuft neben
Builder/Review/Research/Split her.
- Ein fertiger Intent wird **vom Wrapper**, nie vom Modell, als
`docs/intent/<slug>.md` geschrieben — derselbe "Rolle schlägt vor,
Wrapper wendet an"-Grundsatz wie bei Review/Research/Split. Dieser eine
Schreibmoment läuft unter demselben `acquire_repo_lock()` wie
`run_split()`, nicht die ganze Konversation. Ein Slug-Kollision
(Zieldatei existiert schon) verwirft den Vorschlag vollständig, die
Karte bleibt in `entwurf_fehlgeschlagen` für einen manuellen erneuten
Versuch.
- Nach erfolgreichem Schreiben ersetzt `record_draft_intent()` den
`draft-<uuid>`-State-Eintrag durch eine normale Karte unter dem neuen
Slug, Phase **"Geplant"** — kein Auto-Trigger, derselbe manuelle
"Geplant → In Umsetzung"-Weg wie jede andere Karte. `draft_origin`
verlinkt zurück auf die ursprüngliche Dialog-ID, `draft_conversation`
bleibt als Audit-Trail erhalten.
- Antworten/erneute Versuche: `answer_draft(card_id, answer)` (nur bei
Phase `entwurf_frage`, max. 4000 Zeichen, max. 40 Konversationsrunden)
und `retry_draft(card_id)` (nur bei Phase `entwurf_fehlgeschlagen`,
sendet die letzte Runde unverändert erneut). Beide über eigene
`POST /api/board/cards/<id>/draft-answer` bzw. `.../draft-retry`.
- `delete_manual_card()` (vormals `delete_idea()`) akzeptiert jetzt
`"idea"` **und** `"draft"` als löschbare Quellen — ein abgebrochener
Entwurf verschwindet über denselben "×"-Button wie eine Idee-Karte.
- Frontend: eigene Spalten-Zuordnung (`entwurf_laeuft` → "Running",
`entwurf_frage`/`entwurf_fehlgeschlagen` → "Needs attention"), eigenes
Transkript-Rendering (`appendDraftDialogue()`), Options-Buttons plus
Freitextfeld für eine offene Rückfrage, "Erneut versuchen" bei einem
Fehlschlag.
- Nebenbefund aus derselben Diskussion, unabhängig vom Rest dieses
Intents: der periodische 5-Sekunden-Refresh (`setInterval(render, ...)`)
pausiert jetzt, solange ein Formularelement innerhalb des Boards
fokussiert ist (`boardEditInProgress()`), statt bei jedem Tick
bedingungslos die gesamte DOM neu aufzubauen und damit Fokus/Eingabe zu
zerstören — betrifft auch dieses Feature direkt (ein offenes
Antwortfeld im laufenden Dialog).
## Explizit ausgeschlossen
- Datei-Anhänge (Bild, Audio) an einen Entwurf — keiner der Runtimes
bekommt über diesen CLI-Wrapper-Pfad heute nicht-textuelle Eingaben;
Audio bräuchte zusätzlich einen eigenen Transkriptionsschritt. Separater
Folgeintent, falls gewünscht.
- Eine strukturierte Formular-Alternative (feste Felder statt freier
Konversation) — als schnellerer, modellfreier Weg diskutiert, aber
bewusst nicht Teil dieses Intents.
- Eine "Telefonat"-artige Sprachschnittstelle — als Fernziel genannt,
explizit als zu früh eingestuft.
- Column-Config-UI (Runtime/Modell-Dropdown) für die Draft-Spalte — nutzt
wie `run_split()` feste `BOARD_PLANNER_*`-Defaults ohne eigenes
UI-Override.
- Automatische Qualitätsprüfung des fertigen Intent-Vorschlags — wie
überall sonst in diesem Repo liest ein Mensch das Ergebnis, bevor es
über "Geplant → In Umsetzung" weiterläuft.
- `known_card_ids()`/Fan-out-Verlinkung für Entwürfe — ein Entwurf ist
erst nach Fertigstellung eine "echte" Karte.
## Annahmen
- Die Planner-Rolle liefert ohne Repo-Kontext trotzdem sinnvolle
Rückfragen, solange die Konversation selbst genug Substanz enthält —
ungetestete Annahme, zu beobachten im echten Einsatz.
- Ein Operator bricht eine ausufernde Konversation eher selbst ab
(Löschen, neu beginnen) als bis zum harten 40-Runden-Limit zu gehen;
das Limit ist eine Notbremse, kein erwarteter Normalfall.
## Offene Risiken
- Kein Locking zwischen `answer_draft()`/`retry_draft()` und einem
bereits laufenden `draft`-Job für dieselbe Karte — zwei schnell
aufeinanderfolgende Klicks könnten zwei Runden gleichzeitig queuen.
Geringes Risiko bei einem einzelnen Operator, nicht ausgeschlossen bei
mehreren gleichzeitigen Nutzern.
- Ein Slug-Kollision bei der Finalisierung lässt den Entwurf in
`entwurf_fehlgeschlagen` liegen; ein bloßer "Erneut versuchen" sendet
dieselbe Konversation erneut und bekommt mit realistischer
Wahrscheinlichkeit wieder denselben Slug vorgeschlagen. Für den ersten
Wurf akzeptiert; falls das in der Praxis stört, bräuchte es eine
eigene "anderen Slug vorschlagen"-Rückmeldung an den Planner.