Grillade des décisions ouvertes
Interviewer l'utilisateur sans relâche sur un plan, un ticket ou une conception jusqu'à ce qu'une compréhension partagée soit atteinte. Le but est l'alignement avant le début du travail : un changement bâti sur une hypothèse erronée coûte toute l'implémentation, plus la revue, la recette et la fusion qui ont suivi. Une question posée en amont coûte un clic ; la même question posée en cours d'implémentation coûte à l'utilisateur un changement de contexte et bloque l'exécution jusqu'à son retour.
N'entreprendre aucune action sur le sujet de la grillade tant que l'utilisateur n'a pas confirmé que la compréhension est partagée.
La boucle
- Rechercher chaque fait vous-même (voir Faits vs décisions). Arriver à l'entrevue en connaissant déjà le code.
- Cartographier l'arbre de décision. Chaque décision ouverte se ramifie en décisions qui en dépendent.
- Résoudre ce que le ticket et les preuves résolvent. Traiter chaque décision ouverte via les cinq parties d'un bref de décision. Ce que le ticket énonce clairement est enregistré dans ses mots ; un écart où la preuve ne laisse qu'une option est enregistré avec son
Beleg:; tout le reste reste ouvert pour l'utilisateur (Résoudre ou demander). - Re-vérifier chaque question restante par rapport aux sources avant de l'envoyer (Re-vérifier avant de demander). Une question dont les sources donnent déjà la réponse coûte à l'utilisateur une décision qu'il n'avait jamais à prendre.
- Poser la frontière en un seul round. La frontière est l'ensemble des décisions ouvertes dont les prérequis sont déjà réglés : les questions que vous pouvez poser maintenant sans deviner une réponse que vous n'avez pas encore entendue. Une question qui dépend d'une autre question encore ouverte dans ce round appartient à un round ultérieur.
- Présenter chaque question avec son bref. Le bref se termine par votre recommandation, de sorte que l'utilisateur décide en un clic avec les faits en vue, sans lire le code d'abord ni composer une conception de zéro.
- Recalculer la frontière après chaque round : les décisions réglées la repoussent, débloquent les questions qui en dépendaient, et souvent retirent des questions ou les rendent assez claires pour être réglées par les preuves. Re-vérifier et poser le round suivant.
- S'arrêter quand la frontière est vide : chaque branche visitée, rien laissé silencieusement supposé. Rédiger le registre de décision et laisser l'utilisateur le confirmer.
Résoudre ou demander
Le ticket (ou le plan ou le spec en cours de grillade) est la commande, et il prime : ce qu'il énonce clairement est implémenté comme écrit, aussi exactement que possible. Les tickets sont souvent imprécis, se contredisent ou oublient des choses, et ce sont ces points qui sont décidés. Moins l'utilisateur a de décisions à prendre, mieux c'est, et chaque point flou est le sien. Le bref de décision trace la ligne : rédigez-le pour chaque décision ouverte avant de demander à quiconque, et laissez son résultat placer le point dans l'un des trois cas.
1. Le ticket y répond clairement : l'implémenter comme écrit. Le point est réglé et marqué [Ticket <ID>], même si une fonctionnalité voisine fait différemment ou si vous auriez choisi autrement. Personne n'est interrogé.
2. Le ticket est imprécis, se contredit ou omet une conséquence : l'utilisateur décide. Demander avec le bref lorsque son libellé peut se lire de deux façons ou laisse ouvert ce que signifie « fait » ; lorsque la description, les commentaires, les critères d'acceptation et la conception sont en désaccord ; lorsque son image du code actuel ne correspond pas à ce que le code montre ; ou lorsque le suivre à la lettre casserait quelque chose qu'il ne mentionne pas (comportement dont d'autres fonctionnalités dépendent, sécurité, données existantes). Ce que signifie le ticket est l'affaire de l'utilisateur, donc ces points lui reviennent même si vous penchez d'un côté.
3. Le ticket ne dit rien : régler l'écart quand la preuve est sans ambiguïté, demander autrement. Le régler vous-même quand exactement une option tient la route :
- une autre source énonce la réponse (un document lié, la conception, les docs du projet), ou le code gère ce cas exact d'une manière établie (
path:line), - rien dans les sources ou le code ne pointe dans l'autre sens,
- aucune autre option n'a un avantage que quelqu'un pourrait raisonnablement juger supérieur, et
- il n'a pas de conséquences durables (modèle de données, migration, permission par défaut, un contrat qu'un autre module ou équipe consomme). Ceux-ci reviennent à l'utilisateur chaque fois que le ticket est muet, aussi confiant que vous soyez dans votre propre raisonnement.
Enregistrer un écart réglé comme une Annahme avec sa preuve sur une ligne Beleg: (Registre de décision) ; l'utilisateur le voit en confirmant le registre et peut l'y infirmer. Tout autre écart revient à l'utilisateur avec le bref, et il en va de même pour tout point dont vous n'êtes pas sûr : le doute sur le fait qu'un point soit clair signifie qu'il ne l'est pas.
Re-vérifier avant de demander
Une question qui atteint l'utilisateur lui demande de décider, donc avant qu'un round soit envoyé, retourner aux sources avec ses questions en tête. La première lecture cherchait les exigences ; celle-ci cherche la réponse à une question spécifique, et trouve ce qu'une lecture générale laisse passer : une réponse au fond d'un fil de commentaires, une deuxième image dans la conception, un critère d'acceptation qui ne fonctionne que d'une seule manière.
- Relire le ticket en entier, avec les questions du round en tête : description, critères d'acceptation, chaque commentaire et réponse (pas seulement les plus récents), et les images qu'ils contiennent.
- Rechercher dans les autres sources les termes de chaque question, en allemand et en anglais et avec des synonymes (l'entité, le champ, le rôle, l'écran ou l'état concerné) : tickets parents, sous-tickets et liés, documents attachés, commentaires et documents de décisions antérieures, chaque image et état de la conception, les flux, les docs du projet.
- Chercher une réponse qui découle de ce qui est déjà fixé : un autre critère d'acceptation qui ne fonctionne qu'avec une option, une décision prise plus tôt dans cette grillade, un test ou une validation qui épingle déjà un comportement que le ticket laisse inchangé.
Puis trier chaque question à nouveau selon Résoudre ou demander : une réponse que le ticket énonce clairement la règle comme écrite ; une réponse dans une autre source peut régler un écart, avec son Beleg: ; une contradiction que la re-vérification a découverte reste une question, maintenant avec les deux citations. Seule une question qui survit va dans le round, et la partie 3 de son bref nomme ce que la re-vérification a couvert, de sorte que l'utilisateur voit que la question est réelle.
Bref de décision
Cinq parties dans cet ordre, chacune répondue à partir des preuves rassemblées dans cette session : le code tel qu'il est sur la branche, les sources telles qu'elles se lisent aujourd'hui.
- Ist-Stand im Code : ce que le code fait aujourd'hui là où la décision atterrit, avec
path:line. Pour quelque chose qui n'existe pas encore, le dire et nommer où vous avez cherché. Là où le ticket décrit le comportement actuel différemment de ce que le code montre, énoncer les deux : cet écart est souvent la vraie question. - Geplante Änderung : ce qui est changé, ajouté ou supprimé, comment, et pourquoi (le critère d'acceptation ou la source qui l'exige). Séparer ce qui est déjà fixé de la fourche que les options tranchent.
- Ticket und Quellen : ce que le ticket, ses commentaires, les tickets et documents liés, la conception et les docs du projet disent sur ce point, le ticket en premier, cité textuellement dans « … » avec la source entre parenthèses (ticket et section, date du commentaire, titre du document, nœud Figma,
CLAUDE.md:<line>). Citer la phrase qui compte, pas le paragraphe. Là où les sources sont en désaccord, citer chaque côté. Quand aucune source n'aborde le point, le dire et lister ce que la re-vérification a couvert : ce silence est pourquoi c'est une question. - Optionen : deux à quatre, les mêmes que celles offertes par la question, chacune avec ce qu'elle signifie concrètement, son avantage, son inconvénient et son impact : fichiers et modules touchés, données existantes, autres rôles ou consommateurs, tests, effort, et si elle est difficile à défaire plus tard. Une option que le framework livre déjà en fait partie.
- Empfehlung : l'option que vous choisiriez et pourquoi, argumentée à partir des parties 1 à 3.
Garder chaque partie à une à trois lignes : le bref est le contexte pour une décision, pas un rapport. Le rédiger est aussi le test de Résoudre ou demander : quand la partie 3 trouve une citation qui répond au point, ou la partie 1 montre que le code le décide déjà, le point est réglé et quitte le round.
**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.
Le ticket est muet, le projet a les deux précédents, et le choix façonne le modèle de données, donc cet écart revient à l'utilisateur. Si la description avait dit « Les factures supprimées restent enregistrées et sont seulement masquées », le ticket aurait réglé le point : Soft Delete, implémenté comme écrit, marqué [Ticket DEV-1234], pas de question. Si un commentaire avait exigé le contraire, la contradiction serait revenue à l'utilisateur, avec les deux citations dans la partie 3.
Format du round
Utiliser AskUserQuestion : un appel par round, jusqu'à quatre questions, chacune avec son option recommandée en premier et suffixée (Recommandé), la description de chaque option portant son impact en une ligne. L'entrée « Autre » fournie automatiquement contient les réponses en texte libre. Lorsque la frontière contient plus de quatre questions, poser d'abord les questions les plus en amont ; leurs réponses retirent généralement une partie des autres.
Placer les brefs du round dans le même message que l'appel, juste avant, numérotés pour correspondre (F1, F2, …), afin que l'utilisateur les lise avec les questions ouvertes.
Une question qui ne collecte qu'un fait que seul l'utilisateur détient (ce qu'il a observé, quel compte il a utilisé) ou un choix de workflow (lancer une revue, comment fusionner) n'a pas besoin de bref : ses libellés d'option portent l'essentiel.
Sans AskUserQuestion (chat simple, un exécuteur non interactif), imprimer le round dans ce même format et attendre les réponses.
Faits vs décisions
Trouver les faits est votre travail. Demander à l'utilisateur quelque chose que vous auriez pu lire est ce qui donne à une entrevue l'impression d'être un interrogatoire, et la réponse que vous obtenez de mémoire est moins fiable que celle du dépôt.
| Recherchez-le vous-même | Décidez (réglez à partir des preuves, ou demandez) |
|---|---|
Quels rôles un service autorise déjà (@Restricted, @Roles, securityCheck) | Quels rôles devraient être autorisés |
La forme actuelle d'une entité, d'un DTO ou d'un type généré (types.gen.ts, sdk.gen.ts) | Si un champ est ajouté, renommé ou remplacé |
| Si un endpoint, une page ou un composable existe déjà | S'il faut l'étendre ou construire à côté |
| Ce que disent réellement le ticket, ses commentaires et le nœud Figma lié | Ce que signifie le ticket là où il est ambigu |
| Comment une fonctionnalité voisine a résolu le même problème | Si cette fonctionnalité doit suivre ce précédent |
| Quels tests couvrent aujourd'hui les chemins affectés | À quelles coutures les nouveaux tests doivent se situer |
| Si le défaut décrit se reproduit encore | Quel est le comportement correct à la place |
Recourir à Read, Grep, Glob, au MCP Linear et au MCP Figma avant de recourir à une question. Là où une recherche est vaste, répartir un sous-agent pour celle-ci et ne pas bloquer dessus : une recherche en cours est un prérequis non réglé, donc seules les questions en aval de celle-ci attendent, et le reste de la frontière est posé maintenant.
Qualité des questions
- Sonder les limites, pas le chemin heureux. Vide, null, très grand, concurrent, non autorisé, hors ligne. Le chemin heureux est la partie sur laquelle tout le monde est déjà d'accord.
- Faire surface des conséquences qui survivent au ticket : un modèle de données difficile à migrer plus tard, une permission par défaut qui devient le précédent, un contrat que d'autres équipes consommeront.
- Un nouveau projet nest-server règle sa base de données dans ce round. À moins que le ticket ou une section
## Databasedans leCLAUDE.mdracine ne la nomme, la base de données et le moteur SQL sont une question (ils survivent à chaque ticket), briefée par la procédure dansgenerating-nest-servers→ reference/choosing-a-database.md : le signal des sources dans la partie 3, l'étape de décision dans la partie 5, et pour MySQL / MariaDB ce à quoi le projet renonce. Un nouveau module avec ses propres données reste dans la base de données du projet sans question ; il n'en devient une que lorsque les sources pointent vers une autre base de données (hybride). La réponse confirmée va dans le registre de décision et, en tant que## Database, dans leCLAUDE.mdracine. - Couvrir ce pour quoi l'implémentation s'arrêterait autrement. Avant de fermer, parcourir mentalement une fois le travail planifié (modèles, endpoints, permissions, états UI, tests) et passer chaque point où vous vous arrêteriez autrement à travers Résoudre ou demander. C'est ce qui rend l'exécution ultérieure sans question.
Quand l'utilisateur est injoignable
Une décision floue appartient à l'utilisateur, donc une décision bloquante n'est jamais répondue en son nom
…
[abrégé pour la traduction]