Simon Willison a subi des échecs de CI avec Ruff v0.16.0. Les valeurs par défaut avaient changé
- Aisha Washington

- il y a 1 heure
- 16 min de lecture
Simon Willison a constaté l’échec de plusieurs tâches de CI après que Ruff v0.16.0 a étendu ses règles de linting par défaut de 59 à 413. Sa dépendance de développement Ruff non verrouillée avait discrètement intégré la nouvelle version à des projets Python existants.
Astral a publié cette version le 23 juillet 2026. Deux jours plus tard, Willison a expliqué comment la mise à jour avait atteint ses builds sans mise à niveau volontaire. Ces échecs ont transformé une sortie de linter en avertissement concret sur la gestion des dépendances.
Le conflit central n’oppose pas un linting plus strict à un code moins robuste. Il porte sur l’amélioration de la sécurité sans configuration de Ruff et sur la stabilité que les développeurs attendent de dépôts inchangés. Cette tension compte partout où la CI installe, à chaque exécution, les dernières versions disponibles des outils de développement.
Ruff v0.16.0 a changé ce que signifie « par défaut »
Le changement le plus important de Ruff v0.16.0 n’est pas une nouvelle commande. C’est une définition bien plus large de ce que les projets non configurés devraient considérer comme une erreur.
Ruff est un linter et formateur Python écrit en Rust. Un linter analyse le code source pour détecter des erreurs, des motifs suspects et certains problèmes de style, sans exécuter le programme.
Avant cette version, Ruff activait 59 règles lorsqu’un projet ne fournissait aucune sélection explicite de règles de linting. La version 0.16.0 en active 413 dans les mêmes conditions, selon le guide de migration d’Astral.
Cela représente 354 vérifications actives supplémentaires. Une installation Ruff par défaut évalue désormais près de sept fois plus de règles qu’auparavant.
Le catalogue global s’est également enrichi. Ruff prenait en charge 708 règles lorsque ses valeurs par défaut ont été modifiées pour la dernière fois, dans la version 0.1.0. Astral indique que la collection actuelle compte 968 règles.
Les anciennes valeurs par défaut sélectionnaient principalement des sous-ensembles de Pyflakes et pycodestyle. Les projets pouvaient adopter Ruff sans devoir immédiatement faire des choix détaillés parmi ses nombreuses familles de règles intégrées.
Cette base prudente a aidé Ruff à s’intégrer dans des dépôts existants. Elle a aussi creusé un écart grandissant entre ce que l’outil savait détecter et ce qu’il signalait automatiquement.
Astral a comblé une grande partie de cet écart dans la version 0.16.0. Les nouvelles valeurs par défaut s’appuient sur des familles supplémentaires, notamment flake8-bugbear, pyupgrade et la catégorie RUF propre à Ruff.
Flake8-bugbear se concentre sur les bogues probables et les motifs de conception discutables. Pyupgrade identifie les syntaxes et motifs de bibliothèque standard qui peuvent être modernisés pour la version de Python prise en charge par un projet.
La liste des règles par défaut inclut désormais des vérifications susceptibles de révéler des problèmes de syntaxe et des erreurs d’exécution immédiates. Il ne s’agit pas seulement de préférences concernant les espaces ou les conventions de nommage.
Cette distinction explique pourquoi les échecs de CI liés à Ruff peuvent mériter de l’attention. Certains nouveaux signalements révèlent des défauts qui passaient auparavant uniquement parce que Ruff n’activait pas automatiquement le détecteur concerné.
D’autres signalements concerneront la maintenabilité, la modernisation ou des motifs qu’une équipe accepte intentionnellement. Un ensemble de règles par défaut plus vaste ne peut pas connaître les exigences de compatibilité ou les conventions de conception de chaque dépôt.
Ruff v0.16.0 modifie donc deux éléments à la fois. Il accroît la détection automatique de défauts et déplace davantage de décisions de politique vers la première mise à niveau après le 23 juillet.
La version formate également par défaut les blocs de code Python à l’intérieur des fichiers Markdown. Les blocs balisés pris en charge comprennent python, py, python3, py3, pyi et pycon.
Ce comportement importe pour les dépôts contenant de la documentation, des tutoriels ou des notebooks Quarto. Une vérification de formatage peut désormais identifier des modifications en dehors des fichiers .py classiques.
Les notes de version de Ruff décrivent aussi de nouveaux commentaires de suppression et une sortie de diagnostic plus riche. Ces améliorations aident les développeurs à traiter les constats supplémentaires une fois qu’ils apparaissent.
Le changement de périmètre reste l’événement principal de migration. Une commande qui se comportait de manière prévisible la semaine dernière peut aujourd’hui renvoyer un code de sortie non nul sur un code source identique.
Pourquoi les échecs de CI de Simon Willison sont importants
L’expérience de Simon Willison montre comment une mise à jour d’outil de développement peut modifier la politique effective d’un dépôt sans modifier le dépôt lui-même.
Willison est un développeur et auteur indépendant connu pour ses projets autour de Python, des outils de données et de l’IA générative. Il a également co-créé le framework web Django plus tôt dans sa carrière.
Le 25 juillet, Willison a écrit que ses « diverses tâches de CI » avaient commencé à échouer. Il a attribué les échecs aux nouvelles valeurs par défaut de Ruff et à une dépendance de développement "ruff" non verrouillée.
Son récit sur Ruff offre une perspective utilisateur concrète sur cette version. Le code du dépôt n’avait pas nécessairement régressé, mais son environnement de validation avait changé sous ses pieds.
Une tâche de CI, ou d’intégration continue, exécute des vérifications automatisées chaque fois que des développeurs proposent ou fusionnent des modifications. Les équipes dépendent de résultats cohérents pour décider si le code peut être accepté sans risque.
Si une tâche installe ruff sans contrainte de version, le résolveur de paquets peut sélectionner la version disponible la plus récente. Le build suivant peut alors appliquer un comportement qu’aucun responsable n’a explicitement examiné.
Ce mode d’échec est facile à minimiser parce que Ruff est généralement une dépendance de développement. Il n’est normalement pas livré dans l’application qui sert les utilisateurs.
Pourtant, les dépendances de développement déterminent si un logiciel peut progresser dans son pipeline de livraison. Un nouveau code de sortie du linter peut bloquer une pull request, interrompre une publication ou consommer des heures d’investigation.
L’incident révèle également une distinction trompeuse entre dépendances d’exécution et outils. Les paquets d’exécution affectent le comportement du logiciel déployé, tandis que les outils affectent la capacité des développeurs à le déployer.
Les deux peuvent introduire des changements opérationnels. Ils interviennent simplement à différents moments du système.
L’expérience de Willison est particulièrement utile parce que les règles étendues de Ruff fonctionnaient comme prévu. Les échecs ne nécessitaient ni paquet corrompu, ni registre compromis, ni installateur défectueux.
L’outil s’est installé correctement. Il a inspecté le projet correctement selon sa nouvelle politique. La CI a échoué parce que cette politique différait de celle sur laquelle le dépôt s’était implicitement appuyé.
Il s’agit donc d’un problème de reproductibilité. Un build ou une vérification reproductible devrait produire des résultats équivalents à partir du même code source et des mêmes entrées déclarées.
« Latest Ruff » n’est pas une entrée stable. C’est une requête mouvante dont la signification dépend du moment où un gestionnaire de paquets la résout.
Les fichiers de verrouillage et les contraintes exactes peuvent rendre cette entrée explicite. Les services de mise à jour automatisée peuvent ensuite proposer des mises à niveau contrôlées, permettant aux responsables d’examiner les nouveaux diagnostics avant de fusionner le changement de version.
La leçon dépasse Ruff. Les formateurs, vérificateurs de types, lanceurs de tests, générateurs de documentation et analyseurs de sécurité peuvent tous modifier leurs valeurs par défaut entre deux versions.
Un dépôt dont les bibliothèques applicatives sont verrouillées mais dont les outils de développement flottent reste seulement partiellement reproductible. Son comportement en production peut rester fixe, tandis que son chemin vers la production change.
Cette préoccupation est particulièrement pertinente pour les systèmes de codage automatisés. Les agents exécutent souvent les vérifications du dépôt, interprètent leur sortie et modifient le code jusqu’à ce que toutes les étapes de validation passent.
Si les outils à l’origine de ces validations changent de manière inattendue, l’agent fait face à une cible mouvante. Il peut générer des modifications inutiles ou supprimer des signalements sans comprendre pourquoi ils sont apparus.
Les équipes qui construisent une base de connaissances d’ingénierie consultable peuvent conserver les décisions de mise à niveau aux côtés de la configuration et de l’historique de CI. Ce contexte aide les futurs responsables à distinguer une politique intentionnelle d’une dérive accidentelle.
Simon Willison a révélé le nouveau compromis de Ruff
Les valeurs par défaut plus larges de Ruff améliorent la couverture dès la première exécution, mais elles transfèrent le travail de migration aux projets qui considéraient l’absence de configuration comme un contrat stable.
La position d’Astral est simple. Ruff a accumulé des centaines de vérifications tandis que sa sélection par défaut restait figée, laissant des diagnostics sérieux inactifs pour les utilisateurs sans configuration.
L’ancienne sélection remontait à Ruff v0.1.0. Depuis, le catalogue de règles a augmenté de 260, passant de 708 à 968.
Ne laisser que 59 vérifications activées signifiait que l’expérience sans configuration de Ruff ne représentait qu’une portion décroissante de ses capacités. Les nouveaux utilisateurs pouvaient supposer que la valeur par défaut était plus complète qu’elle ne l’était réellement.
La version corrige ce décalage. Les développeurs peuvent désormais découvrir des erreurs de syntaxe, des risques d’exécution, des opportunités de modernisation et des constructions suspectes sans devoir d’abord étudier des centaines de codes de règles.
C’est précieux pour les petits projets. Cela bénéficie aussi aux nouveaux dépôts qui souhaitent une couverture raisonnable avant que leurs responsables ne définissent une politique de linting détaillée.
L’attente opposée est tout aussi raisonnable. Les valeurs par défaut sont souvent considérées comme un comportement du produit, surtout lorsque la documentation présente un outil comme utilisable sans configuration.
Les développeurs qui omettent lint.select peuvent croire qu’ils choisissent la base maintenue par Ruff. Avant la version 0.16.0, ils dépendaient également du maintien de cette base entre les mises à niveau.
Astral a modifié cette base parce que la laisser inchangée avait aussi un coût. Les projets pouvaient réussir Ruff tout en contenant des erreurs que le binaire installé savait déjà détecter.
Le compromis n’oppose donc pas la sécurité à la commodité. Il oppose une protection automatique plus large à la prévisibilité des mises à niveau.
Une valeur par défaut plus étroite réduit les surprises lors des mises à niveau, mais masque davantage de problèmes aux nouveaux utilisateurs. Une valeur par défaut plus large révèle davantage de défauts, mais peut perturber des pipelines établis.
Ruff v0.16.0 choisit une protection renforcée pour la prochaine exécution. Les projets qui souhaitent conserver l’ancien contrat doivent désormais enregistrer explicitement cette préférence.
Astral fournit une configuration de compatibilité directe :
La table exacte peut différer lorsque la configuration se trouve dans un fichier ruff.toml autonome. La décision importante est la sélection explicite des règles, pas le nom du fichier.
Ce réglage restaure les anciennes familles de règles par défaut. Il donne aux équipes une marge de manœuvre sans les obliger à verrouiller indéfiniment la version 0.15.
Toutefois, restaurer l’ancien comportement devrait être une étape de migration, et non un rejet automatique de chaque nouvelle vérification. Certains échecs peuvent révéler des bogues qui méritent d’être corrigés immédiatement.
Une mise à niveau prudente commence par la capture de la sortie complète des diagnostics. Les responsables peuvent ensuite regrouper les constats par code de règle, gravité, sécurité de correction et impact sur la compatibilité.
Les règles qui révèlent des problèmes avérés de syntaxe ou d’exécution méritent la priorité. Les constats de modernisation mécanique peuvent être examinés séparément, de préférence dans des commits ciblés.
Les vérifications orientées politique exigent le jugement de l’équipe. Un motif peut être valide pour des fichiers générés, des conventions de framework, des modules de compatibilité ou des API publiques qui ne peuvent pas être modifiées à la légère.
Ruff prend en charge les ignorances par fichier et les suppressions ciblées dans ces cas. La version 0.16.0 ajoute les commentaires ruff: ignore et ruff: file-ignore au comportement noqa existant.
Une suppression ciblée est généralement plus facile à auditer qu’une exclusion globale. Elle indique où une règle ne convient pas et peut inclure une raison à l’intention des futurs responsables.
Néanmoins, les suppressions peuvent devenir encombrantes lorsque des centaines de violations existantes apparaissent en une fois. Une sélection de règles à l’échelle du projet peut être plus honnête jusqu’à ce que les responsables planifient un nettoyage délibéré.
La bonne réponse dépend de la maturité du dépôt. Un nouveau projet peut adopter immédiatement la base plus large, tandis qu’une grande base de code historique peut nécessiter une adoption progressive.
C’est pourquoi les changements de valeurs par défaut ont un poids inhabituel. Ils appliquent un jugement au niveau du produit à des projets dont les historiques et les contraintes diffèrent radicalement.
Les nouveaux paramètres par défaut ne constituent qu’une partie de la migration
Les équipes qui corrigent la première vague de diagnostics doivent encore examiner le formatage Markdown, la sortie lisible par machine et le comportement des suppressions.
Ruff v0.16.0 intègre les blocs de code Python dans Markdown au champ d’action habituel de son formateur. Cela peut modifier les README, les pages de documentation et les fichiers de publication de type notebook.
Le formateur reconnaît les chaînes d’information Python courantes associées aux blocs de code délimités. Il traite pyi comme du code de stub et pycon comme une session Python interactive.
Les utilisateurs de Quarto peuvent également formater les blocs marqués par des formes telles que {python}. Les projets utilisant des fichiers .qmd peuvent avoir besoin d’un mappage d’extension avant que Ruff ne les inclue.
Cette fonctionnalité aligne les exemples de documentation sur le formateur du code source. Elle réduit le risque que des exemples copiés utilisent un formatage obsolète ou incohérent.
Elle peut aussi provoquer des échecs CI inattendus lorsque ruff format --check n’examinait auparavant que les fichiers source conventionnels. Les responsables de la documentation peuvent ainsi rencontrer pour la première fois les règles Ruff.
Les projets peuvent exclure Markdown avec extend-exclude si nécessaire. Ils peuvent également utiliser des commentaires de suppression du formatage autour de régions sélectionnées.
La décision doit refléter la nature des extraits de code : des instructions exécutables ou du contenu explicatif soigneusement mis en forme. Le formatage automatisé aide plus systématiquement la première catégorie que la seconde.
Le rendu des diagnostics a également changé. Ruff affiche désormais les différences suggérées dans la sortie normale de check et de format --check.
Auparavant, les développeurs pouvaient demander séparément une différence. La nouvelle sortie complète conserve les diagnostics et les modifications proposées ensemble, ce qui facilite l’interprétation d’une vérification échouée.
Pour les fournisseurs CI, format --check prend désormais en charge les formats de sortie utilisés pour les annotations GitHub et GitLab. Un problème de formatage peut apparaître directement sur la ligne concernée dans une revue de code.
Les consommateurs automatisés doivent y prêter davantage attention. Plusieurs champs de la sortie JSON de Ruff peuvent désormais être null au lieu de contenir des emplacements fictifs.
Les champs concernés comprennent filename, location, end_location, ainsi que les emplacements correspondants dans les modifications de correction. Les consommateurs qui supposent que chaque emplacement est un objet ou une chaîne peuvent échouer.
Il s’agit d’un petit changement cassant pour la plupart des utilisateurs. Il est plus important pour les équipes qui analysent la sortie de Ruff afin d’alimenter des tableaux de bord, des bots de revue ou des systèmes qualité personnalisés.
Après la mise à jour, un pipeline peut donc échouer à trois niveaux. Ruff peut détecter une nouvelle violation, le formatage peut s’étendre à un nouveau type de fichier, ou un analyseur de sortie peut rejeter des champs acceptant la valeur nulle.
Considérer chaque échec comme « davantage de règles de lint » risque de masquer la véritable cause. Les mainteneurs doivent identifier quelle couche a changé avant de modifier le code de l’application.
Le nouveau format de suppression mérite lui aussi une révision des règles. Un ruff: ignore[F401] en fin de ligne se comporte comme un noqa ciblé pour ce diagnostic.
Un commentaire précédent peut supprimer les résultats sur la ligne logique suivante. C’est utile pour les en-têtes de fonction sur plusieurs lignes, lorsque le problème signalé ne s’intègre pas proprement à côté du jeton concerné.
Une suppression à l’échelle du fichier est disponible via ruff: file-ignore. Elle peut inclure une raison, ce qui donne aux réviseurs davantage d’informations qu’une exclusion générale non expliquée.
La nouvelle option --add-ignore peut insérer automatiquement une suppression. Cette commodité ne doit pas remplacer l’examen de la question de savoir si le diagnostic sous-jacent représente un véritable défaut.
L’automatisation peut rapidement faire passer la CI au vert en ajoutant des commentaires. Elle ne peut pas décider si un projet doit conserver cette exception pendant des années.
Ruff sépare les corrections considérées comme sûres de celles qui nécessitent une option de correction non sûre. Même une classification comme sûre doit être examinée dans le contexte du code généré, des API publiques et des comportements d’exécution inhabituels.
Le comportement dynamique de Python limite ce que l’analyse statique peut garantir. Les propres conseils sur les corrections de Ruff demandent aux utilisateurs de signaler les cas où une correction sûre endommage le code.
Cette limite n’affaiblit pas l’argument en faveur du linting. Elle renforce la nécessité de distinguer la détection, la modification automatisée et l’approbation humaine.
Les outils de développement non épinglés sont désormais le point de pression
La pression immédiate s’exerce sur les dépôts qui installent Ruff dynamiquement tout en laissant la sélection des règles implicite.
Une version de Ruff entièrement épinglée avec une liste select explicite dispose de deux contrôles stables. L’un fixe l’implémentation de l’outil, tandis que l’autre fixe la politique de lint choisie par le projet.
Une version flottante avec des règles explicites offre une stabilité partielle. Les nouvelles versions de Ruff peuvent encore modifier le comportement de règles individuelles, l’analyse syntaxique, la sortie, le formatage ou la sémantique de configuration.
Une version épinglée sans règles explicites offre également une stabilité partielle. La CI reste cohérente jusqu’à ce que les mainteneurs mettent à jour Ruff, moment où la migration des paramètres par défaut arrive d’un seul coup.
Une version non épinglée sans règles explicites ne dispose d’aucun de ces contrôles. Cette combinaison a créé les conditions à l’origine des échecs de CI Ruff de Simon Willison.
Épingler ne signifie pas figer l’outil indéfiniment. Cela sépare la découverte d’une mise à niveau de son adoption.
Une pull request de mise à jour de dépendance crée une limite de revue visible. La CI peut montrer les nouveaux résultats tandis que la branche principale existante reste reproductible.
Les mainteneurs peuvent alors choisir parmi plusieurs réponses :
Corriger les défauts évidents identifiés par les nouveaux paramètres par défaut.
Accepter les changements mécaniques sûrs dans des commits isolés.
Configurer des exceptions intentionnelles pour des modèles propres au dépôt.
Restaurer la sélection antérieure et planifier une adoption progressive des règles.
Mettre à jour les analyseurs qui ne peuvent pas gérer les emplacements JSON acceptant la valeur nulle.
Exclure les fichiers de documentation qui doivent préserver un formatage manuel.
Ces actions ne doivent pas être mélangées aveuglément. Un unique commit d’autocorrection volumineux peut dissimuler des changements de comportement parmi des milliers de modifications de formatage.
Regrouper le travail par famille de règles permet une revue plus claire. Cela facilite aussi le retour arrière si une règle entre en conflit avec les versions de Python prises en charge par le projet.
La configuration de la version cible est importante lorsque les règles pyupgrade sont actives. Une syntaxe moderne peut être correcte pour une base d’interpréteur et inutilisable pour une autre.
Les équipes doivent vérifier que la cible Python configurée dans Ruff correspond à la réalité du déploiement. Sinon, les conseils de modernisation peuvent dépasser la prise en charge en production.
Le code généré nécessite également un traitement distinct. Reformater ou analyser des fichiers générés crée souvent des changements qui disparaissent à la prochaine exécution du générateur.
Exclure les chemins générés peut être plus juste que de les remplir de commentaires de suppression. La source ou le modèle du générateur est généralement l’endroit approprié pour appliquer les exigences de qualité.
Les monodépôts rencontrent une autre complication. Différents paquets peuvent prendre en charge différentes versions de Python ou maintenir des politiques de lint distinctes.
Un paramètre par défaut au niveau racine peut simplifier les opérations, mais il peut aussi imposer un calendrier de migration unique à des composants sans rapport. Une configuration par paquet peut mieux refléter la responsabilité de chacun.
La principale question sceptique est de savoir si 413 règles constituent une base de référence largement acceptable. Astral a documenté la sélection, mais l’adoption dans le monde réel mettra à l’épreuve son taux de faux positifs et sa charge de compatibilité.
Les échecs de Willison fournissent un premier signal, pas une enquête représentative. Ils montrent que des perturbations sont possibles, non que la plupart des utilisateurs de Ruff les connaîtront.
Les projets qui utilisent déjà un select ou un extend-select explicite peuvent réagir différemment. Leur ensemble de règles effectif dépend de l’interaction entre cette configuration et la nouvelle base de référence.
Astral indique que ce changement peut encore faire apparaître des règles utiles pour les utilisateurs configurés. Chaque équipe devrait inspecter la sélection résolue au lieu de supposer que la configuration rend cette version sans importance.
Il existe aussi un risque de surcorrection. Épingler Ruff tout en laissant flotter tous les autres outils de développement ne résout qu’un cas visible d’un problème plus large.
Les équipes devraient inventorier les formateurs, vérificateurs de types, outils de test, hooks pre-commit et générateurs de documentation. Chacun d’eux peut transformer un build propre en échec.
La politique durable est simple : versionner l’environnement qui décide si le code peut être livré. Cette politique inclut les outils que les développeurs classent traditionnellement comme facultatifs.
Ce que Simon Willison et les utilisateurs de Ruff devraient surveiller ensuite
Les trois prochains signaux montreront si la base de référence élargie de Ruff devient une politique acceptée ou une source récurrente de frictions dans la CI.
Le premier signal est l’activité des versions correctives d’Astral pendant les semaines suivant la version 0.16.0. Des ajustements rapides des règles par défaut indiqueraient que des dépôts réels ont révélé d’importants problèmes de compatibilité.
Des corrections propres à certaines règles n’invalideraient pas la base de référence élargie. Elles montreraient qu’une sélection beaucoup plus vaste doit être ajustée sous des charges de travail de production.
À l’inverse, une activité de retour arrière limitée renforcerait l’argument d’Astral selon lequel la plupart des nouveaux diagnostics sont exploitables. Elle encouragerait également davantage de projets à accepter les paramètres par défaut au lieu de restaurer l’ensemble précédent.
Le deuxième signal est le comportement de configuration dans les dépôts Python publics. Les mainteneurs révéleront leur jugement à travers leurs commits, même sans enquêtes formelles.
Une vague de sélections explicites des anciens paramètres par défaut suggérerait que les équipes privilégient le contrôle de la migration à une couverture immédiate. Des corrections généralisées et le maintien des paramètres par défaut indiqueraient une adoption réussie.
Les dépôts les plus instructifs documenteront leur raisonnement. Une simple liste d’ignorances montre ce qui a changé, tandis qu’une note de migration explique pourquoi une équipe a accepté ou rejeté chaque famille de règles.
Le troisième signal est de savoir si les modèles de paquets et les exemples CI commencent à épingler Ruff. Les générateurs de nouveaux projets façonnent souvent les habitudes plus efficacement que les avertissements rétrospectifs.
Si les modèles adoptent des contraintes de version et des workflows de mise à jour automatisés, l’expérience de Willison aura influencé les pratiques au-delà de cette seule version.
Si les exemples continuent d’installer un ruff non contraint, les futurs changements de paramètres par défaut ou de formateur pourront reproduire la même surprise. Le nombre précis de règles sera différent, mais le problème de reproductibilité demeurera.
Les développeurs n’ont pas besoin d’attendre ces signaux avant d’agir. Ils peuvent exécuter la nouvelle version sur une branche, conserver la sortie et décider quels résultats améliorent leur code.
Une commande de test utile est :
Spécifier la version rend l’expérience reproductible. Exécuter ruff format --check . séparément aide à distinguer les échecs de lint des changements de Markdown ou de formatage du code source.
Ne commencez pas par ajouter des ignorances globales. Identifiez d’abord quelles règles ont trouvé des bugs certains, lesquelles suggèrent une modernisation et lesquelles encodent une politique discutable.
Consignez ensuite la décision dans la configuration et le contrôle de version. Un badge CI vert a moins de valeur lorsque personne ne sait quel contrat de qualité l’a produit.
Ruff v0.16.0 illustre l’avantage et le coût de paramètres par défaut actifs. L’outil détecte davantage sans configuration, mais l’absence de configuration ne signifie plus un comportement inchangé.
L’expérience de Simon Willison transforme ce compromis abstrait en une question d’ingénierie immédiate : votre dépôt déclare-t-il les outils et les politiques qui contrôlent ses livraisons ?
Exécutez la version épinglée sur une branche, examinez chaque nouvelle famille de règles et rendez la base de référence explicite. Le prochain build propre devrait refléter une décision revue, non la date à laquelle la CI a installé Ruff.


