Six bugs sur neuf n'existaient pas
Nous avons mené une révision planifiée de notre base de données de noms. Le plan comportait neuf points de travail, chacun étant un défaut à corriger. Six d'entre eux décrivaient des défauts qui n'existaient pas, ou du travail déjà effectué.
Aucun des six ne provenait d'une mauvaise mesure. Chacun d'eux provenait d'un paragraphe de notre propre documentation.
C'est là le constat, et il est plus dérangeant que l'aveu habituel « nous avons trouvé des bugs dans nos données » — nous en avons déjà écrit un, et ce n'est pas de cela qu'il s'agit ici. Il est question de la classe de défaillance où c'est le ticket qui est le bug : où un mainteneur, agissant raisonnablement, lit une note, y croit, planifie du travail autour d'elle et ne découvre qu'au contact des données qu'il n'y avait rien à faire. Le travail coûte malgré tout ce qu'il aurait coûté. Simplement, il ne produit rien.
Le tableau d'affichage
| Le point, tel que formulé | Ce que les données ont dit une fois enfin interrogées |
|---|---|
| « 33 noms de famille fantômes tirés d'une liste classique — les supprimer » | Zéro. Les 2 707 entrées correspondaient exactement au registre, et chaque poids égalait le décompte du registre à l'unité près |
| « Cinq noms de famille manquent dans la liste vietnamienne » | Tous les cinq présents — aux rangs 42, 46, 55, 59 et 60, les rangs mêmes que le point citait comme preuve |
| « La colonne des poids mélange trois échelles incompatibles ; unifiez-les » | Une seule échelle. Un unique coefficient reconstitué reproduit exactement 1 813 poids sur 1 886 |
| « Ce pays n'a pas de poids de villes » | Il les a tous, 60 sur 60 |
| « Il n'existe pas de registre de fréquences pour ce pays » | Vrai pour les noms de famille, faux pour les prénoms — un office national de statistique les publie année par année depuis 1999 |
| « Charger les poids de villes pour les locales qui en manquent » | Aucun des 14 candidats n'atteint une couverture complète. 563 villes sur 810 ont un chiffre ; 247 n'en ont pas |
Cinq d'entre eux sont des défauts fantômes. Le dernier est d'une autre nature et mérite d'être isolé : la lacune était réelle et c'est la correction proposée qui constituait le défaut. Nous y revenons plus bas, car c'est celui que l'on risque le plus de traiter de travers sous la pression du temps.
Le paragraphe qui énumérait ce qui avait été ajouté
Le cas le plus net, et celui qui se généralise le plus loin.
Une note interne disait, en substance : « Ajouté six noms de famille réels et courants qui manquaient : A (rang 42), B (rang 46), C (#56), D et E (#60–61), F (#66). »
C'est le compte rendu d'un travail achevé. Lu six semaines plus tard par quelqu'un qui n'était pas là, il est indiscernable d'une liste de tâches. Le mot « manquaient » figure bien dans la phrase ; que ce mot décrive un état ayant cessé d'exister du fait de l'action décrite par cette même phrase repose entièrement sur le temps passé d'un seul verbe.
Un point de travail a donc été ouvert : ces noms de famille manquent dans la liste. Et le point citait les rangs — 42, 46, 56, 60 — comme preuve à l'appui.
Ces rangs étaient corrects. Ils étaient corrects parce que les entrées s'y trouvaient, précisément à ces rangs — c'est bien pour cela que la note pouvait les citer. La preuve du défaut et le défaut lui-même avaient été recopiés du même paragraphe. Le contrôle du fichier a pris moins d'une minute et a renvoyé les cinq entrées aux rangs 42, 46, 55, 59 et 60 — conformes à la note, à l'écart près auquel on peut s'attendre après que la liste a été approfondie entre-temps.
La leçon n'est pas « écrivez plus clairement ». La note était claire. La leçon, c'est qu'une phrase décrivant un changement est par défaut non datée, et qu'un changement non daté se lit comme un état. Added A, B, C et A, B, C are missing sont la même phrase pour un lecteur qui ignore quand elle a été écrite.
L'événement lu comme un état
Même forme, rayon d'impact plus large.
Une note consignait que 33 noms de famille archaïques sans aucun porteur vivant avaient été retirés d'une liste, ayant été importés d'un texte du XIe siècle plutôt que d'une population. Vrai, daté et correct.
Quatre jours plus tard, un point du plan indiquait : supprimer 33 noms de famille archaïques sans aucun porteur vivant.
Les deux phrases sont vraies à propos de nos données. Elles sont vraies à propos de versions différentes du même fichier, à quatre jours d'intervalle. Et voici ce qui a aggravé les choses au lieu de les améliorer : entre-temps, le fichier avait été reconstruit à partir d'un registre, si bien que la version courante était un sous-ensemble strict d'un registre nom par nom, où chaque poids égalait un décompte du registre. Il n'y avait pas simplement rien à supprimer — il n'y avait, structurellement, rien qui pût être supprimé, puisque derrière chaque ligne se tenait un compteur.
La mesure n'a demandé qu'un script : 2 707 entrées, toutes présentes dans le registre en comparaison octet par octet, zéro écart de poids, couverture 99,98 %.
Le nettoyage tentant, à ce stade, consiste à biffer l'ancienne note en la tenant pour une erreur. Ce serait une deuxième erreur. L'ancienne note n'est pas fausse — elle décrit fidèlement un événement, et nous avons publié sur cet événement un article qui n'appelle aucune correction. Ce qui manquait à la note, c'était une portée : quel fichier, à quelle date. Deux affirmations exactes portant sur deux versions de la même chose, placées dans deux documents sans date, se présentent comme une contradiction ; et une contradiction dans la documentation est un point de travail qui attend d'être rédigé par la prochaine personne qui la remarquera.
Le mécanisme qui n'a jamais été consigné
Un troisième point affirmait qu'une colonne de poids mêlait trois échelles incompatibles et devait être ramenée à une seule.
Il y avait bien eu trois sources. Il n'y avait qu'une échelle : à un moment antérieur, elles avaient été harmonisées en ajustant l'ensemble à un coefficient unique, et l'étape d'ajustement n'avait jamais été documentée. Reconstituer le coefficient à partir des données elles-mêmes a pris un après-midi ; une fois reconstitué, il reproduit exactement 1 813 poids sur 1 886, à l'unité près.
Vient ensuite la partie intéressante. Nous avons mesuré ce que l'harmonisation proposée aurait effectivement changé :
| Indicateur après la « correction » proposée | Résultat |
|---|---|
| Décalage de rang médian | 0 |
| Décalage de rang au 90e centile | 0 |
| Plus grand décalage de rang isolé | 34 |
| Variation de la part du top 10 | 0,02 pp |
| Entrées dont le poids change | 73 sur 2 222 |
Et du côté des coûts : ces 73 entrées étaient les seules dont les valeurs provenaient d'une source indépendante. Les réécrire aurait rendu le fichier parfaitement cohérent avec lui-même et définitivement invérifiable — le seul ensemble permettant de contrôler un jour le coefficient aurait été écrasé par ce coefficient.
Un changement dont le bénéfice mesuré est nul et le coût non nul n'est pas neutre. C'est une régression. Il ne paraît neutre que parce que « normaliser les échelles » est une phrase qui sonne comme de l'hygiène.
La vraie lacune avec la mauvaise correction
Le sixième point est celui qui mérite le plus d'attention, car tout y était raisonnable sauf la conclusion.
Vingt locales avaient des listes de villes sans poids de population : les villes étaient donc tirées uniformément — une petite ville aussi probable que la capitale. C'est un défaut authentique, honnêtement documenté, avec des sources sur le disque pour une partie des locales. Le point disait : chargez les poids dont nous disposons.
Une fois mesurées, les sources couvraient 563 villes sur 810 réparties sur 14 locales — 69,5 %. Pas une seule locale n'atteignait 100 %. La meilleure plafonnait à 90,4 %, avec cinq villes manquantes.
L'instinct souffle que 69,5 % vaut mieux que 0 %. C'est faux, et la raison mérite d'être formulée avec précision : une liste non pondérée tire uniformément, ce qui est faux mais sans biais d'une entrée à l'autre. Une liste partiellement pondérée rend de façon déterministe les entrées pondérées plus probables et les entrées non pondérées moins probables — or les entrées dépourvues de chiffre de population ne forment pas un échantillon aléatoire. Ce sont celles aux noms malcommodes, aux limites contestées ou aux appariements ambigus. Le chargement partiel défavorise donc systématiquement les entrées qui étaient précisément les plus difficiles à résoudre, et il le fait tout en paraissant plus précis qu'auparavant.
Le résultat correct consistait à ne rien charger et à consigner les 247 lacunes sous forme de manifeste, afin que la prochaine tentative parte d'une liste et non d'une redécouverte. « Quelques données valent mieux que pas de données » est faux dès lors que ce qui manque est corrélé à ce que l'on mesure — ce qui, pour des données géographiques et des données de noms, est presque toujours le cas.
Pourquoi la cause est la documentation et non les données
Six points, six pays différents, six types d'affirmation différents, une origine commune : une phrase de nos propres notes, qui était vraie au moment où elle a été écrite.
C'est structurel, et non une défaillance ponctuelle de la rigueur. Une mesure est datée par construction — vous l'avez exécutée, un jour donné, sur un fichier donné, et si vous la relancez, vous obtenez la réponse d'aujourd'hui. La prose n'a rien de tel. Un paragraphe ne sait pas quand il a été écrit, ne sait pas à quoi il se rapportait, et ne se dégrade pas visiblement. La documentation ne vieillit pas bruyamment. Elle vieillit en silence, puis engendre du travail.
Nous disposons d'une mesure chiffrée de ce rythme. Au cours de cette même révision, un décompte figurant dans notre documentation — combien de locales portaient un certain type de jeu de données — est passé de 7 → 9 → 10 en une seule journée, à mesure que des travaux menés en parallèle aboutissaient. Neuf documents portaient ce décompte à treize endroits. Et le rapport que nous avons rédigé pour corriger les treize était déjà obsolète vingt minutes après avoir été écrit, parce qu'un autre traitement s'était achevé entre-temps et avait porté le nombre à 10.
Ce n'est pas une anecdote sur l'ironie du sort. C'est la contrainte elle-même. C'est la rigueur qui a produit la première version ; « soyez plus rigoureux » ne peut donc pas être le remède.
Le remède : un nombre sans recalcul est une mine terrestre
La règle que nous appliquons désormais, et la seule de cet exercice qui survive au contact d'un projet réel :
N'écrivez jamais un décompte en prose sans écrire, juste à côté, comment le recalculer.
Un nombre nu énonce un fait sur un instant. Un nombre assorti d'un mode de recalcul énonce un fait sur le présent. La différence coûte une ligne et élimine toute une classe de défaillances — car le lecteur suivant n'a pas à décider s'il fait confiance au nombre ; il peut passer dix secondes à le vérifier.
La seconde règle porte sur le temps verbal. Toute phrase factuelle d'une documentation de projet devrait pouvoir être classée, sans aucun contexte environnant, dans exactement une de ces catégories :
| Nature | Doit porter | Exemple du mode de défaillance |
|---|---|---|
| Mesure | la date, et par rapport à quoi elle a été faite | « la couverture est de 60 % » — de quoi, quand ? |
| Événement | la date, et la portée à laquelle il s'appliquait | « 33 entrées supprimées » — de quelle version ? |
| Décision | la date, et le raisonnement susceptible de l'inverser | « nous n'utilisons pas la source X » — pourquoi, et qu'est-ce qui changerait cela ? |
| Instruction | un critère d'acceptation | « approfondir la queue » — jusqu'où ? |
Une phrase impossible à classer est un point de travail fantôme qui n'a pas encore été rédigé.
Pourquoi « vérifiez d'abord » est un conseil plus difficile qu'il n'y paraît
Tout le monde approuve le principe « vérifiez la prémisse avant de planifier le travail ». Presque personne ne le fait, et la raison tient à une asymétrie réelle plutôt qu'à la paresse.
Lire un document prend quelques secondes et n'exige rien. Exécuter un contrôle prend des minutes, exige de savoir quoi exécuter et exige d'avoir les données sous la main. L'ordre naturel est donc : lire, former un plan, puis vérifier en cours d'exécution. Cet ordre est exactement l'inverse du bon — car, au moment où l'exécution commence, le plan a été rédigé, inscrit au calendrier, doté en personnel et défendu en réunion. La vérification en cours d'exécution n'annule pas le travail ; elle se contente de découvrir, à grands frais, que ce travail était inutile.
Il existe aussi une raison précise pour laquelle les points fantômes paraissent solides : ils sont précis. « 33 noms de famille fantômes » porte un nombre, et les nombres se lisent comme mesurés. Celui-là avait été mesuré — quatre jours plus tôt, sur un fichier qui n'existait plus sous cette forme. La précision n'est pas une preuve d'actualité, et c'est la façon la plus fiable qu'a une affirmation obsolète de se faire passer pour une affirmation récente.
Notre propre bilan pour cette révision : au moins trois séances de travail complètes sont parties dans des points qu'un balayage des données d'une minute aurait clos. Ce balayage existe désormais et peut être relancé, ce qui constitue le seul résultat durable qu'ait produit l'une quelconque de ces séances.
La liste de contrôle
- Confrontez la prémisse aux données comme première action — avant de planifier, pas pendant l'exécution. Si la prémisse ne peut pas être testée à bas coût, c'est déjà en soi le premier constat.
- N'écrivez jamais un décompte sans le moyen de le recalculer. Un nombre de nos notes a changé deux fois en une journée et figurait à treize endroits.
- Datez chaque phrase factuelle et fixez son temps verbal. « Ajouté X » et « X manque » sont la même phrase en l'absence de date.
- Un relevé de ce qui a été ajouté n'est pas une liste de ce qui manque. Quand une note énumère des éléments, contrôlez s'il s'agit d'un reçu ou d'une demande.
- Séparez « le défaut n'est pas réel » de « la correction n'est pas la bonne ». Les deux se présentent sous la même forme et appellent des réponses différentes ; l'une clôt le point, l'autre le remplace.
- Des corrections partielles peuvent être pires que rien lorsque la partie manquante n'est pas un échantillon aléatoire. Mesurez la couverture avant de charger quoi que ce soit, et préférez une lacune honnête à un remplissage biaisé.
- Corrigez le document dans la même séance que le point fantôme. Sinon la phrase qui l'a engendré reste en place et l'engendre à nouveau — nous avons vu exactement cela se produire, deux fois, avec le même paragraphe.
- Guettez l'unilatéralité. Chacun de ces défauts existait dans la documentation et n'a jamais pu être reproduit sur les données. Un défaut qui n'apparaît jamais que d'un seul côté d'une comparaison est généralement un problème de diagnostic, non un problème de données.
Ce que cela a réellement coûté, et ce que cela a rapporté
Les trois points authentiques représentaient un vrai travail et ont été traités. Les six autres ont été clos par la mesure, et leur clôture a pris au total moins de temps que n'en aurait demandé la mise en œuvre de l'un quelconque d'entre eux.
Le résultat le plus précieux de la révision n'a pas été une modification des données. Il s'est agi de la suppression et de la redatation des phrases qui avaient engendré les faux points — car ces phrases étaient toujours là, toujours vraies-au-moment-où-elles-ont-été-écrites, toujours prêtes à engendrer les six mêmes points pour la prochaine personne qui les lirait attentivement et agirait de bonne foi.
C'est là la forme générale, et elle est dérangeante. Une base de données se dégrade plus lentement que sa documentation. Les données sont contrôlées par des validateurs à chaque build ; la prose qui les entoure n'est contrôlée par personne, vieillit en continu, et c'est elle que tout le monde lit en premier.
Données arrêtées au 2026-07-21
Chaque chiffre de cet article a été recalculé à partir des données le 21 juillet 2026, et non repris des notes ici discutées — ce qui, pour cet article précisément, aurait été une idée exceptionnellement mauvaise. La révision décrite s'est déroulée du 19 au 21 juillet 2026 sur une base de données de noms et d'adresses couvrant 64 locales.
D'où proviennent les chiffres :
- 2 707 entrées, correspondance octet par octet avec le registre, couverture 99,98 % — recalculés par rapport au registre de noms de famille nom par nom publié pour la locale concernée ; ce registre, sa licence et ses particularités sont documentés dans D'où proviennent nos données de noms taïwanaises.
- Cinq noms de famille aux rangs 42, 46, 55, 59, 60 — lus directement dans la liste livrée, 298 entrées.
- 1 813 poids sur 1 886 reproduits par un seul coefficient ; décalage de rang médian 0 ; 73 entrées sur 2 222 concernées — mesuré en redérivant le coefficient à partir des données et en rejouant le changement proposé sans l'écrire.
- 60 poids de villes sur 60 ; 563 sur 810 réparties sur 14 locales ; 247 lacunes — comptés à partir des listes de villes livrées et des sources hors ligne.
- 7 → 9 → 10 en une journée, à 13 endroits répartis sur 9 documents — comptés pendant la révision de la documentation elle-même.
- Le registre de prénoms dont on disait qu'il n'existait pas est publié par l'Istat, l'institut national de statistique italien, et couvre 1999–2024.
L'article complémentaire, qui porte sur huit erreurs de fond d'une autre nature — dénominateurs erronés, vérification circulaire, statistiques zombies —, est Ce que nous avons mal compris à propos des données de noms. La méthode générale pour tester cette classe d'affirmations se trouve dans Comment auditer un jeu de données de fréquences de noms.