


Garder une grande base de code modulaire lisible et modifiable sans rien casser
À utiliser quand une IA travaille sur une grande base de code à nombreux composants. Donne des règles sur le style de code, la taille des fichiers et des changements, la revue de code, les tests, les noms d'API et les builds, pour des changements petits, lisibles et sans casse ailleurs.
Pour utiliser ces règles d'IA
## Éviter les arguments true/false nus pour que chaque appel se comprenne seul
Privilégier la clarté au point d'appel plutôt que l'ingéniosité.
- Insérer directement les variables dans les emplacements de formatage de chaînes plutôt que de les passer positionnellement.
- Préférer les références de méthode aux fermetures (closures) triviales lorsque le langage le permet.
- Éviter les arguments positionnels opaques — booléens nus, null/none, ou littéraux numériques — qui obligent le lecteur à deviner leur signification (par ex. `foo(false)`). Préférer les énumérations, les méthodes nommées, les newtypes, ou d'autres formes d'API auto-documentées.
- Lorsqu'une forme auto-documentée est impossible et qu'un littéral positionnel doit être conservé, l'annoter avec un commentaire en ligne `/*param_name*/` qui correspond exactement au nom du paramètre de la fonction appelée. Ne pas annoter les littéraux de chaîne/caractère, sauf si le commentaire apporte une réelle clarté.
- Rendre les branchements exhaustifs (pas de branche générique fourre-tout) afin que les nouveaux cas ajoutés soient détectés à la compilation.
- Doter les nouvelles abstractions (traits/interfaces) de commentaires de documentation expliquant leur rôle et la manière dont les implémenteurs doivent les utiliser.
- Respecter les conventions locales au fichier. Ne pas faire osciller le code entre des formes équivalentes sans gain clair de lisibilité ou fonctionnel, et ne pas ajouter d'annotations de type dans le seul but de satisfaire un raccourci.
- Ne pas créer de petites fonctions utilitaires qui ne sont référencées qu'une seule fois.
## Garder fichiers et changements petits au lieu de gonfler le composant central
Garder les unités petites afin que des changements sans rapport cessent d'entrer en collision.
### Taille des modules
- Préférer l'ajout d'un nouveau module plutôt que de faire grossir un module existant. Viser des modules de moins d'environ 500 lignes de code hors tests ; dès qu'un fichier approche ~800 lignes, placer les nouvelles fonctionnalités dans un nouveau module, sauf raison forte et documentée de ne pas le faire.
- Appliquer cela le plus strictement aux fichiers d'orchestration centraux à fort trafic qui attirent déjà des modifications sans rapport ; garder ces fichiers concentrés sur l'orchestration plutôt que de les laisser accumuler des fonctions utilitaires autonomes.
- Lors de l'extraction de code depuis un module volumineux, déplacer ses tests ainsi que la documentation de type/module avec la nouvelle implémentation, afin que les invariants restent proches du code qui les possède.
### Résister au gonflement du plus gros composant
- Le composant le plus volumineux ou le plus central constitue la voie de moindre résistance pour le nouveau code, ce qui explique précisément pourquoi il continue de grossir. Résister à la tentation d'y ajouter du code. Se demander d'abord si un composant existant serait un meilleur emplacement, ou s'il est temps d'en introduire un nouveau — en refactorisant si nécessaire. En revue, s'opposer aux changements qui agrandiraient inutilement le composant central.
### Taille des changements
- Sauf si un changement est mécanique, garder le nombre total de lignes modifiées sous ~800 ; pour une logique complexe, sous ~500.
- Si un changement est plus important, le diviser en étapes revuables et livrer d'abord la plus petite étape cohérente, en basant ce découpage sur le diff réel, les dépendances et les points d'appel affectés.
## En revue de code, repérer les changements incompatibles et le contexte qui grossit sans limite
Effectuer la revue en ciblant les risques coûteux à détecter plus tard.
### Garder la surface publique réduite
Garder l'API publique/exportée de chaque composant aussi réduite que possible. Préférer des éléments internes privés avec une surface publique explicitement exportée, et éviter de multiplier les fonctions utilitaires réservées aux tests dans le code de production.
### Protéger le contexte du modèle/de l'inférence
Lorsqu'un système maintient un contexte envoyé à un modèle à chaque requête d'inférence, le protéger :
- Construire le contexte de manière incrémentale ; ne jamais réécrire l'historique.
- Éviter les changements fréquents de contexte qui invalident la mise en cache.
- Tout élément injecté doit avoir une taille bornée et un plafond strict — aucun élément non borné, et aucun élément individuel ne doit dépasser un plafond fixe de tokens.
- Signaler tout nouvel élément susceptible de franchir individuellement un seuil de taille important, pour une revue manuelle supplémentaire.
- Faire transiter tous les fragments injectés par une abstraction typée unique plutôt que par une insertion ad hoc.
### Détecter les changements incompatibles
Rechercher activement les changements incompatibles dans les surfaces d'intégration externes : API publiques, charges utiles d'événements (y compris expérimentales), paramètres de ligne de commande, chargement de la configuration, et la capacité à reprendre des sessions existantes ou un état persistant.
## Vérifier le vrai comportement avec des tests d'intégration et de snapshot
Tester le comportement, garder les tests honnêtes, et les tenir à l'écart du code de production.
- Pour les changements de comportement central, préférer des tests d'intégration qui sollicitent une instance réelle plutôt que des tests unitaires étroits. Tout changement à ce comportement DOIT ajouter un test d'intégration ; énumérer les comportements qui nécessitent une couverture.
- Placer les tests unitaires dans un fichier de test dédié et adjacent plutôt qu'en ligne dans le fichier d'implémentation, et lui donner un nom descriptif. Ne pas ajouter de fonctions réservées aux tests dans les modules de production, et ne pas réécrire les modules de test en ligne existants dans le seul but de suivre cette convention.
- Tout changement affectant un rendu visible par l'utilisateur doit inclure une couverture par snapshot — ajouter ou mettre à jour le snapshot et examiner le diff dans le cadre du changement, afin que l'impact sur l'interface reste visible.
- Effectuer les assertions sur des objets entiers avec une égalité profonde plutôt que de comparer les champs un par un, en utilisant une bibliothèque d'assertions qui produit des diffs clairs.
- Ne pas modifier l'état global du processus (par exemple les variables d'environnement) à l'intérieur des tests ; injecter les dépendances et les indicateurs depuis l'appelant.
- Ne pas tester les constantes définies statiquement, et ne pas ajouter de tests négatifs pour une logique qui a été supprimée.
- Vérifier l'existence d'utilitaires de test avant d'écrire une nouvelle configuration, afin que les tests restent épurés et lisibles.
## Garder les mêmes noms et formats de champs dans toute l'API
Lors de l'évolution d'une API réseau ou multi-langage, la cohérence à la frontière du protocole (« wire boundary ») évite les ruptures silencieuses.
- Concentrer le développement actif sur la version courante de l'API ; ne pas ajouter de nouvelle surface aux versions dépréciées.
- Nommer les charges utiles de manière cohérente selon leur rôle (un suffixe pour les paramètres de requête, un pour les réponses, un pour les notifications). Exposer les méthodes sous la forme d'un nom de ressource suivi d'un nom d'action, avec une convention singulier/pluriel cohérente pour la ressource.
- Fixer une seule convention de casse pour les champs et les valeurs d'énumération au niveau du protocole, et l'appliquer partout, en ne dérogeant que pour des besoins explicites de compatibilité. Garder alignées les annotations du sérialiseur et de la génération de types afin que les deux côtés soient en accord ; lorsque l'un utilise un renommage explicite, l'autre doit correspondre.
- Pour les unions discriminées, utiliser un marquage (tagging) explicite dans chaque sérialiseur.
- Préférer des identifiants en simple chaîne de caractères à la frontière, et les convertir en interne. Utiliser des horodatages entiers avec une convention de nommage `*_at` cohérente.
- Pour les points de terminaison de liste, mettre en œuvre par défaut une pagination par curseur (un curseur et une limite en entrée ; un tableau de données et un curseur suivant en sortie).
- Protéger toute surface expérimentale derrière un marqueur explicite, et régénérer la documentation, les exemples et les fixtures de schéma chaque fois que la forme de l'API change.
## Lancer d'abord le formateur et des tests ciblés, sans toucher aux garde-fous du sandbox
Respecter la chaîne d'outils et les contraintes déjà en place.
### Garde-fous d'environnement et de sandbox
- Ne jamais ajouter ni modifier du code qui gère des indicateurs de sandbox ou de capacité d'environnement sans intention délibérée. Ces garde-fous existent parce que le code et les tests ont été conçus autour de limites d'exécution spécifiques — par exemple, des tests qui s'interrompent prématurément lorsqu'une capacité telle que l'accès réseau est indisponible. Supprimer ou modifier silencieusement un garde-fou brise ces hypothèses.
### Hygiène de build et de chaîne d'outils
- Exécuter automatiquement le formateur une fois les modifications de code terminées ; ne pas demander d'approbation pour formater.
- Exécuter d'abord les tests pertinents les plus ciblés, limités au composant modifié. N'élargir à la suite complète que lorsque du code partagé ou central a été modifié, et confirmer avant de lancer de longues exécutions de la suite complète.
- Lorsque vous modifiez des entrées qui alimentent des artefacts générés — schémas, fichiers de verrouillage (lockfiles), types générés — les régénérer dans le même changement ; les écarts sont vérifiés en CI.
- Si l'outil de build nécessite que les fichiers source soient déclarés pour un accès à la compilation, mettre à jour cette déclaration chaque fois que vous ajoutez de telles lectures.
- Faire preuve de patience avec les commandes de build et de test lentes ; une contention de verrous attendue peut les ralentir. Ne pas les tuer par identifiant de processus.
### Support des plateformes
- Les tests et les fonctionnalités doivent prendre en charge tous les systèmes d'exploitation officiellement supportés, sauf si une fonctionnalité est explicitement spécifique à un système. Lorsque le système permet à des composants de s'exécuter sur différents systèmes d'exploitation, s'assurer que les nouveaux tests couvrent ces configurations multi-plateformes.
