blog.vfg.lol

Journal du 30 septembre : le jour où la CI était rouge et personne ne le savait

Une nuit à planifier 22 lots sans en livrer un, un audit au petit matin, puis deux lots en ligne en une heure et demie — dont un bug qui empêchait toute livraison depuis six heures.

TL;DR

La nuit a produit 5 884 lignes de documentation et 20 lignes de code. À 06 h, la CI n'avait rien livré. À 07 h 52, alpha.12 était en ligne, avec didou de retour et les mises à jour qui ne coupent plus la partie. Entre les deux : un audit au petit matin, un bug invisible qui bloquait toutes les livraisons depuis six heures, et la preuve qu'une règle outillée vaut mieux qu'une règle écrite. Voici le journal de la journée, avec les chiffres et les leçons.

La nuit : beaucoup de plan, aucun lot

Le point de départ est une demande de FG : préparer une vague de fonctionnalités pour être réalisée « en parallèle par plusieurs agents, pour release deploy rapide ».

Résultat à 06 h du matin :

MesureValeur
Lots livrés en production0 sur 22
Lignes ajoutées au code produit+20
Lignes ajoutées aux plans, fiches, prompts, audits+5 884
Ratio documentation / code290 pour 1
Audits successifs, tous sur le plan10
Nombre de vagues annoncé, selon la source citée10, puis 9, puis 11, puis 7

La méthode n'a pas échoué parce que les agents étaient mauvais. Elle a échoué parce qu'elle avait optimisé le parallélisme d'un travail qui n'avait pas commencé. Chaque couche de planification a créé des défauts, que la couche d'audit suivante a trouvés, puis corrigés avec de la documentation — et ainsi de suite, pendant six heures.

Un détail résume la nuit : le script qui devait auditer le plan a effacé les sections d'audit écrites par les agents. Il a fallu un audit de plus pour s'en rendre compte. On auditait l'outil qui auditait le plan qui décrivait le code qu'on n'avait pas écrit.

06 h 19 : le bug que personne n'avait vu

À 06 h, la session reprend avec une mission simple : fusionner les PR en attente et sortir la release.

Première vérification, avant d'écrire quoi que ce soit — lancer les tests de la branche principale tels quels, sans rien toucher :

test/unit/check.test.mjs › un domaine : ses tests d'intégration et ses E2E
  actual:   [['appels','appels-salon'], ['phase7-appels','phase7-salon']]
  expected: [['appels','appels-salon'], ['phase7-appels','phase7-salles','phase7-salon']]

La branche principale ne passait plus son propre contrôle. Depuis une fusion de la nuit, une liste de tests avait été déplacée dans un fichier, mais le contrôle qui vérifie cette liste attendait l'ancienne version.

La conséquence est brutale, et il faut la dire clairement : aucune pull request, de personne, n'aurait pu obtenir la vérification complète verte. Un des deux lots les plus attendus — didou, le personnage qui accueille, répond aux idées et aux quêtes — était bloqué derrière ça. Pas par difficulté, pas par manque de code : par un désaccord de trois mots entre deux fichiers.

Ce qui rend ce bug intéressant, c'est pourquoi il a survécu six heures :

  • Les audits portaient sur le plan, pas sur le dépôt. Dix audits ont relu les intentions, les découpages, les dépendances entre lots. Aucun n'a lancé les tests de la branche principale.
  • Les documents disaient le contraire. Un commentaire dans le fichier modifié affirmait, mot pour mot, que le changement avait été fait « pour que le contrôle reste vert ». C'est exactement l'inverse qui s'était produit.
  • La CI ne pouvait pas le dire. Le contrôle échouait sur la branche principale, donc tous les runs étaient rouges, donc « rouge » était devenu la normale. On ne regarde plus un voyant qui clignote depuis toujours.

La réparation a pris deux minutes. Le diagnostic a pris cinq.

06 h 20 → 07 h 52 : deux lots et une release

Une fois le chemin dégagé, tout s'est enchaîné vite. Le tableau du jour :

HeureCe qui est faitFichiers
06 h 19Le bug bloquant est réparé, la branche principale repasse1 fichier, 7 lignes
06 h 42Règles de travail pour l'assistant, par portée3 fichiers
06 h 56Lot S1 : le déploiement pose et lève le voile de maintenance4 fichiers, 96 lignes
06 h 56Lot H1 : didou existe en production6 fichiers, 248 lignes
07 h 34Vérification complète locale : 1 100 secondes, tout vert—
07 h 52alpha.12 en ligne. /readyz répond 4.0.0-alpha.12—

Total : une heure et demie, dont environ 22 minutes d'écriture de code.

C'est le chiffre qui compte le plus : les deux lots de code ont pris 2 et 6 minutes à écrire. Les neuf dixièmes du temps ont été de la vérification, de la lecture et de l'attente. Le travail n'était pas dur. Il était bloqué, puis débloqué.

Ce que alpha.12 apporte, concrètement

Pour un habitant, deux choses :

1. didou est de retour. Le papillon de Jah a retrouvé son compte. Il t'accueille quand tu arrives, il répond à tes idées, à tes quêtes et à tes questions, et il offre le tutoriel du Wizz. Avant, son compte n'était créé que par un outil de développement : en production, les quatre fonctions qui dépendent de lui étaient mortes.

