Que fait design-doc ?
gemini-4-argon écrit et révise toute la prose, y compris les résumés, les jumeaux en langage clair (plain twins), les poignées (handles), les notes de révision et le texte de publication. La session lui transmet les faits et les règles (le contrat d'écriture, les règles anti-bavardage, les limites de longueur) via gemini -m gemini-4-argon --skip-trust -p, enregistre la réponse textuellement, et collecte les preuves et publie elle-même le résultat. Les assistants de prose appellent le même modèle via gemini --skip-trust -p, sans modèle de repli.
Une conception architecturale est une pile de décisions sur une pile d'hypothèses. Cette compétence exécute la conception comme une conversation — l'utilisateur décide tout — et rend le résultat sous forme d'un document où chaque affirmation remonte à une hypothèse, une décision et le tour de questions qui l'a produite.
Une seule commande pilote les parties mécaniques :
TOOL="python3 ${CLAUDE_PLUGIN_ROOT}/skills/design-doc/scripts/design.py"
$TOOL scaffold --title <nom> # nouveau répertoire ./<slug>/ pour ce document de conception
$TOOL scaffold --example # ./tinyq/, un petit exemple complet
$TOOL check <rép> # lint des registres, des jumeaux en langage clair, du source du diagramme et du jeu de résumés ; les erreurs terminent avec un code non nul, --strict fait des avertissements bloquants des erreurs
$TOOL summary-text <rép> # le jeu de résumés en Markdown, une section ## par panneau ; l'entrée pour les portes (gates)
$TOOL plainify <rép> [--only DQ3,A2] [--dry-run]
$TOOL glossary <rép> # termes que la prose utilise et qui manquent dans le glossaire, en tant qu'entrées candidates
$TOOL build <rép> # compile components/*.tsx en components.js ; uniquement pour un document avec un répertoire components/
$TOOL render-check <rép> # rend chaque bloc Mermaid dans un Chrome sans tête ; échoue en cas d'erreur d'analyse ou d'exception de page
$TOOL pdf <rép> # imprime le document via la feuille de style d'impression du modèle dans <rép>/design-doc.pdf
$TOOL snapshot <rép> --note "…" --item "…" # estampe une révision que la vue des modifications compare ; note est le titre visible du lecteur, chaque --item un changement
$TOOL links <rép> [--fetch] [--missing] # chaque décision et élément ouvert avec ses liens de pull request et son statut ; --fetch demande à GitHub si chaque lien a été fusionné et signale les écarts, --missing liste les entrées encore non liées
Lisez reference/method.md avant la Phase 1, reference/writing.md avant la Phase 5, et reference/publish.md avant la Phase 6 — le fichier de méthode est le protocole des rounds/registres, le fichier d'écriture est le contrat de voix, le fichier de publication est le flux d'hébergement. reference/schema.md est le contrat champ par champ pour les fichiers JSON ; générez l'exemple tinyq lorsque vous voulez un registre rempli à côté du schéma.
Terminologie
- Registre — une liste structurée dans
registers.jsondont les entrées ont des ID stables :A#hypothèses,DQ#décisions,Q#questions ouvertes,V#expériences,c-<slug>cartes d'architecture. - Round — un tableau soumis à l'utilisateur, enregistré textuellement dans
qa-log.json. Un round pose chaque bifurcation ouverte à la fois, chacune comme un blocdesign-doc.fork, et ne pose rien d'autre. Les réponses qui ouvrent de nouvelles bifurcations démarrent le round suivant, à nouveau toutes à la fois ;qa-log.jsonenregistre les rounds dans l'ordre, de sorte qu'un tableau ultérieur peut dépendre d'une réponse antérieure. - Supersession — une décision modifiée reçoit une nouvelle entrée et l'ancienne reçoit
s: "superseded"plus un pointeurby, que le document rend sous forme de "Remplacé par" et le titre du successeur. L'historique reste lisible car rien n'est modifié sur place. - Étoile (
★) — marque l'hypothèse porteuse, celle dont l'échec invalide le document. - Expérience (Spike) — une expérience nommée et limitée dans le temps (
V#) qui transforme une estimation marquée(E)en un nombre mesuré. - Sommaire exécutif —
summary.html, un fragment HTML rédigé à la main à côté deregisters.json, pour le lecteur qui ne lit rien d'autre : un jeu de panneaux plein écran par défaut, une affiche lorsque la conception est une seule idée et un seul chiffre. Jamais analysé comme données ;checkvérifie sa forme, ses budgets de mots et ses citations. - Jumeau en langage clair (Plain twin) — le champ
pà côté du libellé précis d'une entrée, une ou deux phrases courtes expliquant ce que l'entrée signifie pour quelqu'un qui ne la lira pas. Le document affiche les jumeaux par défaut et le libellé exact à un basculement de distance. - Clé et thème —
key: truemarque les 3 à 8 décisions et hypothèses sur lesquelles le document s'ouvre sous forme de cartes ;themeclasse chaque entrée sous l'un des 3 à 5 thèmes de la conception, nommés dans la Phase 0 et définis dans la cartethemes. - Diagramme — la source Mermaid du diagramme système, dans la clé
diagramdu registre ; le document le rend, le lecteur peut le parcourir et le survoler, et les chemins de requête le traversent.diagram.overviewest le sous-ensemble de dix nœuds que la carte Overview dessine, le graphe complet étant à un clic. Unsysd.svgdessiné à la main reste valide commediagram.kind: "svg". - Poignée (Handle) — le champ
hsur chaque décision, hypothèse, élément ouvert, carte d'architecture et tableau de chiffres : comment un lecteur l'appellerait, deux à cinq mots. Les citations et les lignes de puces montrent la poignée ; l'ID vit dans la carte de survol. - Composant — une figure interactive déclarée dans la carte
components(dd.tabs,dd.before-after,dd.whatif,dd.steps,dd.timeline,dd.matrix, les deux figures de panneau de comparaisondd.flowetdd.lanes, la carte système dessinée à la maindd.system, etdd.arch, qui intègre un document d'architecture publié) et placée par identifiant dans le jeu de résumés ou sur une entrée ; un fichier TSX souscomponents/est l'échappatoire quebuildcompile. - Brief de figure et critique — les deux sections de NOTES.md à partir desquelles le jeu de résumés est tiré et contre lesquelles il est lu. Un brief contient cinq lignes par figure, écrites avant que la figure ne soit dessinée : le point qu'elle fait, la décision qu'elle sert par ID, la vue la plus petite qui fait le point, ce qu'elle omet et les vraies étiquettes qu'elle utilise. Ses deux premières lignes deviennent la
<figcaption>. La critique est une ligne par panneau, figure, tableau et statistique, écrite avant les portes : la décision qu'elle sert, l'affirmation qu'elle fait, la question qui reste au lecteur, et fixé ou supprimé.checkprévient lorsque l'un ou l'autre titre manque. - Lien — une entrée de
links[]sur une décision, un élément ouvert ou une ligne de constatation : la pull request, le problème, le commit ou le document qui le concrétise.closes: truesur un lien d'élément ouvert marque celui qui le retire. Le document affiche chaque lien comme une puce avec son état GitHub et précède chaque groupe ouvert du nombre de ses éléments qui sont fermés. - Statuts : les décisions sont
resolved | superseded | open, que le document rend comme Décidé, Remplacé et Toujours ouvert ; les hypothèses sontworking | validate, rendues comme Supposé et Nécessite confirmation (quelqu'un en dehors du document doit dire oui). Les éléments ouverts sontopen | closed, rendus Toujours ouvert et Fermé ; un lienclosesfusionné ferme un élément avant quesne le dise. La prose utilise les mots rendus, le JSON les valeurs.
Périmètre
Cette compétence s'arrête à la conception. Ses sorties sont un enregistrement de décisions et un document ; le code d'implémentation est une tâche différente qui commence après que la proposition survit à la révision. Quatre portes maintiennent l'enregistrement honnête :
- Les bifurcations de conception sont à la décision de l'utilisateur. Chaque bifurcation passe par un round, même lorsqu'une option semble évidemment bonne : l'enregistrement du pourquoi vaut plus que l'économie d'échange.
qa-log.jsonest textuel et en annexe uniquement. Nettoyez les fautes d'orthographe dans les réponses, ne changez rien de substantiel et ignorez les échanges explicatifs uniquement ; c'est un journal de décisions, pas une transcription.- L'artefact de révision adversarial reste en dehors du document rendu. Seules les décisions qu'elle a motivées sont livrées ; une section de constatations se lit comme de l'auto-congratulation et n'apprend rien au lecteur.
- Le document ne contient aucun décompte de vanité ("27 entrées", "9 expériences en attente"). Les nombres apparaissent lorsqu'ils décrivent le système, pas l'effort.
Phase 0 — Génération et diagnostic
Exécutez $TOOL scaffold --title <nom>. Chaque document de conception vit dans son propre répertoire frais — scaffold crée ./<slug>/ (passez un chemin explicite comme argument positionnel pour le placer ailleurs) et refuse une cible non vide, de sorte qu'une conception ne se mélange jamais dans les fichiers d'une autre ou dans ceux d'un projet existant. Interviewez l'utilisateur sur le système actuel avant de proposer quoi que ce soit : ce qui existe, ce qui fait mal et pourquoi. Écrivez le diagnostic dans NOTES.md sous forme de causes profondes, pas de symptômes ("la latence de durabilité est la latence de S3", pas "les écritures sont lentes"). Le diagnostic ne va jamais sur un tableau : écrivez-le directement dans NOTES.md, l'utilisateur le révise dans le document rendu, et chaque correction qu'il apporte est réintégrée dans ses propres mots. Terminez le diagnostic par la seule classification sur laquelle s'appuie le sommaire exécutif : un changement à un système qui existe aujourd'hui, ou nouveau, sans rien derrière à part des exigences. Nommez les trois à cinq thèmes de la conception dans la même foulée ("stockage", "distribution", "location") : ils deviennent la carte themes sous laquelle les décisions et les hypothèses sont classées, et un thème que le diagnostic ne peut pas nommer est un thème que la conception n'a pas. Concevoir contre un mauvais diagnostic gaspille toutes les phases ultérieures.
Critères de sortie : le répertoire du projet existe ; l'utilisateur a lu le diagnostic dans le document rendu, changement ou nouveau et les thèmes inclus, et est d'accord avec lui.
Phase 1 — Hypothèses
Avant le premier round, vérifiez la liste des compétences disponibles pour cc-present:present (la compétence de tableau /cc-present) et invoquez-la avec l'outil Skill lorsqu'elle est listée ; l'entretien se déroule comme un tableau en direct dès la première question, avec AskUserQuestion uniquement comme solution de repli sans cc-present. Ce plugin fournit son propre pack de blocs — exécutez cc-present pack list et lisez le fragment de référence de design-doc ; son bloc design-doc.fork est la surface d'entretien, et le seul bloc qu'un tableau d'entretien porte.
Écrivez les hypothèses directement dans registers.json ; aucun tableau ne les confirme ou ne les conteste. Ne mettez jamais de bloc design-doc.claims, de passage de confirmation/contestation ou de vidage de registre devant l'utilisateur : ils révisent les hypothèses dans le document rendu, et une correction qu'ils apportent est réintégrée dans leurs propres mots. Une hypothèse que la conception ne peut pas poursuivre sans choisir entre est une bifurcation, et va sur le tableau de la Phase 2 comme un bloc design-doc.fork. Collectez les vérités fondamentales de l'entretien de diagnostic, du code et de ce que l'utilisateur a déjà dit : les contraintes que la conception doit satisfaire, les faits sur l'échelle et la charge de travail, les choses que l'utilisateur croit mais n'a pas vérifiées. Chacune devient une entrée A# avec le statut working ou validate ; marquez d'une étoile celle qui est porteuse, et enregistrez qui doit confirmer chaque entrée validate comme un élément ouvert. Lorsque l'utilisateur signale une hypothèse comme fragile, ce drapeau va dans l'entrée ; la résoudre à sa place irait à l'encontre du but du registre.
Critères de sortie : l'utilisateur a révisé les hypothèses dans le document rendu et elles couvrent ce que l'utilisateur sait ; $TOOL check est propre.
Phase 2 — Rounds de conception
Concevez par rounds de questions. L'entretien est un tableau cc-present qui pose chaque bifurcation ouverte à la fois, chacune sous forme de bloc design-doc.fork avec des options riches : une conséquence sur chaque option, les avantages et les inconvénients, exactement une recommandée et l'échappatoire de liste ouverte. Le tableau porte des blocs de bifurcation et rien d'autre. Tout ce qui n'est pas une bifurcation est un défaut : un bloc design-doc.claims, un passage de confirmation/contestation, un vidage design-doc.registers ou un bloc de contexte. La question propre d'une bifurcation, ses conséquences et ses avantages et inconvénients portent le contexte dont elle a besoin. Les réponses qui ouvrent de nouvelles bifurcations vont sur le tableau suivant, construit de la même manière.
Les rounds s'exécutent sur un tableau cc-present en direct : avant le premier round (dans la Phase 1 et à nouveau ici), vérifiez la liste des compétences disponibles pour cc-present:present (la compétence de tableau /cc-present) et invoquez-la avec l'outil Skill — ses instructions régissent la composition et la poussée du tableau, et chaque round à partir de là passe par un tableau. Une bifurcation est un bloc design-doc.fork, dont les options portent leur conséquence en ligne et dont l'échappatoire renvoie {defer: {title, why}} : l'humain nomme la question ouverte, de sorte que le Q# atterrit sans passer un autre round à demander comment l'appeler. Là où le pack manque, un bloc choice simple porte la même forme à la main — des descriptions de conséquence sur chaque option, exactement une marquée "(Recommandé)", et une dernière option "Ajouter à la liste ouverte" qui met effectivement en file d'attente un Q# — et AskUserQuestion est la surface de dernier recours, utilisée uniquement lorsque cc-present:present est absent de la liste des compétences. Tant que la compétence de tableau existe, les bifurcations de conception ne passent jamais par AskUserQuestion. Posez chaque bifurcation comme une question simple à laquelle une personne peut répondre à froid ("Comment les workers devraient-ils recevoir les jobs?"). L'ID du registre qu'elle règle va dans le champ decides du bloc, ou suit l'header d'AskUserQuestion, jamais dans le texte de la question ; la conséquence d'une option dit ce qui se passe, pas quelle entrée elle remplace. Les rounds sont un entretien, pas un sondage : signalez les défauts du brouillon actuel, suggérez des alternatives que l'utilisateur n'a pas nommées, opposez-vous là où les preuves ne sont pas d'accord, et ne décidez rien vous-même. Chaque réponse devient un DQ# avec la résolution, les alternatives rejetées et le numéro du round. Lorsqu'un round ultérieur change une décision antérieure, remplacez-la : un nouveau DQ#, un pointeur by sur l'ancien.
Critères de sortie : aucune bifurcation non résolue ne reste en dehors de la liste ouverte ; chaque DQ# remonte à un round dans qa-log.json.
Phase 3 — Révision adversarial
Attaquez le brouillon intermédiaire, avant que le polissage ne rende les défauts plus difficiles à voir. Utilisez la compétence de plugin codex lorsqu'elle est disponible ; sinon, créez un sous-agent de contexte frais sans intérêt dans la conception et avec pour mission de l'attaquer en tant qu'ingénieur senior sceptique : bogues d'exactitude, modes de défaillance manquants, nombres injustifiés. Enregistrez la sortie textuellement sous <réviseur>-review-<date>.md, indexez chaque constatation dans le registre findings (données uniquement — jamais rendues), et traitez chacune : une nouvelle décision, un élément ouvert ou un rejet enregistré avec une raison. Une constatation corrigée par du code porte la pull request qui l'a corrigée comme cinquième élément de la ligne, dans la même forme qu'une entrée links[]. Une constatation qui nécessite la décision de l'utilisateur devient un round comme un autre, dont la question dit ce que le réviseur a trouvé, en propres termes ; le numéro de constatation
…
[tronqué pour la traduction]