Une image servie en production, absente du dépôt. Personne ne l'a signalée, aucune erreur n'est apparue, et le prochain déploiement aurait remis l'ancienne version sans prévenir. C'est la forme la plus discrète de la dette technique.
1. Le constat de départ
Un service sert de petites images : quatre-vingt-dix-huit octets de configuration, quarante-deux entrées, une réponse par identifiant. Rien de complexe. Le service répond, les images s'affichent, l'affaire tourne depuis des semaines.
Puis un jour, quelqu'un remarque que l'image affichée n'est pas la bonne. Pas cassée : ancienne. Le service renvoie un visuel qui ne correspond plus au fichier présent dans le dépôt.
Comparaison des octets :
- dans le dépôt : 3 380 octets, une empreinte SHA-256 donnée ;
- servi par le service en production : 2 899 octets, une autre empreinte.
Deux tailles, deux empreintes, une seule entrée concernée sur quarante-deux. Le reste est identique.
2. Comment on arrive là
L'explication est banale, et c'est ce qui la rend dangereuse.
À un moment, une image a été mise à jour directement sur le service en production, hors du dépôt. Un geste rapide, souvent pour répondre à une demande immédiate : « la photo ne s'affiche pas, change-la ». Le dépôt, lui, a gardé l'ancienne version.
Dès lors, deux sources de vérité coexistent :
- ce que la production sert, et que les utilisateurs voient ;
- ce que le dépôt contient, et que le prochain déploiement écrasera.
Tant qu'aucun déploiement n'a lieu, la divergence est invisible. Le jour où un déploiement passe — pour une autre raison, six semaines plus tard — l'ancienne image revient sans erreur, sans alerte, sans que personne ne le demande.
C'est le pire scénario possible : une régression silencieuse, provoquée par une action de maintenance normale.
3. Pourquoi le dépôt n'est pas la vérité par défaut
Nous vivons avec une conviction confortable : le dépôt est la source de vérité, la production n'est qu'un reflet.
Cette conviction n'est vraie que si le reflet est vérifié. Un dépôt qui n'a jamais été comparé à ce qui est réellement servi est un souhait, pas une source de vérité. Et le service, lui, n'a aucun moyen de savoir qu'il diverge : il n'est pas indexé par version, il sert des octets, et rien ne compare.
Trois conditions rendent la dérive probable :
- un déploiement manuel possible, en contournant le dépôt ;
- aucune empreinte publiée, donc aucune comparaison possible ;
- aucun contrôle automatique entre les deux états.
Réunissez-les, et vous obtenez une divergence qui survit des semaines, jusqu'à ce qu'un humain remarque... une image qui n'est pas la bonne.
4. Le correctif, dans le bon ordre
La tentation est de « corriger » le dépôt en y remettant ce qu'on croit être la bonne image. Mauvaise direction : on ne sait pas ce qui est bon, on sait seulement que deux états diffèrent.
L'ordre retenu a été l'inverse, et il mérite d'être retenu :
- Relever l'état réellement servi : les octets, pas la description. Taille, empreinte, format, dimensions.
- Comparer l'ensemble, pas seulement l'entrée suspecte : quarante-deux clés comparées, une seule divergence. C'est ce qui évite de « corriger » des choses qui n'étaient pas cassées.
- Aligner le dépôt sur les octets servis, en modifiant une seule ligne — l'entrée concernée, sans toucher aux quarante et une autres.
- Ajouter un contrôle automatique : un script qui interroge le service, calcule l'empreinte de chaque réponse, compare avec le dépôt, et sort en erreur au premier écart.
- Documenter la règle : le dépôt est la seule vérité durable ; toute publication hors dépôt sera détectée, donc inutile.
Le correctif a coûté une ligne. Le contrôle automatique en a coûté cinquante, et il vaut plus que la correction.
5. Le contrôle doit être testé contre lui-même
Un contrôle anti-dérive qui n'a jamais échoué est un contrôle dont on ne sait rien. Nous l'avons donc éprouvé à l'envers : une copie volontairement altérée du fichier, et le script doit signaler exactement un écart et sortir en erreur.
Résultat : un écart détecté, code de sortie non nul. Le contrôle n'est pas décoratif.
Trois détails qui font la différence entre un contrôle utile et un contrôle de façade :
- comparer des octets, pas des noms : deux fichiers de même nom peuvent différer, deux fichiers différents peuvent être identiques ;
- limiter le temps d'attente par requête, sinon un service lent bloque la vérification ;
- nommer ce qui est comparé : « quarante-deux clés comparées, une divergence » vaut mieux qu'un « OK » global.
6. Ce que ça dit de la production
Une ressource n'existe durablement que si ses octets sont dans le dépôt. Tout le reste est un état temporaire, maintenu par la mémoire des personnes et la chance.
Cela vaut pour une image, mais aussi pour :
- un texte de configuration modifié à la main sur un serveur ;
- une variable d'environnement ajoutée dans une console ;
- une règle de routage créée dans une interface ;
- une page publiée directement dans un outil d'édition.
Chacune de ces actions produit le même motif : une production qui en sait plus que le dépôt, et un prochain déploiement qui appauvrit la production.
7. Ce que ça change
Nous avons ajouté trois habitudes :
- toute publication passe par le dépôt, y compris pour une urgence — la voie directe existe, mais elle doit être suivie d'un alignement dans l'heure ;
- chaque ressource servie porte une empreinte, et un contrôle compare dépôt et production ;
- un déploiement vérifie l'état d'arrivée, pas seulement le succès de l'opération.
Le dernier point est le plus important. Un déploiement réussi n'est pas un déploiement correct : l'ancien fichier est revenu « avec succès », sans erreur, et c'est précisément ce qui aurait dû alerter.
À retenir. Une ressource qui n'est servie que par un serveur n'existe pas durablement. Comparez les octets, pas les intentions : empreinte dans le dépôt, contrôle automatique, et test du contrôle contre lui-même.