Steven
Steven7 min de lecture

L'anatomie d'un logiciel livré à la perfection : comment la revue de code a rattrapé ce que les tests ne voyaient pas

À travers toute la série GeekBye v2, la même chose se répète : un correctif passe tous les tests sur la machine du développeur, puis la revue de code prouve qu'il aurait échoué pour presque tout le monde. Voici le workflow derrière neuf versions — la barrière de revue, les diagnostics posés avant le correctif, et la discipline du test-avant-livraison qui transforme le « ça marche chez moi » en « ça marche ».

Ingénierie
Processus
Revue de code
GeekBye Releases
L'anatomie d'un logiciel livré à la perfection : comment la revue de code a rattrapé ce que les tests ne voyaient pas

En l'espace de quelques semaines, GeekBye a livré neuf versions — de la v2.0.0 à la v2.0.11 — et cette série a raconté l'histoire de chacune. Lisez-les ensemble et un motif ressort, plus intéressant que n'importe quel bug isolé : encore et encore, un correctif a passé tous les tests sur la machine du développeur, et la revue de code a prouvé qu'il aurait échoué pour presque tous les autres.

Cet écart — entre « ça marche chez moi » et « ça marche » — c'est là que réside vraiment la fiabilité. Voici le workflow qui le comble, et l'index de chaque version qu'il a produite.

Le motif : des tests au vert, la mauvaise réponse

