1 points par GN⁺ 3 시간 전 | 1 commentaires | Partager sur WhatsApp
  • La réécriture de Bun en Rust ressemble davantage à une décision de migration vers une stack technologique plus grand public, tout en conservant l’architecture et les structures de données existantes construites en Zig
  • La PR de réécriture représentait 6 755 commits et a été ouverte le 8 mai puis fusionnée le 14 mai, ce qui laisse planer un doute sur la profondeur de revue d’un changement de runtime de niveau production
  • La réussite des tests ne valide que les chemins connus, et il est difficile de garantir aussi des invariants globaux comme les chemins d’erreur, la concurrence ou des conditions mémoire extrêmes
  • Le point central n’est pas un échec de Zig, mais un décalage structurel entre la culture de l’équipe Bun, tournée vers des sorties rapides, et le coût de la gestion manuelle de la mémoire
  • Le vrai pari n’est pas Zig contre Rust, mais de savoir si du code généré par l’IA et insuffisamment relu peut être maintenu à long terme

Les fondations de Bun construites avec Zig

  • Avant de regarder la PR de réécriture Rust de Bun, il faut rappeler que Zig a joué un rôle majeur dans l’ascension de Bun jusqu’à sa position actuelle
  • Si Jarred a choisi Zig, ce n’était pas parce que c’était « cool », mais parce que cela permettait à une petite équipe de prototyper rapidement un runtime JS haute performance sans garbage collector
  • La faible friction de Zig, sa manipulation directe de la mémoire et son interopérabilité simple avec le C ont rendu possibles les performances initiales de Bun et la petite taille de son équipe
  • Puisque Jarred a déclaré que « l’architecture ne change pas, et les structures de données ne changent pas non plus », la réécriture en Rust ressemble davantage à la reprise de l’ossature construite en Zig
  • Construire la base avec Zig, lancer le produit, lever des fonds, puis migrer vers une stack plus grand public une fois l’entreprise acquise et agrandie peut être vu comme une décision commerciale normale
  • En revanche, il est difficile de présenter cela comme une preuve d’inadéquation de Zig lui-même

Les risques d’une réécriture massive fusionnée en 6 jours

  • La PR de réécriture a laissé des traces parlantes : 6 755 commits, un nom de branche claude/phase-a-port, ouverte le 8 mai puis fusionnée le 14 mai
  • Le cœur du problème est qu’une réécriture complète d’un runtime JS de niveau production a été fusionnée en 6 jours
  • Un principe de base du software engineering dit que « le code qu’on ne comprend pas ne devrait pas tourner en production »
  • Ce principe n’existe pas forcément parce que le code contient des bugs, mais parce que lorsqu’un bug survient, on ne sait plus par où commencer : c’est une ligne de base de la maintenabilité
  • Dans la liste des reviewers de la PR figuraient coderabbitai[bot] et claude[bot], tandis que l’unique reviewer humain, alii, était au statut « Awaiting requested review »
  • Une boucle fermée où Claude écrit et Claude relit n’est pas logiquement impossible, mais cela signifie en pratique qu’aucun humain n’a réellement lu l’ensemble du code jusqu’au bout

Ce que la réussite des tests ne garantit pas

  • Même si la suite de tests passe sur toutes les plateformes, cela ne valide que la justesse des comportements connus et des chemins connus
  • Une suite de tests a du mal à garantir suffisamment les points suivants
    • que les chemins d’erreur sont correctement gérés
    • quel est le comportement aux limites sous forte contrainte
    • que la cohérence de l’état est préservée en situation de concurrence
    • que le modèle mémoire reste conforme à l’intention dans des conditions extrêmes
  • Jarred aurait lui-même reconnu que les problèmes mémoire lors de la réentrée dans la frontière JS ne peuvent pas être pris en charge par le compilateur Rust et dépendent toujours des humains
  • Le problème est que cette partie qui dépend des humains n’a justement pas été relue par des humains
  • La traduction de code par l’IA se rapproche d’une équivalence sémantique locale : faire en sorte que chaque fonction se comporte comme l’original, de manière isolée
  • Mais les invariants globaux entre fonctions, ainsi que les contraintes de conception absentes des tests et présentes seulement dans la tête de l’auteur initial, sont difficiles à garantir par une simple traduction par IA
  • Ce genre de contraintes peut ne pas apparaître dans les tests actuels, puis se manifester six mois plus tard sous une charge de production particulière, sous forme de crashs difficiles à expliquer
  • Ce n’est pas un problème propre à Claude : cela vaut aussi pour tout outil ou programmeur humain qui traduit sans revue suffisante
  • À l’échelle de 6 755 commits, ce risque est fortement amplifié

