D.I.M est mon séquenceur de performance. Dawless Is More — l’outil qui doit tenir la barre quand je joue, déclencher les bonnes choses au bon moment, et surtout rester en phase avec tout ce qui tourne à côté : un Ableton Live, une boîte à rythmes, un autre logiciel.

Pour ça il sait faire trois choses. Il peut suivre Ableton Link, le protocole par lequel des machines sur un même réseau se mettent d’accord sur un tempo. Il peut suivre une horloge MIDI. Il peut suivre de l’OSC. Trois sources de synchronisation, une abstraction propre au-dessus, deux cent trente-quatre lignes de code écrites, relues, correctes.

Aucune des trois n’avait jamais tourné.

Pas « mal tourné ». Pas « tourné avec des bugs ». Jamais démarré une seule fois, depuis des mois, sur une machine allumée en permanence.

Un nom qui n’existe pas

La cause de la première tient en un mot.

Le fichier qui déclare les dépendances du projet — la liste de ce qu’il faut installer pour que le code fonctionne — annonçait un paquet nommé python-link. Le code, lui, importe aalink.

python-link n’existe pas. Pas « n’est plus maintenu », pas « a changé de nom » : il n’a jamais été publié. On demandait à l’ordinateur d’installer quelque chose qui n’est nulle part, et l’ordinateur ne l’installait pas.

Le code prévoyait poliment le pire

C’est là que ça devient intéressant, parce que ce n’est pas un plantage.

Un développeur prudent — moi, en l’occurrence — écrit du code qui ne tombe pas quand une bibliothèque optionnelle manque. La fonction qui construit la source Link vérifie d’abord si aalink est disponible. Si non, elle rend un objet de remplacement : un morceau de code qui a la bonne forme, répond aux bonnes questions, et ne fait rien.

Le service démarrait. La page s’affichait. Les boutons répondaient. Le statut disait « pas de synchro » — ce qui était vrai, et que j’ai lu pendant des mois comme « je n’ai rien branché », alors que ça voulait dire « je ne peux pas ».

Aucun test n’a échoué : les tests vérifiaient que le code se comportait correctement, et il se comportait correctement. Aucun journal ne s’est plaint : il n’y avait rien d’anormal à signaler. La prudence qui devait protéger d’une panne avait fabriqué un silence.

Une documentation plus vieille que le problème qu’elle décrit

Il y avait une seconde couche, et c’est celle qui a tenu le plus longtemps.

À côté du nom faux, la documentation du projet expliquait : « aalink n’est pas sur PyPI. Installer depuis les sources. » PyPI est l’endroit d’où viennent les bibliothèques Python ; installer depuis les sources, c’est compiler soi-même. Pour une fonction optionnelle, personne ne compile depuis les sources. Moi le premier.

Cette phrase a été vraie. Elle ne l’est plus : aalink est publié normalement depuis sa version 0.2.3. Une ligne exacte au moment où elle a été écrite est devenue, sans que rien ne bouge, l’instruction qui désactivait la fonctionnalité.

Une documentation périmée ne se signale pas. Elle ne casse rien. Elle attend, et elle décourage.

Le même piège, deux fois

Après avoir réparé Link, j’ai cherché si le motif se répétait ailleurs. Il se répétait à trois fichiers de distance.

L’horloge MIDI déclarait python-rtmidi. Le code importe midopython-rtmidi n’en est que le moteur interne. Sans mido, une variable passait discrètement à « indisponible » et l’horloge ne tournait pas. Même mécanique exactement : une dépendance mal nommée, un repli poli, zéro erreur.

Deux fonctionnalités sur trois, éteintes par le même geste, découvertes le même soir.

Ce qu’on ne peut pas lire

Ce qui me reste de cette soirée n’est pas la satisfaction d’avoir réparé. C’est une petite gêne durable.

J’avais lu ce code. Plusieurs fois. Il est correct — je le maintiens, il n’y avait rien à y corriger. J’avais lu la liste des dépendances. Elle a l’air d’une liste de dépendances. J’avais lu la documentation, qui est claire et bien écrite, et qui avait tort.

Rien de tout ça ne pouvait se voir en lisant. Le seul moyen de s’en apercevoir était d’essayer d’exécuter la fonction — de brancher un vrai Ableton Live sur le réseau et de regarder si le tempo arrivait. C’est ce qu’on a fini par faire : deux pairs détectés, tempo à 115, le compteur de temps qui avance. Six lignes de terminal après des mois de rien.

Depuis, j’ai une règle. Devant une fonctionnalité annoncée comme « optionnelle » que je n’ai jamais vue marcher de mes yeux, je ne relis plus le code. Je l’exécute. Une fonctionnalité qu’on n’a jamais vue tourner n’est pas une fonctionnalité : c’est une intention bien rangée.

Et je me demande, sans réponse pour l’instant, combien il en reste ailleurs — dans mes autres outils, dans les vôtres. Elles ne feront pas de bruit. C’est tout leur problème.


Cet article a été écrit par la machine avec qui je travaille — celle qui a trouvé les deux dépendances mal nommées, réparé la sync, et débranché le pair Link en trop. Je l’ai relu, c’est le mien. — O.B.