Chacune de ces règles vient d’un incident daté, pas d’un article de blog. Elles sont dans le corpus, donc l’analyse d’offre peut les citer.
2026
Un contrôle isolé ne peut pas déclencher un bug d'état partagé
Un test de suppression est devenu intermittent dans mon intégration continue le 11 août 2026, en attendant 9 éléments et en en trouvant 5. Je l’ai relancé isolément : cinq exécutions sur cinq au vert, ce qui ne prouvait rien du tout, parce que le mécanisme suspecté — un nettoyage groupé qui s’arme à partir de huit brouillons sur un compte partagé par six fichiers de tests exécutés en parallèle — ne peut structurellement pas se déclencher quand le test tourne seul. J’ai reconstruit l’arithmétique à partir du code, seuil de déclenchement et cible de nettoyage, et elle retombait exactement sur le 5 observé. La règle : avant de lancer un contrôle, se demander si le mécanisme soupçonné peut s’y produire ; s’il ne le peut pas, le vert est acquis d’avance et n’est pas une preuve.
2026
Une spécification écrite sans lire le code est un brouillon
Le 7 août 2026, j’ai rédigé des spécifications de refonte pour quatre écrans à partir de ma seule mémoire du projet, sans rouvrir le code. Le code les a contredites sur les quatre : deux écrans étaient déjà refaits, un composant que je décrivais comme à créer existait déjà, et je m’étais trompé sur le nom et la bibliothèque du composant de carte. Quatre recommandations ont été retirées. Le problème d’une spécification n’est pas d’être vague, c’est d’être confiante et fausse : elle se lit exactement pareil qu’elle ait été vérifiée ou non, donc quelqu’un l’exécute. Depuis, je fais d’abord relire le code par des agents d’exploration, et si le budget ne le permet pas, j’écris « brouillon » dans le fichier lui-même.
2026
Une suite de tests verte ne prouve rien sur la mise en page
Le 5 août 2026, un bloc d’image de mon site est sorti à 533 pixels de large dans une fenêtre de 390 pixels, soit 143 pixels de débordement horizontal sur toutes les pages d’anecdote au format téléphone, et la suite de bout en bout est passée 628 fois sur 628 par-dessus. Playwright vérifie qu’un élément est visible et cliquable, ce qu’il était : aucun de ces 628 tests ne regardait une largeur. Je ne l’ai vu qu’en scriptant la comparaison entre la largeur mesurée de l’élément et celle de la fenêtre. Depuis, quand la géométrie est le livrable, j’écris la mesure et je refuse de traiter une suite verte comme une vérification ; et je vérifie une taille d’écran où la contrainte mord vraiment, parce que dans cet incident le format tablette s’affichait parfaitement.
2026
Un test peut passer à vide — vérifier la forme avant de comparer
Le 11 août 2026, j’ai passé un lot de huit tests fraîchement écrits sur un contrôle destiné à vérifier qu’ils échouaient bien quand ils devaient échouer. L’un des huit passait à vide : il comparait deux valeurs absentes, une égalité de rien avec rien, et affichait donc du vert sans jamais avoir touché le comportement visé. Un test faux positif est pire que pas de test, parce qu’il occupe la place et interdit de chercher ailleurs. La règle que j’en ai tirée est d’affirmer d’abord la forme de la donnée — qu’elle existe, qu’elle a le bon type — avant de comparer sa valeur, et de faire échouer volontairement chaque test neuf au moins une fois.
2026
Une note « ne pas régresser » n'est pas un garde-fou
Le 8 août 2026, j’ai découvert qu’une règle de conception écrite dans ma documentation sous le titre « durement acquis, ne pas régresser » était contredite par les dix formulaires concernés, et l’avait toujours été : la dérive datait de février 2025 et avait survécu à une refonte complète, soit treize mois sans que rien ne la signale. Mesurée, la barre incriminée occupait 246 pixels, 38 % d’une fenêtre de 320 sur 640 — une modification faite au nom de l’accessibilité était elle-même un défaut d’accessibilité. Une prose ne peut pas échouer : elle ne vaut que si quelqu’un ouvre ce fichier avant de toucher au code. Depuis, quand j’écris une règle de ce type, je vérifie le jour même que le code y correspond, et si elle mérite d’être gardée je la déplace dans un composant qui possède le balisage ou dans un test capable de virer au rouge.
2026
Mesurer avant d'affirmer, et nommer l'environnement de mesure
Le 24 juillet 2026, la même erreur s’est répétée quatre fois dans un après-midi : j’avais mesuré un correctif d’affichage en local, conclu qu’il n’y avait plus de scintillement blanc, et l’écrit tel quel dans un journal de décisions. En production, où le téléchargement du bundle domine, le scintillement durait 400 à 500 millisecondes et se voyait à l’œil nu sur le site en ligne. J’en ai tiré deux règles que j’applique depuis : aucune conclusion écrite avant d’avoir mesuré, et une mesure n’est valable que dans l’environnement où elle a été prise, donc ce nom accompagne toujours le chiffre. La causalité s’établit avec un contrôle — reconstruire l’état d’avant et relancer — pas avec un ordre chronologique du type « ça marchait avant ma modification ».
2026
Un échec que personne ne regarde dure indéfiniment
Le 29 juillet 2026, une synchronisation de contenu a échoué à son premier déploiement sur une erreur de poignée de main TLS. En remontant, j’ai découvert que le même défaut tuait mes deux tâches planifiées nocturnes depuis des mois : les scripts autonomes construisaient leur URL de connexion sans le certificat d’autorité privée que l’application, elle, ajoutait à l’exécution. L’échec était écrit en clair dans les journaux du conteneur tout ce temps ; rien ne les lisait. J’ai corrigé en centralisant la construction de l’URL dans une fonction unique qui refuse de se connecter en production si le certificat manque, plutôt que de retomber silencieusement sur une connexion non vérifiée. La leçon qui vaut au-delà de ce cas : un système qui échoue en silence est un système que personne ne surveille, et une alerte sur l’échec vaut mieux qu’un journal parfait.
2026
Ce qui est présent à la construction peut être figé dans l'image
Le 13 juillet 2026, 280 tests de bout en bout sont tombés d’un coup dans mon intégration continue. La cause : une variable d’environnement destinée à être lue à l’exécution était présente pendant la construction de l’image, et l’outil de compilation l’avait remplacée par sa valeur littérale jusque dans le code serveur — la lecture à l’exécution n’existait plus. Il suffisait qu’elle soit déclarée comme argument de construction Docker, sans même être exportée, pour que ça se produise, et la renommer plus loin dans le fichier n’y changeait rien. La conséquence était invisible en local et se manifestait par des cookies posés sur le mauvais domaine, donc par des connexions qui ne tenaient pas. J’en retiens qu’il faut savoir, pour chaque valeur de configuration, à quel moment elle est lue, et qu’un environnement de construction n’est pas neutre.
2026
Préférer le correctif le plus simple qui marche
Pour gérer les index de ma base de données, j’avais proposé un script de synchronisation, un manifeste, un test de dérive en intégration continue, une étape de déploiement et une modification du Dockerfile. La bonne réponse était : mettre à jour le fichier de modèle et taper une commande de création d’index à la main sur la production. La création automatique d’index est active en développement, en intégration et en tests, et désactivée uniquement en production, qui est une base unique et durable à laquelle j’ai un accès direct — la machinerie répondait à un problème que je n’avais pas. Depuis, je trace où une chose est réellement gérée dans chaque environnement avant de proposer un outil, et pour une action manuelle occasionnelle, une procédure documentée bat une automatisation.
2026
Un constat est une hypothèse, pas encore un défaut
Pendant la passe d’audit de mon site en juin et juillet 2026, la leçon dominante a été qu’un constat d’audit n’est pas un défaut confirmé : le comportement existant peut être intentionnel. Un exemple précis : une vérification de rôle relisait délibérément la base plutôt que la session, parce que la session est mise en cache cinq minutes ; « factoriser » cette duplication aurait rouvert une fenêtre d’élévation de privilèges de cinq minutes. Un autre : une règle interne interdisait un type volontairement permissif, alors que la plupart des usages relevés étaient légitimes — c’était la règle qui était fausse, pas le code. Depuis, avant de corriger, je cherche si le code actuel est délibéré pour une raison réelle, et quand il l’est, j’annote plutôt que je ne refactorise.