Conception (canon)
Une conception est réalisée lorsqu'une session ultérieure peut lire pourquoi (une décision, canon/decisions/D-n.md) et ce qui doit être respecté (règles, canon/rules/<domain>/BR-n.md) sans avoir à demander. Une conception qui ne vit que dans cette conversation est perdue.
1. Choisir le mode
| Mode | Lecture | Axe |
|---|---|---|
architecture | references/mode-architecture.md, references/architecture-patterns.md | couches, frontières, C4, migration |
api | references/mode-api.md, references/api-design.md | points de terminaison / commandes, erreurs, authentification, pagination |
database | references/mode-database.md, references/database-design.md | schéma, index, migrations, motifs d'accès |
system | references/mode-system.md, references/system-design.md | SLA, modes de défaillance, capacité |
module | references/mode-module.md | responsabilité, profondeur (test de suppression), points de couture, catégories de dépendances |
Ne lisez que les fichiers du mode dont vous avez besoin. Les références transversales (references/cross-cutting/ : autorisation, gestion des erreurs, idempotence, identité de session) sont consultées lorsque la conception les concerne.
2. Avant de concevoir
canon context <path|domain|C-n>: tout le domaine actuel, ses règles, les décisions acceptées et les modifications en cours. La conception ne doit pas contredire une règle active ou une décision acceptée ; si c'est le cas, dites-le et modifiez-les dans le même changement.canon search <sujet>: décisions et notes antérieures sur la même question. Étendez ou remplacez (--supersedes D-n), ne refaites jamais en silence.- Examinez comment 1 à 3 produits ou bibliothèques matures résolvent le même problème avant d'en inventer un.
- Lisez le code existant que vous modifiez (symboles, appelants) avant de proposer une structure.
3. Concevoir
- Formulez le problème avant de lister les options : à quelles questions cette conception doit-elle répondre, quels scénarios doit-elle servir ? Lors de l'évaluation d'une conception existante, une liste de ses défauts est une entrée, pas le cadre : un plan construit uniquement à partir de la liste des défauts est un correctif, pas une conception.
- Donnez au moins deux options réelles avec leurs compromis, et une recommandation. Réelles signifie des conceptions différentes, pas une seule conception réalisée plus ou moins (« corriger 3 choses » vs « corriger 10 choses » est une seule option). Trois options ou plus ou plusieurs dimensions → écrivez le raisonnement dimension par dimension au lieu d'une liste d'avantages/inconvénients de mémoire.
- Avant de donner la recommandation, faites-la contester une fois par un sous-agent qui voit le problème et les options mais pas votre recommandation. Demandez-lui : la question elle-même est-elle mal formulée, une conception vraiment différente manque-t-elle, dans quel scénario chaque option échoue-t-elle ? Répondez à ce qu'il soulève, puis recommandez. Sautez cette étape uniquement pour une petite conception à l'intérieur d'un module qui ne modifie aucune interface, et dites que vous l'avez sautée et pourquoi.
- Consultez la documentation officielle actuelle avant de proposer une bibliothèque, une version ou une API.
- Une question qu'un prototype jetable résout plus rapidement que l'argumentation (ce modèle d'état ou de données tient-il la route en pratique, laquelle de quelques maquettes d'écran fonctionne) est réglée d'abord avec la compétence canon-prototype ; la conception cite ensuite ce que le prototype a montré.
- Quantifiez d'abord les objectifs vagues (« rapide » → p99 sous X ms à Y req/s).
- Chaque scénario que la conception sert nomme au moins une défaillance métier qu'il doit gérer (limite atteinte, paiement refusé, autorisation révoquée en cours de route, panne amont) et comment il échoue bruyamment et de manière récupérable ; « aucun mode de défaillance ne s'applique » doit être argumenté, pas supposé.
- Pesez la complexité de chaque option par rapport à ce qu'elle coûte lorsque le scénario se produit, et posez une question pour chaque scénario : les opérations normales y mènent-elles ? Pour canon, plusieurs sessions travaillant et atterrissant en même temps est une utilisation normale ; comment un test pourrait le reproduire ne décide pas. Une situation qui nécessite une configuration ou une action anormale (un wrapper utilisateur autour d'une commande système, un backend non utilisé par défaut, tuer un processus spécifique au milieu d'une étape, une entrée hostile qui ne franchit aucune frontière de sécurité) devient une limite connue (une ligne dans les 后果 de la décision ou la règle), pas un nouveau mécanisme ; la perte de données, la sécurité et la rupture de l'une des promesses du projet (pour canon, P1 à P7 dans canon/product.md) sont les exceptions.
- Relisez vous-même le brouillon à travers les lentilles du mode. Les sous-agents de relecture parallèles (un par lentille, voir le fichier de mode) sont facultatifs : chacun part de zéro contexte et coûte des dizaines de milliers de tokens, alors utilisez-les uniquement lorsque le rayon d'impact est important (inter-module, API publique, migration de données, sécurité).
Portes de qualité (toutes doivent passer, ou dites laquelle ne passe pas et pourquoi)
| Mode | Portes |
|---|---|
architecture | chaque exigence non fonctionnelle a une réponse architecturale mesurable ; chaque tension a une décision avec justification ; les risques élevés ont des mesures d'atténuation ; phases de migration avec retour arrière |
api | chaque opération a ses erreurs ; chaque opération a son exigence d'authentification ; les problèmes de sécurité résolus ou acceptés avec justification ; pagination et limites de débit indiquées |
database | toutes les clés étrangères indexées ; chaque table justifiée par un motif d'accès ; migration sans temps d'arrêt pour chaque changement de schéma ; pas de flottant pour l'argent, fuseaux horaires sur les horodatages |
system | objectifs SLA (débit, p99, disponibilité) ; aucun point de défaillance unique non atténué ; chaque composant a un mode de défaillance et une dégradation ; capacité à 1×/10×/100× |
module | pas de cycles de dépendances ; une responsabilité claire par module ; chaque module passe le test de suppression ; pas de point de couture avec un seul adaptateur ; surface publique suffisante pour tester en boîte noire ; dépendances injectables |
Préoccupations transversales (évaluer à chaque fois ; ne sauter qu'avec une raison indiquée)
| Préoccupation | Quand | Faire |
|---|---|---|
| Sécurité | entrée utilisateur, authentification, stockage, appels externes | tracer le flux de données, lister les menaces et les mesures d'atténuation |
| Concurrence | état partagé, plusieurs sessions ou processus | nommer l'entrelacement qui pourrait le casser en utilisation normale et ce qui le rend atomique ; les plus rares sont des limites connues sauf si elles perdent des données |
| Performance | chemins sensibles à la latence, grandes données | définir un budget et montrer que la conception le respecte |
| Observabilité | nouveau composant | ce qui est journalisé ou enregistré, et comment une défaillance est remarquée |
| Confidentialité des données | données personnelles ou autres données utilisateur | classifier sa sensibilité ; chiffrement au repos et en transit ; durée de conservation et suppression ; piste d'audit de qui lit ou modifie les données |
4. Enregistrer la conception
- Décision pour chaque choix réel :
canon decision new --title "..."→ remplir 背景 (faits, données), 方案 (chaque option marquée 采用 ou 否决 avec pourquoi, au moins une de chaque), 决定, 后果. Écrivez-la en chinois (les documents canon/ sont en chinois). Sous les options, citez d'où viennent les faits, une ligne chacune :- 来源:<URL ou chemin du dépôt> "<citation exacte, 8+ caractères>"— recherchez d'abord la pratique externe, puis citez-la ; une nouvelle décision a besoin d'au moins une source, et l'atterrissage récupère chaque nouvelle source et la refuse sauf si la citation est vraiment présente. N'ajoutez pas de notes d'auto-évaluation ou de niveaux de confiance : personne ne peut les vérifier. - Règles pour chaque comportement auquel la conception engage le produit :
canon rule new --domain <d> --title "...". Une règle = un déclencheur et un résultat ; remplissez 规则 et 例子 avec des entrées concrètes des deux côtés de la frontière. Un comportement que ce changement ne construit pas (son code vient dans une étape ultérieure du plan) reçoitstatus: planneddans l'en-tête de la règle : il a besoin de 规则 et 例子 mais pas de test, et le changement qui le construit le liste sousrules:et le rend actif. Dans les 例子 d'une règle planifiée, ne fixez que les frontières que la conception établit ; les cas limites trouvés par l'implémentation sont ajoutés par l'étape qui le construit. - Fichier de modification (
canon/changes/C-n.md) : 为什么 / 要改什么 en référence à la décision et aux règles. - Si la conception change un conteneur (une partie runtime, où vivent ses données) ou un flux principal, mettez à jour
canon/architecture.mddans le même changement : il décrit le système tel qu'il est maintenant, chaque partie se terminant par ses numéros de décision. Vérifiez ses numéros de décision par rapport à ce que vous venez de décider : une décision remplacée ou modifiée signifie une ligne à réécrire. - Atterrissez comme d'habitude (
canon work land). La relecture des règles lit la décision et les règles par rapport à l'ensemble du domaine, ainsi que la vue d'ensemble ; corrigez ce qu'elle bloque.
Aucun document séparé par conception : les interfaces qui valent la peine d'être fixées avant l'implémentation (types, signatures de commandes, schéma) vont dans le fichier de modification ou le code lui-même.