Voici trois des cas les plus clairs de la série, parce qu'ils rendent l'abstrait concret.

  • Dans le correctif de capture multi-écran (v2.0.10), la première implémentation ancrait la capture d'écran sur la fenêtre d'overlay de l'application. Elle a passé les tests — sur une machine de dev à un seul écran. La revue a raisonné sur l'endroit où cet overlay se trouve réellement (l'écran principal, toujours, sauf si vous le déplacez physiquement) et a prouvé que le « correctif » serait revenu tout droit vers le mauvais écran pour presque tous les vrais utilisateurs. Le bon point d'ancrage — le curseur — est sorti de cet argument, pas d'une exécution de test.
  • Dans la version avec repli WebSocket (v2.0.8), la revue a découvert que le 403 exact que renvoie un proxy bloquant était classé comme une erreur d'authentification fatale — de sorte que le repli que la fonctionnalité existait justement pour déclencher ne pouvait jamais se déclencher. La fonctionnalité aurait été livrée, aurait passé ses tests de scénario nominal, et n'aurait rien fait pour son public réel.
  • Dans le correctif du délai d'inactivité (v2.0.9), la première version horodatait l'horloge « toujours en vie » à l'intérieur d'un chemin de code qu'un sous-ensemble de transcriptions saute légitimement — celui de l'autre interlocuteur. La revue a repéré qu'un futur changement pourrait réintroduire en silence le bug même qu'on corrigeait, et l'horodatage a été déplacé à un endroit inconditionnel, avec un test pour l'y maintenir.

Aucun de ces cas n'a été rattrapé en exécutant le code. Tous ont été rattrapés par un relecteur qui raisonnait sur les raisons pour lesquelles le code fonctionne — et qui a trouvé un cas où il ne fonctionne pas.

Les trois parties de la barrière

Le workflow derrière la série n'a rien d'élaboré. Ce sont trois habitudes appliquées sans exception.

1. La revue raisonne sur la correction, elle ne se contente pas d'exécuter le code. Un test qui passe prouve que le code fonctionne pour le cas auquel vous avez pensé. La revue est un second modèle du système, adverse, qui demande à quel cas n'avez-vous pas pensé ? — le deuxième écran, le proxy d'entreprise, la transcription qui saute la branche, le client qui a une version de retard. L'étape de revue dans cette série était souvent un agent relecteur indépendant, incité à réfuter le correctif, pas à le bénir. Ce cadrage est tout l'enjeu : un relecteur qui essaie de casser votre raisonnement trouve le trou qu'un relecteur qui essaie de l'approuver survole.

2. Chaque correctif de comportement est livré avec un test qui fige l'échec exact. Pas un test qui vérifie que la fonctionnalité marche — un test qui vérifie que ce bug précis est mort. Le 403 du proxy bloquant doit basculer vers le repli ; un vrai 403 d'authentification ne doit pas. L'horloge d'activité doit s'horodater sur une transcription qui saute l'attribution. Ces tests existent pour que le bug ne puisse pas revenir discrètement dans six mois quand quelqu'un refactorisera à côté — l'échec est cloué au sol.

3. Le build est notarisé et vérifié avant d'être livré. Plusieurs de ces correctifs sont passés du diagnostic à une version signée, notarisée et auto-actualisée en une journée. Cette vitesse n'est sûre que parce que la barrière est disciplinée : le diagnostic prouve la cause racine (la version sur les permissions du microphone a livré son diagnostic en premier), le test fige le correctif, la revue réfute le raisonnement, et c'est seulement alors qu'un vrai build notarisé part. La rigueur est ce qui rend la vitesse sûre, pas ce qui se fait au détriment de la vitesse.

Pourquoi cela compte encore plus pour une application d'IA

Il y a une raison pour laquelle cette discipline est non négociable pour un outil comme GeekBye en particulier. Plusieurs des bugs les plus vicieux de la série étaient silencieusement faux, pas bruyamment plantés : une capture d'écran qui envoyait le mauvais écran à l'IA (v2.0.10), une transcription biaisée vers des termes parasites de sorte que « speak » ressortait comme un nom (v2.0.11), un assistant qui répondait dans le mauvais mode sans aucun moyen de le voir (v2.0.3 + v2.0.5). Quand votre application fournit du contexte à un modèle, une entrée erronée produit une sortie fausse avec assurance et aucune erreur nulle part. On ne peut pas se sortir par les tests d'échecs qui ne lèvent rien. Il faut s'en sortir par le raisonnement — ce à quoi sert exactement la barrière de revue.

La série, dans l'ordre

Chacun de ces articles est une étude de cas autonome sur une version. Lus du début à la fin, ils sont l'anatomie du passage d'un produit du stade « ça marche » au stade « on peut lui faire confiance ».

  1. Ce qu'exige vraiment une version 2 : 206 commits d'états honnêtes — v2.0.0. Le fondement : ne jamais afficher un état qui n'est pas vrai.
  2. Le jour où notre application s'est auto-DDoSée — v2.0.1 + v2.0.4. Un arriéré d'envois au démarrage qui piétinait notre propre backend, et l'échelle de vivacité qu'il a imposée.
  3. Un logiciel apaisé : le correctif du scintillement et la pastille de mode de réponse — v2.0.3 + v2.0.5. Des versions sans fonctionnalité qui ont acheté la confiance un détail à la fois.
  4. Votre application Mac oublie l'accès au microphone à chaque lancement — v2.0.6. La translocation d'application de macOS, et livrer le diagnostic avant le correctif.
  5. Une variable CSS, cinq tours de revue, et une chaîne d'outils Swift qui mentait — v2.0.7. Une translucidité uniforme, et un binaire qui changeait de taille parce que la doc était en désaccord avec le script de vérification.
  6. La transcription en direct quand le pare-feu bloque les WebSockets — v2.0.8. Un repli en pur HTTPS, et le 403 qui l'aurait caché à lui-même.
  7. Pourquoi votre preneur de notes IA arrête d'enregistrer au milieu d'une réunion — v2.0.9. Un minuteur d'inactivité qui ne pouvait entendre que vous, et un plantage qui pouvait verrouiller votre bureau.
  8. Pourquoi l'enregistrement d'écran capture le mauvais moniteur — v2.0.10. Le bug du mauvais écran, et le correctif qui passait sur un moniteur et aurait échoué sur deux.
  9. Pourquoi la transcription IA entend mal les termes techniques — v2.0.11. Biaiser la reconnaissance vocale vers votre vocabulaire — et la régression qui l'a rendue pire avant de la rendre meilleure.

À retenir

La perfection n'est pas un état que l'on atteint ; c'est une barrière que l'on tient. Neuf versions, et les trois mêmes questions à chacune : à quel cas n'avez-vous pas pensé, l'échec exact est-il figé par un test, et un vrai build signé est-il réellement parti ? Rien de tout cela n'est glamour. Tout cela est la raison pour laquelle GeekBye v2 donne cette impression d'apaisement. Si vous construisez du logiciel — d'IA ou autre — la partie transférable n'est aucun correctif isolé. C'est l'habitude de traiter une suite de tests au vert comme le début de l'argument, pas comme sa fin.

Chaque version ci-dessus est en ligne via l'auto-mise à jour. Pour découvrir le produit auquel ces correctifs aboutissent, voyez les nouveautés de GeekBye v2.

Articles Connexes

Le silence était porteur
Steven
Steven9 min de lecture

Le silence était porteur

Les deux dernières versions de GeekBye v1 tournent autour de la même vérité inconfortable : la transcription en temps réel sur un vrai réseau n'est pas sans perte, et le geste honnête est de cesser de prétendre le contraire. La v1.8.20 gardait sur disque une copie de chaque chunk audio avant de le jeter pendant une reconnexion, et s'est mise à marquer les trous dans la transcription à voix haute. La v1.9.0 a cessé d'envoyer le silence pour économiser de la bande passante — et a découvert que le silence était justement le signal que le transcripteur utilisait pour savoir qu'une phrase s'était terminée. Deux versions sur le coût de jeter les choses.

Ingénierie
Audio
Fiabilité
Les trois verbes qui gardent le Web Audio en vie
Steven
Steven10 min de lecture

Les trois verbes qui gardent le Web Audio en vie

Deux versions ponctuelles de GeekBye, à deux mois d'écart et dans deux fichiers différents, ont enseigné à notre code audio la même leçon depuis des extrémités opposées : cesser de traiter l'AudioContext du navigateur comme jetable. Une version a appris à faire resume() d'un contexte que macOS avait silencieusement suspendu en pleine session d'enregistrement ; l'autre a appris à faire suspend() au lieu de close() pour que des sessions consécutives cessent de percuter le plafond d'environ six contextes de Chromium. Resume, suspend, close — voilà toute l'intrigue.

Ingénierie
Audio
Desktop
Distinguer un appel d'une app ouverte
Steven
Steven10 min de lecture

Distinguer un appel d'une app ouverte

GeekBye peut remarquer que vous avez rejoint une réunion vidéo et vous proposer de l'enregistrer. La détection s'avère être la moitié facile — un binaire Swift qui lit les titres de fenêtre toutes les dix secondes. La moitié difficile, c'est la précision : ne pas se déclencher quand Zoom est simplement ouvert, ne pas proposer d'enregistrer une réunion que vous enregistrez déjà, et ne pas couper le microphone dans l'appel où vous êtes réellement. Trois versions, et chacune est un garde-fou qui a dû apprendre à ne pas se saboter lui-même.

Ingénierie
macOS
Desktop