Offene Entscheidungen durchleuchten (Grillen)
Befrage den Benutzer unerbittlich zu einem Plan, Ticket oder Design, bis ein gemeinsames Verständnis erreicht ist. Der Zweck ist die Abstimmung vor Arbeitsbeginn: Eine Änderung, die auf einer falschen Annahme basiert, kostet die gesamte Implementierung plus das Review, den Browser-Durchlauf und den Merge, der darauf folgte. Eine Frage, die vorab gestellt wird, kostet einen Klick; dieselbe Frage mitten in der Implementierung kostet dem Benutzer einen Kontextwechsel und unterbricht den Durchlauf, bis er zurück ist.
Ergreife keine Maßnahmen zum Gegenstand des Grillens, bis der Benutzer bestätigt, dass das Verständnis geteilt ist.
Der Kreislauf
- Jede Information selbst nachschlagen (siehe Fakten vs. Entscheidungen). Komme zum Interview bereits mit Kenntnis des Codes.
- Den Entscheidungsbaum kartieren. Jede offene Entscheidung verzweigt sich in die davon abhängigen Entscheidungen.
- Klärung durch Ticket und Beweislage. Arbeite jede offene Entscheidung durch die fünf Teile einer Entscheidungsskizze. Was das Ticket klar angibt, wird in seinen Worten festgehalten; eine Lücke, für die die Beweislage genau eine Option übrig lässt, wird mit ihrem
Beleg:festgehalten; alles andere bleibt für den Benutzer offen (Klärung oder Frage). - Jede verbleibende Frage erneut anhand der Quellen prüfen, bevor sie hinausgeht (Erneute Prüfung vor der Frage). Eine Frage, die die Quellen bereits beantworten, kostet den Benutzer eine Entscheidung, die er nie treffen musste.
- Die Frontier als eine Runde abfragen. Die Frontier ist jede offene Entscheidung, deren Voraussetzungen bereits geklärt sind: die Fragen, die du jetzt stellen kannst, ohne eine noch nicht gehörte Antwort zu erraten. Eine Frage, die von einer anderen, in dieser Runde noch offenen Frage abhängt, gehört zu einer späteren Runde.
- Jede Frage mit ihrer Skizze präsentieren. Die Skizze endet mit deiner Empfehlung, sodass der Benutzer mit einem Klick und den Fakten im Blick entscheidet, ohne zuerst den Code lesen oder ein Design von Grund auf entwerfen zu müssen.
- Die Frontier nach jeder Runde neu berechnen: Geklärte Entscheidungen schieben sie nach außen, entsperren Fragen, die von ihnen abhingen, und erledigen oft Fragen oder machen sie klar genug, um sie aus der Beweislage zu klären. Erneute Prüfung und nächste Runde.
- Stoppen, wenn die Frontier leer ist: Jeder Zweig besucht, nichts stillschweigend angenommen. Das Entscheidungsprotokoll schreiben und vom Benutzer bestätigen lassen.
Klärung oder Frage
Das Ticket (oder der Plan oder das zu grillende Lastenheft) ist der Auftrag und hat Vorrang: Was es klar angibt, wird so genau wie möglich wie geschrieben implementiert. Tickets sind oft ungenau, widersprechen sich selbst oder vergessen Dinge, und das sind die Punkte, die entschieden werden. Je weniger Entscheidungen der Benutzer treffen muss, desto besser, und jede unklare gehört ihm. Die Entscheidungsskizze zieht die Grenze: Schreibe sie für jede offene Entscheidung, bevor jemand gefragt wird, und lass ihr Ergebnis den Punkt in einen von drei Fällen einordnen.
1. Das Ticket beantwortet es klar: implementiere es wie geschrieben. Der Punkt ist geklärt und mit [Ticket <ID>] markiert, auch wenn eine benachbarte Funktion es anders macht oder du selbst anders gewählt hättest. Niemand wird gefragt.
2. Das Ticket ist ungenau, widerspricht sich selbst oder übersieht eine Konsequenz: Der Benutzer entscheidet. Frage mit der Skizze, wenn die Formulierung zwei Lesarten zulässt oder offen lässt, was "erledigt" bedeutet; wenn Beschreibung, Kommentare, Abnahmekriterien und Design widersprüchlich sind; wenn das Bild des aktuellen Codes nicht dem Code entspricht; oder wenn die wörtliche Befolgung etwas kaputt machen würde, was nicht erwähnt wird (Verhalten, auf das andere Funktionen angewiesen sind, Sicherheit, vorhandene Daten). Was das Ticket bedeutet, ist die Entscheidung des Benutzers, daher gehen diese Punkte an ihn, selbst wenn du zu einer Tendenz neigst.
3. Das Ticket sagt nichts: Kläre die Lücke, wenn die Beweislage eindeutig ist, ansonsten frage. Kläre es selbst, wenn genau eine Option Bestand hat:
- Eine andere Quelle nennt die Antwort (ein verlinktes Dokument, das Design, die Projektdokumentation), oder der Code behandelt diesen genauen Fall auf eine etablierte Weise (
pfad:zeile), - nichts in den Quellen oder im Code weist in die andere Richtung,
- keine andere Option hat einen Vorteil, den jemand vernünftigerweise höher bewerten könnte, und
- sie hat keine dauerhaften Konsequenzen (Datenmodell, Migration, Berechtigungsstandard, ein Vertrag, den ein anderes Modul oder Team konsumiert). Diese gehen bei Stille des Tickets an den Benutzer, so zuversichtlich deine eigene Argumentation auch sein mag.
Halte eine geklärte Lücke als Annahme mit ihrem Beweis auf einer Beleg:-Zeile fest (Entscheidungsprotokoll); der Benutzer sieht sie bei der Bestätigung des Protokolls und kann sie dort umstoßen. Jede andere Lücke geht mit der Skizze an den Benutzer, und ebenso jeder Punkt, bei dem du dir unsicher bist: Zweifel, ob ein Punkt klar ist, bedeutet, dass er es nicht ist.
Erneute Prüfung vor der Frage
Eine Frage, die den Benutzer erreicht, fordert ihn zu einer Entscheidung auf. Bevor also eine Runde hinausgeht, kehre mit ihren Fragen im Hinterkopf zu den Quellen zurück. Die erste Lesung suchte nach den Anforderungen; diese sucht nach der Antwort auf eine bestimmte Frage und findet, was ein allgemeines Lesen übersieht: eine Antwort tief in einem Kommentarthread, ein zweites Bild im Design, ein Abnahmekriterium, das nur auf eine Weise funktioniert.
- Lies das Ticket erneut vollständig, mit den Fragen der Runde im Hinterkopf: Beschreibung, Abnahmekriterien, jeden Kommentar und jede Antwort (nicht nur die neuesten) und die darin enthaltenen Bilder.
- Durchsuche die anderen Quellen nach den Begriffen jeder Frage, auf Deutsch und Englisch und mit Synonymen (die Entität, das Feld, die Rolle, der Bildschirm oder der Zustand, um den es geht): übergeordnete, untergeordnete und verlinkte Issues, angehängte Dokumente, frühere Entscheidungskommentare und -fragen in Dokumenten, jedes Bild und jeden Zustand des Designs, die Abläufe, die Projektdokumentation.
- Suche nach einer Antwort, die sich aus dem bereits Festgelegten ergibt: ein weiteres Abnahmekriterium, das nur mit einer Option funktioniert, eine in diesem Grillen bereits getroffene Entscheidung, ein Test oder eine Validierung, die das Verhalten bereits festlegt, das das Ticket unverändert lässt.
Sortiere dann jede Frage erneut nach Klärung oder Frage: Eine klare Antwort des Tickets klärt es wie geschrieben; eine Antwort in einer anderen Quelle kann eine Lücke klären, mit ihrem Beleg:; ein Widerspruch, den die erneute Prüfung aufgedeckt hat, bleibt eine Frage, jetzt mit beiden Zitaten. Nur eine Frage, die bestehen bleibt, kommt in die Runde, und Teil 3 ihrer Skizze benennt, was die erneute Prüfung abgedeckt hat, damit der Benutzer sieht, dass die Frage echt ist.
Entscheidungsskizze
Fünf Teile in dieser Reihenfolge, jeder beantwortet aus Beweisen, die du in dieser Sitzung gesammelt hast: der Code auf dem Branch, die Quellen wie sie heute gelesen werden.
- Ist-Stand im Code: Was der Code heute tut, wo die Entscheidung hinfällt, mit
pfad:zeile. Für etwas, das noch nicht existiert, sage dies und nenne, wo du gesucht hast. Wo das Ticket das aktuelle Verhalten anders beschreibt, als der Code zeigt, nenne beides: Diese Lücke ist oft die eigentliche Frage. - Geplante Änderung: Was geändert, hinzugefügt oder entfernt wird, wie und warum (das Abnahmekriterium oder die Quelle, die es fordert). Trenne, was bereits festgelegt ist, von der Gabelung, die die Optionen klären.
- Ticket und Quellen: Was das Ticket, seine Kommentare, verlinkte Tickets und Dokumente, das Design und die Projektdokumentation zu diesem Punkt sagen, zuerst das Ticket, wörtlich zitiert in „…“ mit der Quelle in Klammern (Ticket und Abschnitt, Kommentardatum, Dokumenttitel, Figma-Knoten,
CLAUDE.md:<zeile>). Zitiere den Satz, der zählt, nicht den Absatz. Wo Quellen widersprüchlich sind, zitiere jede Seite. Wenn keine Quelle den Punkt adressiert, sage dies und liste auf, was die erneute Prüfung abgedeckt hat: Dieses Schweigen ist der Grund, warum es eine Frage ist. - Optionen: Zwei bis vier, dieselben, die die Frage bietet, jede mit dem, was sie konkret bedeutet, ihrem Vorteil, ihrem Nachteil und ihren Auswirkungen: berührte Dateien und Module, vorhandene Daten, andere Rollen oder Konsumenten, Tests, Aufwand und ob es schwer rückgängig zu machen ist. Eine Option, die das Framework bereits mitbringt, ist eine davon.
- Empfehlung: Die Option, die du wählen würdest, und warum, argumentiert aus den Teilen 1 bis 3.
Halte jeden Teil auf ein bis drei Zeilen: Die Skizze ist der Kontext für eine Entscheidung, kein Bericht. Das Schreiben ist auch der Test aus Klärung oder Frage: Wenn Teil 3 ein Zitat findet, das den Punkt beantwortet, oder Teil 1 zeigt, dass der Code ihn bereits entscheidet, ist der Punkt geklärt und verlässt die Runde.
**F1 Löschverhalten von Rechnungen**
1. **Ist-Stand im Code:** `InvoiceService.delete()` löscht hart per `deleteOne` (`projects/api/src/server/modules/invoice/invoice.service.ts:88`), wird bisher aber nirgends aufgerufen. `Payment.invoice` verweist auf die Rechnung (`payment.model.ts:31`). Im Projekt gibt es beide Muster: `Order` löscht weich über `deletedAt` (`order.service.ts:54`), `Customer` hart (`customer.service.ts:71`).
2. **Geplante Änderung:** Admins bekommen in der Rechnungsliste eine Löschaktion (AK 3): neuer Endpoint `DELETE /invoices/:id`, Button in `InvoiceList.vue`. Fest steht, wer löschen darf; offen ist, ob der Datensatz dabei verschwindet.
3. **Ticket und Quellen:**
- „Admins sollen fehlerhafte Rechnungen löschen können.“ (DEV-1234, Beschreibung)
- „Löschen nur für Admins.“ (DEV-1234, Kommentar vom 02.10.2026)
- Ob gelöschte Rechnungen erhalten bleiben, sagen die Quellen nicht (geprüft: Beschreibung, 3 Kommentare, Figma-Node 12:345, `docs/`).
4. **Optionen:**
- **A Soft Delete** über `deletedAt`, wie bei `Order`. Vorteil: Historie und `Payment`-Verweise bleiben gültig. Nachteil: jede Abfrage braucht den Filter. Auswirkung: Modell, Service und drei Listen-Queries ändern sich; keine Migration, das Feld ist optional.
- **B Hard Delete**, wie bei `Customer`. Vorteil: kein Zusatzfeld, kein Filter. Nachteil: die Rechnung ist endgültig weg. Auswirkung: `Payment`-Verweise laufen ins Leere und brauchen eine eigene Behandlung.
5. **Empfehlung:** A, weil Zahlungen auf die Rechnung verweisen und eine gelöschte Rechnung sonst nicht mehr nachvollziehbar ist.
Das Ticket schweigt, das Projekt hat beide Präzedenzfälle, und die Wahl prägt das Datenmodell, also geht diese Lücke an den Benutzer. Hätte die Beschreibung gesagt: „Gelöschte Rechnungen bleiben gespeichert und werden nur ausgeblendet“, hätte das Ticket es geklärt: Soft Delete, wie geschrieben implementiert, markiert [Ticket DEV-1234], keine Frage. Hätte ein Kommentar das Gegenteil gefordert, wäre der Widerspruch mit beiden Zitaten unter Teil 3 an den Benutzer gegangen.
Rundendurchführung
Verwende AskUserQuestion: ein Aufruf pro Runde, bis zu vier Fragen, jede mit ihrer empfohlenen Option zuerst und mit dem Suffix (Recommended), die Beschreibung jeder Option trägt ihre Auswirkungen in einer Zeile. Der automatisch bereitgestellte "Other"-Eintrag trägt Freitextantworten. Wenn die Frontier mehr als vier Fragen enthält, frage die am weitesten vorgelagerten zuerst; ihre Antworten erledigen in der Regel einen Teil der restlichen.
Füge die Skizzen der Runde in dieselbe Nachricht wie den Aufruf ein, unmittelbar davor, nummeriert zur Übereinstimmung (F1, F2, …), damit der Benutzer sie mit den offenen Fragen liest.
Eine Frage, die nur eine Tatsache sammelt, die nur der Benutzer kennt (was er beobachtet hat, welches Konto er verwendet hat) oder eine Workflow-Entscheidung (ein Review durchführen, wie zu mergen), benötigt keine Skizze: Ihre Optionsbezeichnungen tragen das Wesentliche.
Ohne AskUserQuestion (einfacher Chat, ein nicht interaktiver Runner), gib die Runde in demselben Format aus und warte auf die Antworten.
Fakten vs. Entscheidungen
Fakten zu finden ist deine Aufgabe. Den Benutzer um etwas zu bitten, was du hättest lesen können, lässt ein Interview wie ein Verhör wirken, und die Antwort, die du aus dem Gedächtnis bekommst, ist weniger zuverlässig als die im Repository.
| Suche selbst nach | Entscheide (aus Beweislage klären oder fragen) |
|---|---|
Welche Rollen ein Dienst bereits erlaubt (@Restricted, @Roles, securityCheck) | Welche Rollen erlaubt sein sollten |
Die aktuelle Form einer Entität, eines DTO oder eines generierten Typs (types.gen.ts, sdk.gen.ts) | Ob ein Feld hinzugefügt, umbenannt oder ersetzt wird |
| Ob ein Endpunkt, eine Seite oder ein Composable bereits existiert | Ob es erweitert oder parallel gebaut werden soll |
| Was das Ticket, seine Kommentare und der verlinkte Figma-Node tatsächlich sagen | Was das Ticket bedeutet, wo es mehrdeutig ist |
| Wie eine benachbarte Funktion dasselbe Problem gelöst hat | Ob diese Funktion diesem Präzedenzfall folgen sollte |
| Welche Tests heute die betroffenen Pfade abdecken | An welchen Nahtstellen die neuen Tests sitzen sollten |
| Ob sich der beschriebene Fehler noch reproduzieren lässt | Was stattdessen das korrekte Verhalten ist |
Greife zu Read, Grep, Glob, dem Linear MCP und dem Figma MCP, bevor du zu einer Frage greifst. Wo eine Suche breit ist, delegiere einen Unteragenten dafür und blockiere nicht darauf: Eine laufende Suche ist eine ungeklärte Voraussetzung, also warten nur die nachgelagerten Fragen, und der Rest der Frontier wird jetzt gefragt.
Fragequalität
- Prüfe die Ränder, nicht den Happy Path. Leer, null, sehr groß, nebenläufig, nicht autorisiert, offline. Der Happy Path ist der Teil, dem alle bereits zustimmen.
- Oberflächenkonsequenzen, die das Ticket überleben: Ein Datenmodell, das später schwer zu migrieren ist, ein Berechtigungsstandard, der zum Präzedenzfall wird, ein Vertrag, den andere Teams konsumieren werden.
- Ein neues nest-server-Projekt klärt seine Datenbank in dieser Runde. Sofern das Ticket oder ein
## Database-Abschnitt in der rootCLAUDE.mdsie nicht nennt, sind die Datenbank und die SQL-Engine eine Frage (sie überleben jedes Ticket), skizziert nach der Vorgehensweise ingenerating-nest-servers→ reference/choosing-a-database.md: das Signal aus den Quellen in Teil 3, der entscheidende Schritt in Teil 5, und für MySQL / MariaDB, was das Projekt aufgibt. Ein neues Modul mit eigenen Daten bleibt ohne Frage in der Datenbank des Projekts; es wird nur dann zu einer, wenn die Quellen auf eine andere Datenbank verweisen (hybrid). Die bestätigte Antwort geht in das Entscheidungsprotokoll und, als## Database, in die rootCLAUDE.md. - Decke ab, wofür die Implementierung sonst anhalten würde. Gehe vor dem Abschluss die geplante Arbeit einmal gedanklich durch (Modelle, Endpunkte, Berechtigungen, UI-Zustände, Tests) und ordne jeden Punkt, an dem du sonst innehalten würdest, durch Klärung oder Frage ein. Das macht den nachfolgenden Durchlauf fragenfrei.
Wenn der Benutzer nicht erreichbar ist
Eine unklare Entscheidung gehört dem Benutzer, daher wird eine blockierende niemals in seinem Namen beantwortet
…
[gekürzt zur Übersetzung]