Depuis le rachat, ceux qui portent le risque ont changé

  • Au départ, Bun était un projet sur lequel Jarred pariait lui-même ; l’usage de Zig, les itérations rapides et l’acceptation de dette technique pouvaient se comprendre dans une logique de startup où l’on assume soi-même le risque
  • Maintenant que Bun a été acquis par une grande entreprise et dispose d’une base d’utilisateurs qui l’exécutent dans de vrais systèmes de production, ceux qui portent le risque de la réécriture ne sont plus Jarred, mais les ingénieurs qui font tourner Bun en production et les utilisateurs derrière eux
  • Jarred dit que cette version est encore en canary et qu’il reste des optimisations et du nettoyage à faire avant la release officielle
  • Le canary est une ligne de défense, mais pas un substitut à la revue humaine
  • L’optimisation et le nettoyage relèvent de la qualité du code ; ils ne résolvent pas la question de savoir si les mainteneurs comprennent réellement le code
  • Une codebase que personne dans l’équipe n’a entièrement lue reste une boîte noire pour les mainteneurs, même si les tests sont complets ou si la phase canary dure longtemps
  • Ce problème peut se traduire par une vraie douleur le jour où il faudra déboguer un bug grave

L’erreur de diagnostic sur Zig

  • Selon les explications précédentes de Jarred, l’ancienne codebase Zig contenait beaucoup de use-after-free, de double-free et de fuites mémoire sur les chemins d’erreur
  • Ce diagnostic en lui-même peut être correct, mais il est difficile d’en conclure que « Zig ne fonctionne pas »
  • Un diagnostic plus précis serait que, dans un projet commercial privilégiant les itérations rapides, le coût cognitif de la gestion manuelle de la mémoire a dépassé le budget de l’équipe
  • On peut y voir non pas un bug de Zig, mais un décalage structurel entre les objectifs de conception de Zig et le modèle économique de Bun
  • Le public visé par Zig est constitué de programmeurs systèmes qui savent ce qu’ils font et sont prêts à payer le coût du contrôle total
  • TigerBeetle a écrit en Zig une base de données pratiquement sans bugs mémoire, ce qui s’expliquerait par une culture d’équipe et une nature de projet alignées avec la philosophie de Zig
  • La culture de l’équipe Bun est plus proche d’itérations rapides, de releases rapides et de corrections rapides, ce qui crée une tension fondamentale avec la discipline mémoire stricte qu’exige Zig
  • Interpréter « notre équipe fait souvent des erreurs avec cet outil » comme « cet outil est inadapté » relève presque de l’erreur d’attribution
  • L’auteur utilise l’analogie suivante : si le marteau ne convenait pas, cela ne veut pas dire que le marteau est lui-même en faute

Perspectives à court terme et risques à long terme

  • À court terme, il est probable que la version réécrite fonctionne globalement correctement
  • Les chemins principaux sont couverts par les tests, les problèmes évidents apparaîtront pendant la phase canary, et les garanties du compilateur Rust éliminent un certain type de bugs mémoire
  • En surface, tout peut sembler normal
  • À long terme, ces 6 755 commits qu’aucun humain n’a lus entièrement restent un risque structurel
  • Si, dans six mois, un bug de concurrence étrange apparaît, ou si une condition limite provoque un comportement anormal sous une certaine charge, l’ingénieur chargé du débogage se retrouvera face à un système que personne n’a jamais vraiment compris
  • Dire qu’il s’agit d’un système jamais compris ne signifie pas qu’il n’a pas de bugs, mais que lorsque les bugs apparaîtront, personne ne saura pourquoi
  • Le vrai pari technique de cette réécriture n’est pas Zig contre Rust, mais de savoir si du code généré par l’IA et non relu peut être maintenu à long terme en production
  • Cette question est plus complexe que « tous les tests passent » et plus profonde que « la sûreté mémoire de Rust »
  • La conclusion se résume dans cette image : « Zig a posé les fondations, Claude a construit le bâtiment, et les reviewers humains sont encore en route »
  • La durée pendant laquelle ce bâtiment restera habitable dépendra de la capacité de quelqu’un à lire les plans au moment où la première fuite apparaîtra

