Bibliothèque de playbooks
Garde-fous pour le code généré par IA
Le code écrit par un agent échoue autrement que le code écrit par un humain. Il n'oublie pas un point-virgule : il invente une API plausible, laisse les deux implémentations en place, écrit un test qui vérifie qu'un mock a été appelé, et transforme une erreur en valeur par défaut. Ces règles sont agnostiques du langage et décrivent à quoi ressemble la production d'un agent quand elle n'est pas terminée.
- Écrit pour
- Toute équipe où les agents (Claude Code, Cursor, Copilot) écrivent une part significative du diff.
- Non couvert
- C'est un complément à votre playbook de stack, pas un remplacement. Il ne dit rien de votre architecture — il ne fait qu'intercepter les façons précises dont du code généré arrive en ayant l'air terminé sans l'être.
10 règles4 bloquantes5 warning1 info
01 Les imports nomment de vrais paquets et de vrais symboles
errorChaque import ajouté par un changement nomme un paquet qui existe réellement et un symbole que ce paquet exporte réellement — pas de helper inventé, pas de méthode empruntée à une bibliothèque voisine, pas d'import d'un module que le changement ne crée jamais. Les imports hallucinés sont la défaillance signature du code généré, et des attaquants publient des paquets sous les noms les plus couramment hallucinés, précisément pour qu'une installation par erreur exécute leur code.
Bloque : au mieux cela échoue à l'exécution, au pire cela installe le code de quelqu'un d'autre. Jugé sur les lignes d'import que le changement ajoute — savoir si une dépendance déjà déclarée figure toujours dans le manifeste relève de votre lockfile, pas de cette règle.
Portéetout le repo
Tagsai-codesupply-chaincorrectness
02 Aucun placeholder dans un diff annoncé prêt
error`TODO`, `FIXME`, `...`, `pass # implement`, `throw new Error("not implemented")` et les valeurs de retour bouchonnées ne doivent pas apparaître dans une pull request ouverte pour revue. Le code d'échafaudage généré se lit comme du code fini — tout ce qui l'entoure est entièrement écrit — si bien qu'un placeholder au milieu survit à la revue bien plus souvent qu'une fonction manquante.
Bloque : c'est un trou connu qui part en production sous les apparences d'un travail terminé.
Portéetout le repo
Tagsai-codecompleteness
03 Aucun catch silencieux
errorUn bloc catch journalise avec du contexte, puis relève l'erreur ou renvoie un échec typé. Un catch vide, ou qui avale l'erreur dans une valeur par défaut, est refusé — sauf si un commentaire sur la même ligne explique pourquoi ce défaut est le bon résultat. Les agents résolvent l'incertitude en interceptant l'erreur et en continuant, ce qui transforme un bug bruyant en réponse fausse et silencieuse.
Bloque : une erreur avalée transforme une défaillance analysable en données inexplicables.
Portéetout le repo
Tagsai-codeerrorsreliability
04 Les boucles sur des systèmes externes sont bornées
errorToute boucle de retry, de pagination, de polling ou tout `while (true)` déclare un nombre maximum d'itérations et un backoff. Un retry non borné contre une dépendance dégradée est une panne auto-infligée : votre service transforme la minute de lenteur d'un partenaire en attaque par amplification de trafic, contre lui et contre vous.
Bloque : le rayon d'impact dépasse votre propre service.
Portéetout le repo
Tagsai-codereliabilityresilience
05 Ne réimplémentez pas ce que le changement importe déjà
warningUn changement ne doit pas réécrire à la main une opération pour laquelle il importe déjà un helper, ni ajouter deux implémentations du même utilitaire — formatage de date, retry, slugify, clone profond, formatage monétaire. Les agents écrivent de zéro par défaut, parce que c'est plus rapide que de chercher ; trois formateurs de date, c'est ainsi qu'une codebase cesse d'avoir un seul comportement.
Avertit : la duplication est un coût de maintenance, pas un défaut — et la gate ne voit que la duplication interne au changement. Un helper qui existe déjà ailleurs dans le repo reste à la charge du reviewer.
Portéetout le repo
Tagsai-codeduplicationmaintainability
06 Un client HTTP, un framework de test, un style d'import
warningUn changement ne doit pas introduire une seconde façon de faire ce qu'il fait déjà ailleurs dans le même changement : un `require` à côté d'un `import`, un nouveau client HTTP en plus des appels qu'il vient d'écrire, une deuxième bibliothèque d'assertions dans le même fichier de test, deux formes d'erreur différentes pour un même type d'échec. Le coût n'est pas esthétique — il double ce que chaque futur lecteur, humain ou agent, devra garder en tête.
Avertit : c'est de la dérive, pas de la casse — et le jugement porte sur les lignes ajoutées par le changement, donc la cohérence avec le reste du fichier, non modifié, reste une décision humaine.
Portéetout le repo
Tagsai-codeconsistency
07 Aucune alternative morte laissée dans le diff
warningUn diff ne doit pas ajouter d'implémentation commentée, de helper inutilisé, ni de second chemin de code gardé « au cas où ». Les agents se couvrent en laissant les deux versions en place ; le lecteur suivant — humain ou agent — ne peut pas dire laquelle est la conception voulue, et les conservera toutes les deux.
Avertit : c'est de l'encombrement au coût cumulatif, pas un défaut en soi.
Portéetout le repo
Tagsai-codedead-code
08 Les tests vérifient un comportement, pas une mécanique
warningUn nouveau test doit échouer si le comportement casse. Les tests qui se contentent de vérifier qu'un mock a été appelé, qui prennent un snapshot d'une structure entière sans rien affirmer sur son sens, ou qui réimplémentent la fonction testée, sont refusés. Les tests générés sont optimisés pour passer, et un test qui ne peut pas échouer est pire que pas de test — il achète de la confiance sans rien derrière.
Avertit : un test faible n'est pas une panne, mais c'est un faux signal dans toutes les revues à venir.
Portée**/*.test.***/*.spec.*tests/**
Tagsai-codetesting
09 Énoncez explicitement vos hypothèses de concurrence
warningLe code qui conserve un état mutable au niveau du module, qui suppose une instance unique ou qui compte sur un ordre de livraison doit le dire dans un commentaire, juste à côté. Les agents recourent volontiers aux caches et aux compteurs au niveau du module ; cela fonctionne parfaitement sur une machine et casse dès qu'un second réplica démarre.
Avertit : c'est correct aujourd'hui dans bien des déploiements — c'est le commentaire qui rend la chose relisible.
Portéetout le repo
Tagsai-codeconcurrency
10 Les commentaires disent pourquoi, et restent fidèles au code
infoUn commentaire ajouté à côté du code explique pourquoi le code est ainsi ; il ne doit ni contredire la ligne qu'il accompagne, ni raconter ce que cette ligne dit déjà. Le code généré commente par narration, et un commentaire qui décrit une version antérieure de la logique reste cru bien plus longtemps qu'un code périmé — personne ne relit un commentaire avec méfiance.
Indicatif : un défaut de lisibilité qui ne coûte que plus tard — mais c'est lui qui fera se tromper le prochain lecteur, et le prochain agent.
Portéetout le repo
Tagsai-codecommentsmaintainability
Avant de tout importer
La sévérité est le levier qui décide si l'équipe garde la gate activée. Seul error bloque un merge — importez d'abord ces règles en warning, regardez ce qui se déclenche réellement sur quelques semaines de vraies pull requests, et promouvez celles qui l'ont mérité. Et réécrivez les globs de portée : les chemins ci-dessus sont des exemples, et une règle ne s'applique qu'aux fichiers correspondant à ses globs.
Les règles entrent dans Normik une par une — via le formulaire du playbook, ou en laissant un agent de code les proposer par MCP à partir d'un repo existant. Il n'y a pas d'import markdown en masse : le bouton de copie ci-dessus sert à votre AGENTS.md, à une PR où l'équipe débat de la liste, et à garder les règles sous les yeux pendant que vous saisissez celles que vous avez retenues.
Chaque règle ici est jugée comme Normik la juge : sur les lignes que la pull request ajoute. Rien dans ce playbook ne dépend de la description de la PR, d'un fichier que le diff ne touche pas, ni de l'historique d'un fichier — ce sont de vrais standards de revue, mais une gate qui n'en voit pas la preuve ne pourrait que rester muette ou deviner.
L'anatomie d'une règle, le comportement des sévérités et des globs, le versionnage et l'export AGENTS.md sont détaillés dans la documentation du playbook.