Jeudi matin, la radio s’est tue. Pas coupée : muette. La musique enchaînait, le flux sortait, la sonde de santé répondait {"status":"on-air"} — vert, franc, rassurant. Seulement plus personne ne parlait entre les morceaux.
Ce billet raconte les deux pannes de cette semaine, et surtout ce qu’il a fallu faire pour rendre les correctifs au projet dont Subwave est le fork. La partie technique tient en trois paragraphes. La partie intéressante est ailleurs : dans les usages qui décident si un correctif offert sera lu, ou ignoré.
1. Une panne qui se présente bien
Ollama Cloud avait retiré le modèle de langage à minuit, heure du Pacifique. Pas prévenu, pas de préavis : un modèle hébergé disparaît quand son hébergeur le décide.
Tout ce qui parle s’est mis à échouer — les liens entre morceaux, les identifiants de station, les rubriques. Et le sélecteur de titres aussi, qui a fait ce qu’on lui a appris à faire quand il ne peut plus réfléchir : prendre le premier candidat du vivier. Donc la musique continuait, sans choix éclairé, et le voyant restait vert.
C’est la signature de la panne coûteuse : celle qui ne ressemble pas à une panne. Une erreur franche se voit en une seconde. Une dégradation silencieuse derrière un indicateur au vert peut durer des heures — ici, jusqu’à ce qu’une oreille remarque que le DJ s’était tu.
La cause était dans les journaux dès la première recherche, parce qu’un réflexe y était écrit depuis juillet : devant un silence, on vérifie le modèle avant de chercher un bug dans le code. Troisième occurrence en trois mois. La note avait payé.
2. Le filet qui ne pouvait pas rattraper
Subwave a un secours prévu pour ça : une seconde voie de repli, configurée ici sur un modèle local, donc à l’abri des retraits. Il était correctement réglé. Il n’a pas bougé.
En lisant le code, la raison saute aux yeux. La bascule ne se déclenche que sur quatre familles d’erreur : hôte injoignable, quota ou authentification, amont saturé, débit limité. Un modèle retiré n’en est aucune — l’hôte répond parfaitement, la clé est bonne, il n’y a ni quota ni surcharge. Le secours n’était donc jamais sollicité.
Les chiffres d’une journée : 401 échecs, zéro tentative de bascule.
Le filet existait, il était bien accroché, et il ne pouvait structurellement pas attraper cette chute-là. C’est une nuance qui mérite qu’on s’y arrête, parce qu’elle se répète partout : une protection configurée n’est pas une protection vérifiée. Tant que rien ne prouve qu’elle produit un résultat, elle ne fait que rassurer.
3. Rendre, plutôt que rapiécer
Ici commence la partie qui m’intéresse.
Le réflexe du fork, c’est de corriger chez soi et de passer à autre chose. C’est tentant : c’est immédiat, ça ne demande de comptes à personne, et ça marche. Sauf que chaque correctif gardé pour soi devient une divergence — une ligne de plus à reporter à chaque mise à jour, une friction permanente, et un savoir qui ne profite à personne d’autre.
Rendre le correctif coûte une heure de plus et rapporte deux choses : la divergence finit par disparaître d’elle-même si elle est acceptée, et le prochain qui tombera sur la panne trouvera la réparation déjà faite.
Mais on ne dépose pas un correctif chez quelqu’un comme on range sa propre cuisine.
4. Les usages, et ce qu’ils protègent
Ce qu’on appelle « politesse » dans une contribution n’est pas de la délicatesse. C’est un protocole de coordination entre gens qui ne se connaissent pas, ne se parleront jamais, et n’ont aucun moyen de synchroniser leurs efforts autrement. Chaque convention y protège quelque chose de précis.
Chercher avant d’ouvrir
Avant d’écrire une ligne, on cherche si c’est déjà signalé. Pour la deuxième panne — les DJ qui annonçaient leur propre nom avant de parler, « Iris : bonsoir » — l’issue existait déjà, ouverte quatre jours plus tôt par quelqu’un d’autre.
Ouvrir un doublon n’est pas un crime, c’est juste du travail en double pour le mainteneur : il devra lire, comprendre, rapprocher, fermer. Ce qu’on protège ici, c’est son attention — la ressource la plus rare d’un projet ouvert.
Commenter l’existant plutôt que recommencer
Le fil contenait déjà deux hypothèses : l’auteur du rapport accusait ses petits modèles locaux ; un contributeur pensait qu’il suffirait de durcir la formulation du prompt.
Mes mesures contredisaient les deux. Je tourne sur un modèle hébergé, pas sur un petit local, et j’avais le symptôme à 32 % — douze lignes parlées sur trente-sept en quarante-huit heures. Et l’instruction interdisant les étiquettes figurait déjà à trois endroits du code, dont un correctif écrit par ce contributeur lui-même un mois plus tôt. Le modèle se le fait dire trois fois et recommence une fois sur trois.
Apporter ça dans le fil existant plutôt que dans une issue neuve, c’est laisser la discussion au même endroit. Ce qu’on protège, c’est le fil — sa lisibilité pour celui qui le retrouvera dans six mois.
Apporter des mesures, pas des avis
« Ça marche pas » n’aide personne. « Douze sur trente-sept, sur un modèle hébergé, voici deux lignes verbatim » déplace une conversation.
Et surtout : on contredit une hypothèse sans humilier celui qui l’a posée. Le contributeur avait tort sur la cause, mais son intuition était raisonnable et il l’avait explicitement donnée comme telle — « mon impression sans avoir ouvert le code ». On écrit ce que les chiffres disent, on ne marque pas de point.
Annoncer qu’on s’y met
Le détail qui compte le plus, et qu’on oublie le plus souvent. Ce contributeur avait écrit dans le fil : « si quelqu’un veut proposer un correctif avant moi, allez-y ».
J’ai commenté avant de coder, en disant que je m’y mettais. Pas par cérémonie : parce qu’il avait annoncé vouloir s’en occuper après sa tâche en cours. Sans ce message, on risquait d’écrire deux fois le même correctif — et le sien aurait été jeté, ou le mien.
Ce qu’on protège, c’est le temps de l’autre. C’est la seule chose qu’on ne peut pas lui rendre.
Viser la bonne branche
Ce projet fusionne sur develop, pas sur main. C’est écrit dans ses notes de contribution, et c’est l’erreur la plus fréquente parce que l’outillage suggère spontanément main.
Une PR sur la mauvaise base, c’est un diff illisible et un mainteneur qui doit expliquer. Trente secondes de vérification contre une friction garantie.
Compléter la défense, ne pas la remplacer
Le prompt interdisait déjà les étiquettes. J’aurais pu retirer ces instructions devenues « inutiles » puisque le code les rattrape maintenant.
Surtout pas. Elles restent la première ligne : elles abaissent le taux, le code ferme la porte. Toucher à ce qu’on n’est pas venu corriger, c’est agrandir la surface de relecture et donner une raison de refuser.
Écrire les tests de ce qui ne doit PAS changer
Mon correctif retire une étiquette en tête de ligne. La tentation est d’écrire « retire n’importe quel Mot : ». Elle est fausse : un DJ qui dit « Attention : voici le morceau » perdrait son premier mot.
La garde tient en une phrase : on ne retire un préfixe que s’il correspond à un nom de la distribution en cours — que le code connaît déjà, puisque c’est lui qui route les voix.
Et la moitié des tests vérifie précisément ce qui ne doit pas bouger : la vraie parole avec un deux-points survit, un nom hors distribution reste en place, un nom plus loin dans la phrase n’est pas touché. Ces tests-là sont un message au relecteur : voilà ce que j’ai pensé casser, voilà pourquoi ce n’est pas cassé.
Signaler ses propres pièges
Dans le premier correctif, ma détection cherchait une formule d’erreur dans un message. J’avais exclu le point pour rester dans une phrase — sans penser que les noms de modèles en contiennent : llama3.1, qwen2.5, gpt-3.5. La recherche s’arrêtait à l’intérieur du nom qu’elle essayait de lire. Deux itérations perdues.
Je l’ai écrit dans la PR, en toutes lettres. Pas par contrition : parce que c’est exactement ce qu’un relecteur bien intentionné réintroduira en trouvant la fenêtre trop large. Un piège documenté est un piège désamorcé.
5. Ce que la politesse achète vraiment
Aucune de ces conventions n’est une question de savoir-vivre. Chacune retire une friction précise à quelqu’un qui ne vous doit rien et qui pourrait fermer votre proposition sans la lire.
Un projet ouvert n’a pas de hiérarchie pour arbitrer, pas de réunion pour se synchroniser, pas de contrat pour obliger. Il n’a que des conventions. Les respecter, c’est rendre son travail utilisable par quelqu’un qu’on ne rencontrera jamais.
Et ça marche dans les deux sens. Le contributeur qui a écrit « allez-y si vous voulez » m’a offert exactement la même chose : une information qui m’évitait de travailler pour rien.
6. Où ça en est
Deux propositions déposées, deux correctifs qui tournent déjà ici en attendant :
- le secours qui ne rattrapait pas un modèle retiré — une famille d’erreur ajoutée aux conditions de bascule, avec les tests qui vérifient que le portillon ne s’élargit pas au passage ;
- les étiquettes de locuteur qui partaient à la synthèse vocale — un nettoyeur qui ne retire qu’un nom de la distribution connue.
Mille sept cent trente-cinq tests au vert dans les deux cas. Aucune revue humaine pour l’instant : c’est le rythme normal d’un projet vivant, et l’attente fait partie du protocole elle aussi.
Si les deux sont acceptés, mes divergences locales disparaîtront d’elles-mêmes à la fusion suivante — le correctif reporté chez moi et le commit venu d’amont portent le même contenu. C’est la meilleure fin possible pour une modification de fork : qu’elle cesse d’exister en tant que divergence.
Et la radio parle de nouveau.