1 commentaires

 
GN⁺ 3 시간 전
Avis sur Lobste.rs
  • Avant de parler de « réécrire Bun en Rust », il faut rappeler que si Bun en est arrivé là aujourd’hui, c’est grâce à Zig
    Le créateur de Bun, Jarred, le dit lui-même. Selon lui, Zig a rendu Bun possible, et Zig a largement contribué à faire passer un projet codé seul pendant un an dans une chambre qui puait à Oakland à l’un des outils les plus utilisés de l’écosystème JavaScript
    Il ajoute aussi que Zig est un excellent langage et que Bun lui doit beaucoup, mais que d’autres projets comme Ghostty ou Tigerbeetle n’ont pas rencontré les problèmes de stabilité qu’a connus Bun

    • Si « d’autres projets comme Ghostty ou Tigerbeetle n’ont pas rencontré les problèmes de stabilité qu’a connus Bun », cela vaut la peine de se demander pourquoi
      En général, une base de données a des contraintes de stabilité bien plus fortes qu’un runtime de langage
  • Ce texte sent fortement le texte écrit par un LLM

  • Si l’utilisateur cible de Zig est « un programmeur système qui sait ce qu’il fait et est prêt à en payer le prix pour avoir le contrôle ultime », cela ressemble à une forme de surconfiance à la C/C++ réapparue dans le contexte des langages arrivés après Rust et Swift
    Si Jarred dit qu’il migre parce qu’il y avait « trop d’use-after-free, de double free et de fuites mémoire sur les chemins d’erreur dans la base de code Zig », cela constitue un point de données sur la question de savoir si l’on peut rendre un langage non memory-safe pratiquement sûr simplement en demandant à un LLM de traquer les bugs de sécurité mémoire avec acharnement
    Même les entreprises de LLM n’ont pas choisi cette voie ici

  • L’idée selon laquelle « du code écrit par Claude et relu par Claude forme une boucle fermée qui n’est pas logiquement impossible, mais cela signifie qu’aucun humain n’a jamais réellement lu l’ensemble de cette base de code » paraît clairement erronée
    Si une base de code Zig écrite par des humains a été traduite mécaniquement en Rust, alors les personnes qui comprennent le code d’origine peuvent aussi comprendre le nouveau code. Ce n’est pas comme si on la portait en APL ; ce sont dans les deux cas des langages procéduraux de tradition syntaxique C
    On peut laisser ouverte l’idée qu’à l’avenir, faire tourner des LLM sans supervision éloignera peu à peu le code de l’intuition humaine, mais à ce stade la base de code semble encore compréhensible, autant qu’on peut l’attendre d’un runtime JavaScript d’un million de lignes et d’un outil fourre-tout en binaire unique
    La phrase « l’IA n’assure qu’une équivalence sémantique locale au niveau des fonctions, sans comprendre les invariants globaux entre fonctions » est étrange, aussi bien dans un sens favorable aux LLM que critique
    Les LLM ne sont pas assez déterministes pour garantir que chaque fonction se comporte exactement comme l’original. Pour ce type de garantie, il faut des outils comme c2rust. Un LLM peut traduire du code qui ressemble à l’original, mais empêcher qu’il transforme ((abc & 45) << 3) == 360 en ((abc & 45) << 30) == 360 repose seulement sur le compilateur, la suite de tests, et peut-être la détection probabiliste d’une revue de code par LLM
    À l’inverse, s’il existait un traducteur qui, comme c2rust, garantisse l’identité de chaque fonction tout en préservant aussi les commentaires et la structure comme un LLM, alors ce serait un traducteur parfait et il pourrait porter automatiquement une base de code d’un million de lignes. On peut même voir les compilateurs comme un cas particulier de cela, et Clang, sans être exempt de bugs, est suffisamment proche de cette confiance pour que les gens s’y fient. Si un LLM pouvait traduire du Zig ou du C++ vers Rust avec un niveau de confiance comparable à Clang, Chrome serait devenu 100 % Rust d’ici la fin du mois
    De plus, encoder des invariants entre fonctions, c’est précisément au cœur du système de types. L’une des raisons de réécrire Bun en Rust est justement que le système de types de Rust peut mieux exprimer des invariants complexes. Anthropic n’a pas non plus compilé le tout en assembleur avant de brûler le code source

    • La phrase « si une base de code Zig écrite par des humains a été traduite mécaniquement en Rust, alors les personnes qui comprennent le code d’origine peuvent aussi comprendre le nouveau code » risque d’être entièrement optimisée hors de l’existence en release fast :^)
      Bun faisait déjà du vibe coding bien avant le portage vers Rust. Le projet a adopté l’IA assez tôt, et depuis le rachat d’Anthropic, presque tous les commits sont écrits par des bots. Jarred a aussi tweeté qu’il avait fait écrire des fonctionnalités à une IA pendant le week-end, ce qui a ajouté plusieurs fonctionnalités
    • Indépendamment de l’observation de Kristoff selon laquelle Bun n’est plus depuis longtemps une base de code écrite par des humains, cela semble supposer que le portage par Claude serait une traduction mécanique, alors qu’en pratique cela n’a pas l’air d’être le cas
      HTML Parsers in Portland analyse plusieurs portages d’un parseur HTML Python et montre que l’un des algorithmes centraux y est implémenté de manière très différente selon les portages. Dans tous les cas, un portage mécanique était possible, mais ce n’est pas ce qui a été fait en pratique
      Certes, c’est un exemple du début d’année et le processus était différent, mais certains fragments observés dans la base de code de Bun après le portage semblent souffrir de problèmes similaires
    • L’affirmation « si une base de code Zig écrite par des humains a été traduite mécaniquement en Rust, alors les personnes qui comprennent le code d’origine peuvent aussi comprendre le nouveau code » est en soi correcte
      Mais le fait que « les LLM ne sont pas assez déterministes pour garantir que chaque fonction se comporte comme l’original » conduit au final à la conclusion qu’aucun humain n’a réellement lu l’ensemble de la base de code
  • Un exemple de « tous les tests passent » : https://github.com/oven-sh/bun/…

    • La modification de ce commit ne figure pas dans le diff final, et on peut facilement le vérifier soi-même
      Comme plusieurs personnes sur d’autres forums ont aussi lié ce même commit, on dirait qu’elles ont vu ce lien quelque part, ont trouvé que cela collait bien à leurs attentes, puis n’ont pas vérifié s’il était réellement pertinent. Je pense qu’il faut s’imposer un niveau d’exigence plus élevé
    • Pour le meilleur ou pour le pire, ce commit est un commit écrit par un humain qui annule partiellement un commit précédent lui aussi écrit par un humain
      Premier commit : « await process exit / JSON-parse-retry instead of fixed sleeps »
      Annulation : « test: revert proc.exited change in spawn.test.ts, keep isDebug iteration count »
  • Je réfléchis beaucoup en ce moment au principe selon lequel « il ne faut pas exécuter en production du code qu’on ne comprend pas »
    Ma carrière est déjà bien avancée, mais j’ai délibérément évité d’aller vers le management, et mon parcours en programmation s’est même orienté de plus en plus vers les couches basses de la stack. Parce que j’aime comprendre en profondeur les programmes eux-mêmes. Livrer des fonctionnalités et améliorer la vie des utilisateurs est très important, mais l’une des grandes récompenses intérieures de la programmation, c’est cette impression d’apprendre des vérités réelles sur les systèmes concrets
    Pour quelqu’un comme moi, l’idée qu’un humain doive comprendre chaque ligne d’un programme ressemble à un axiome. Pourtant, sur l’organigramme, mon manager est responsable du programme dont j’assure la maintenance. C’est un excellent manager et il ne micro-manage pas, donc bien sûr il ne comprend pas chaque ligne du logiciel livré par l’équipe. En fait, je ne sais même pas s’il a beaucoup lu le code. Alors, en un sens, il enfreint déjà ce principe
    Je me demande s’il existe une différence significative entre « du code écrit par un collaborateur que je ne comprends pas » et « du code écrit par mon IA que je ne comprends pas »
    Le cas 1 me paraît acceptable, mais le cas 2 me met mal à l’aise. La différence tient-elle seulement au fait qu’il y ait un humain qui en porte la responsabilité ? Au fait qu’il y ait quelqu’un à blâmer ? Je ne sais pas encore si cela suffit à justifier le fort sentiment moral que j’éprouve
    Je crains que cette émotion intense ne soit pas indispensable à une bonne ingénierie, mais relève davantage d’une esthétique personnelle. Chacun peut avoir ses préférences, mais si ce n’est que cela, il faut peut-être s’attendre à ce que cet aspect du métier devienne moins agréable à l’avenir. En fin de compte, ce serait comme être poussé vers le management, sauf que mes subordonnés seraient des bots

  • On dit que « Zig a permis à une petite équipe de prototyper rapidement un runtime JS hautes performances sans garbage collector ni runtime lourd », mais d’autres runtimes majeurs, Node et Deno, font la même chose
    Tous deux encapsulent un moteur JS en C++ et Rust, des langages sans garbage collector. Je ne sais pas vraiment si V8 ou JSC embarquent eux-mêmes un garbage collector au moment du déploiement, mais ce n’est pas le sujet central

  • L’ensemble du dépôt Bun donne une impression dystopique. Des bots se parlent entre eux et produisent des PR absurdes
    Exemple : https://github.com/oven-sh/bun/issues/30766

  • La vitesse à laquelle cela a été considéré comme « terminé » est assez choquante, mais je n’y vois pas l’accident de train en marche que le texte décrit sans preuves solides
    Dire que « dans six mois, un bug de concurrence étrange apparaîtra, et quand une condition limite sous une certaine charge déclenchera un comportement anormal, l’ingénieur chargé du débogage se retrouvera face à un système que personne n’a jamais réellement compris » relève de la pure spéculation, sans faits à l’appui
    Les portages de langage sont un domaine bien adapté aux LLM, et beaucoup d’humains comprenaient déjà le code de base. Je ne vois pas pourquoi un simple portage de langage détruirait soudainement et irréversiblement la capacité à diagnostiquer le système