2. Les mises à jour ne te laissent plus bloqué dehors. Quand Jah se met à jour pendant que tu es connecté, l'écran de maintenance se lève maintenant pour de bon. Et pendant la mise à jour, tu vois la chenille au lieu d'une coupure sèche.

Sous le capot, c'est le premier déploiement de Jah qui se met en pause tout seul : il pose le voile, installe la nouvelle version, vérifie qu'elle répond, puis lève le voile. Et si la nouvelle version ne démarre pas, il lève le voile avant de revenir en arrière — pour que personne ne reste coincé devant un papillon qui ne s'en va plus.

Cinq leçons de la journée

1. Mesurer le dépôt, pas seulement le plan

Dix audits ont relu les intentions. Aucun n'avait lancé les tests. Un contrôle qui ne s'applique pas à lui-même ne contrôle rien — et le premier geste d'une session de livraison devrait être de lancer les tests sur la branche principale telle quelle, avant d'écrire une ligne.

2. Une règle outillée tient, une règle écrite ne tient pas

Le projet interdit en toutes lettres || true (masquer un échec) dans son plan, sur plusieurs pages. Le premier lot de la journée a quand même introduit deux || true. C'est le linter qui les a trouvés, en 55 secondes, avant tout le monde.

Le même jour, on a ajouté trois fichiers de règles pour l'assistant. La leçon n'est pas « il faut plus de règles » : c'est « ce qui compte doit être dans un linter, un test ou une vérification automatique ». Une règle en prose se perd ; une règle outillée se défend toute seule.

3. Un plan peut créer les bugs qu'il prétend éviter

Le défaut le plus dangereux de la nuit venait du plan lui-même : il réservait à l'avance les numéros de migration sur neuf vagues. Or l'outil de migration refuse, au démarrage, une migration plus ancienne que la plus récente appliquée. Résultat : un lot prévu en avant-dernière position aurait empêché le serveur de démarrer.

Même chose pour une fiche technique : elle prescrivait d'utiliser une variable de journalisation qui, à cet endroit précis du code, n'existe pas encore. Recopier la fiche à la lettre aurait produit une erreur au démarrage.

La leçon : plus une fiche est précise sans avoir été exécutée, plus elle propage des erreurs avec autorité. Une fiche décrit une intention et des contraintes ; elle ne remplace pas un test.

4. Sept endroits qui disent « où on en est », c'est six de trop

À un moment, le projet avait : le tableau de bord, le plan, les fiches de lot, les fiches techniques, le rapport d'audit, deux documents de passation, le journal d'exécution, les tickets. Ils ne disaient pas la même chose : le nombre de vagues valait 10, puis 9, puis 11, puis 7 selon la source.

Deux documents de passation écrits à 33 minutes d'écart se contredisaient, et l'un des deux recommandait une suppression qui aurait détruit trois fichiers uniques — le second a dû le corriger.

Ce qui ne ment jamais, c'est l'état du système : les pull requests, les vérifications, les versions déployées. Et STATUS.md, tenu par une seule personne, à un seul moment.

5. Le contexte d'un projet, c'est le dépôt

On avait retiré un agent de la vague au motif qu'il « perdait le contexte ». Mais aucun agent ne garde sa mémoire d'une session à l'autre — la nuit l'a prouvé, avec deux documents de passation contradictoires en 33 minutes, écrits par des outils censés transmettre le contexte.

Ce qui transmet vraiment le contexte : des petits diffs, un tableau de bord juste, et des tests. Pas des documents de passation de plus en plus longs. Quels que soient les outils, c'est la taille des lots qui fait tenir le contexte, pas le nombre de documents.

Ce qu'on change dès maintenant

RèglePourquoi
Un lot en ligne dans l'heure qui suit la demandeil sert de vérité à tout le reste
Au plus deux agents en code, une PR ouverte par agentle vrai goulot est la vérification et la relecture humaine
Trois cases : bug-prod (≤ 1 h, sans fiche) · petite-feature (≤ ½ j) · projet (fiche + décision)les 22 lots portaient tous l'étiquette « hotfix », y compris des projets de 3 jours
Une revue porte un diff ou la production — jamais un planle bug du jour était invisible à 10 audits de plan
Plafond de 15 % du temps pour la planificationau-delà, on code
La durée de la vérification est affichée dans le tableau de bordelle est passée de 5 à 18 minutes sans que personne ne le voie

Et demain ?

La file est prête, dans l'ordre : débloquer un ami, remettre un chantier à zéro, puis les fenêtres qu'on déplace et qu'on redimensionne. Un lot à la fois, une version à chaque fois.

La règle de la journée tient en une phrase : on livre d'abord ; le reste est du commentaire.


Journal du 30 septembre 2026. Les chiffres viennent de l'historique Git du dépôt Jah Messenger, des 30 derniers runs GitHub Actions, et de deux vérifications complètes mesurées au chronomètre. La version en ligne au moment d'écrire ces lignes : 4.0.0-alpha.12.

source markdown

Concepts de cet article

handoffgarde

Partage le plus de concepts avec