Aller au contenu

Décisions d'architecture (ADR)

Ce journal consigne les décisions structurantes du projet : les choix qui engagent l'architecture ou le domaine sur la durée, et surtout pourquoi ils ont été faits. Une décision oubliée se re-débat ; écrite, elle se relit.

Ce qu'est (et n'est pas) une ADR

Une ADR (Architecture Decision Record) décrit une décision : son contexte, ce qui a été tranché, ses conséquences, et les pistes écartées. Elle est immuable une fois acceptée : on ne la réécrit pas, on en écrit une nouvelle qui la remplace (statut « Remplacée par ADR NNNN »).

Une ADR n'est pas :

  • un compte rendu de chantier (ça, c'est le bilan, déposé dans le corps de l'EPIC à sa clôture) ;
  • une description de l'implémentation (ça, c'est le code et sa Javadoc, ou Patterns et principes) ;
  • une note de rappel opérationnelle (« attention au piège X ») : ces notes vivent ailleurs.

On écrit une ADR quand un chantier prend une décision qu'un développeur futur pourrait raisonnablement remettre en cause faute d'en connaître les raisons : « pourquoi ne pas simplement comparer l'empreinte ? », « pourquoi une fenêtre courte plutôt qu'une moyenne ? ».

Comment une ADR est vérifiée

Une décision qui n'est jamais reconfrontée au code se re-débat de la même façon qu'une décision oubliée. Chaque ADR déclare donc, dans son en-tête, comment on sait si elle est tenue :

  • certaine : un invariant qui se prouve. Un test (DecisionsRespecteesTest) ou un script déterministe échoue en CI si la règle est violée. L'en-tête nomme le test ou le script.
  • probable, pas de preuve possible, mais un script (scripts/adr/NNNN-*.py) liste des suspects qu'un humain trie. Le signal utile n'est pas « zéro » mais « aucun nouveau » : un cliquet, inscrit dans l'en-tête, borne la dette et fait rougir la CI si un cas s'ajoute.
  • humaine, aucun invariant mécanique. Le motif dit pourquoi. Une décision de méthode ou de comportement ne se prouve pas par un scan, et un test creux serait pire que rien. Quand un pattern reconnaissable existe malgré tout, une loupe (scripts/adr/loupe-NNNN-*.py) surface une surface de revue pour la passe humaine : elle ne bloque jamais, elle aide à ne rien oublier.

Un garde-fou (DocumentationAJourTest) exige que chaque ADR déclare son niveau, et que le test, le script ou la loupe nommé existe vraiment : une ADR ne peut pas annoncer une garde disparue.

Le rapport hebdomadaire (scripts/adr/rapport.py, workflow rapport-adr) agrège les cliquets et les loupes pour mesurer l'écart d'une semaine sur l'autre, et resserre automatiquement, par une PR, les cliquets dont la réalité est passée sous la marge. Resserrer est mécanique ; desserrer reste un geste humain.

Quand en écrire une

À la passe 11 de la clôture d'un chantier : chaque décision structurante prise pendant le chantier donne une ADR, et la passe 12 (bilan) s'y réfère plutôt que de dupliquer le raisonnement.

Pas en passe 3, et c'est un changement (#3505). Les passes 4 à 9 produisent des décisions : la revue visuelle en particulier découvre ce qu'aucun test ne dit. Écrire les ADR en début de clôture demandait donc l'impossible, et la mesure le confirme - les cinq ADR du chantier #3151 (3406, 3439, 3450, 3451, 3483) portent toutes la mention « suite de », c'est-à-dire qu'aucune n'est née là où le cycle la demandait. Les ADR antérieures qui déclarent « Rédigée à la clôture (passe 3) » sont datées : elles disent vrai du cycle en vigueur ce jour-là.

Symétriquement, la passe 0 relit les ADR existantes avant que la clôture ne commence : un chantier a le droit de dépasser une décision, pas de le faire en silence.

Le numéro d'une ADR est celui de son chantier

Le numéro d'une ADR est le numéro de l'issue du chantier qui l'a décidée (l'EPIC quand il y en a un). Il ne se choisit pas : il est déjà attribué quand on s'assoit pour écrire.

Ce n'était pas le cas avant : le numéro était pris au compteur, « le premier libre dans le dossier ». Ce compteur était une ressource partagée sans verrou, et deux chantiers parallèles prenaient régulièrement le même. Sur les quatre dernières ADR numérotées ainsi, trois ont dû être renumérotées, et la dernière collision a coûté bien plus que le renommage d'un fichier (#1881). Réserver le numéro à l'avance a été essayé, et démenti en trente minutes ; un script de balayage des branches a été écrit, et sa sortie s'est survolée. Un numéro d'issue, lui, ne peut pas entrer en collision : personne ne le choisit.

Comme les numéros d'issue croissent avec le temps, le dossier reste dans l'ordre chronologique.

Le compteur est clos à 0048

Les ADR 0001 à 0048 gardent leur numéro de compteur : elles ne bougent pas. Les renuméroter toucherait 288 citations dans 154 fichiers, dont 93 fichiers Java, et surtout les discussions GitHub déjà closes, qu'on ne peut pas réécrire. 0049 n'existera jamais : une ADR numérotée sous 1000 est une ADR d'avant la bascule.

Deux trous subsistent dans cette série, 0029 et 0030 : ce sont les numéros qu'une résolution de collision a libérés. Ils restent vides, parce que les combler ferait pointer vers un numéro qui a déjà voulu dire autre chose dans une PR et une discussion.

DocumentationAJourTest garde la règle : numéros uniques, en-tête d'accord avec le nom de fichier, ligne de journal et entrée de nav pour chaque ADR, et pour toute ADR postérieure à la bascule, un numéro qui figure bien dans sa ligne « Chantier ».

Format

Copier le squelette suivant dans NNNN-titre-court.md, où NNNN est le numéro de l'issue du chantier :

# ADR NNNN : La décision, formulée comme une affirmation

- **Statut** : Accepté - AAAA-MM-JJ
- **Chantier** : EPIC #NNNN (titre court)

## Contexte
Les forces en présence, le problème, ce qui contraint.

## Décision
Ce qui est tranché, à l'impératif.

## Conséquences
Ce que cela implique, en bien comme en moins bien.

## Alternatives écartées
Les autres pistes, et pourquoi elles ont perdu.

Journal

Les premières entrées sont rétroactives : elles consignent, à partir des bilans de chantier, des décisions structurantes prises avant l'ouverture du journal.

# Décision Chantier
0001 Identité d'un passage reconstruit : régénération structurelle, l'acoustique en indice #1653
0002 Détection acoustique par énergie de pointe, pas par moyenne globale #1653
0003 Une feature est un plugin désactivable ; dépendances entre features = ports optionnels #923, #1057
0004 Pas de cycle entre features : les ponts passent par un port dans commun ArchUnit
0005 Réactivation par cascade de preuves ; « archivé » est un état observé #1297
0006 Le dépôt par ZIP est le mode par défaut ; la perte de l'audio serveur est assumée #984, #1297
0007 Les retours de l'API sont un type scellé ReponseApi #1284
0008 Aucun échec silencieux ; la sévérité de journalisation se décide à l'émission #1523
0009 La nuit (soir → matin, bornée à midi) est l'unité de traitement #664, #1696
0010 Les dialogues bloquants (confirmation, compte rendu) sont des ports injectables #789, #1405
0011 La transformation audio est pilotée par le log (fréquence réelle), pas par l'en-tête import Tadarida
0012 L'audit rend tout écart visible, mais un état normal ne crie pas #1154
0013 Un passage local est ancré à sa participation serveur (lien explicite) #720
0014 Toute capacité métier est offerte aussi en CLI (parité CLI ↔ IHM) #619, #1304
0015 Cartes SD de recette : specs déclaratives + générateur déterministe #1749, #1769
0016 La synchro rapatrie les nuits en squelettes, hydratés à la demande EPIC #1662
0017 L'origine d'un point (rapatrié vs manuel) est un état porté, pas déduit #1738
0018 La synchro rapatrie aussi l'identité de la nuit (amende 0016) #1814
0019 L'ancrage s'acquiert quand il sert, pas à un moment décrété (amende 0016) #1838
0020 Écrire sur la plateforme : ne rien inventer, ne rien effacer, parler la langue du lecteur #1828, #1844
0021 Le double-clic est le miroir de l'action principale, et il rend compte quand il n'aboutit pas EPIC #1792
0022 Le verbe d'un geste dit le sens réel de l'échange #1855, #1866
0023 Rendre compte se fait au bandeau ; le modal est réservé à l'irréversible EPIC #1870
0024 Les heures d'une nuit viennent de ses preuves ; de l'utilisateur seulement à défaut #1860, #1878, #1892
0025 Une capture passe par le code de production, elle ne le reconstruit pas #1468, #1865
0026 Le nommage des tranches est une étape du pipeline, pas un détail de la découpe EPIC #1944
0027 Une attente porte toujours un nom, et c'est l'étape qui va attendre qui le pose #1931, #1951, #1959
0028 Un état n'est pas un compte rendu, et ils ne partagent pas de canal EPIC #1870
0031 Un retour d'opération n'est pas un compte rendu : le mot « compte rendu » se libère pour l'extensible EPIC #1990
0032 Le plan de dépôt précède l'écriture des archives EPIC #1991
0033 Une fenêtre bornée, pas un pipeline unitaire, et deux seuils disque au lieu d'un EPIC #1991
0034 La forme du dépôt se choisit, elle ne se déduit pas de la place disponible EPIC #1991
0035 Un pictogramme d'IHM est une icône ; un caractère dans une phrase reste un caractère #1933, #700
0036 La copie des enregistrements bruts est une option de ré-analyse, pas un défaut EPIC #2061
0037 Une barre d'actions plie ; et tout texte coupé n'est pas une barre qui ne plie pas #2012, #1641, #1873
0038 L'échelle de sévérité compte quatre niveaux, et son ordre de déclaration porte la sémantique (amendée : elle en ignorait une seconde) #1990, #2004, #2159
0039 Une barre de statut dit où l'on en est, pas si c'est bien ou mal #1990, #2004
0040 Le sujet d'un commit est une syntaxe, pas une phrase française : le : ne prend pas d'espace EPIC #2104, #2105
0041 Un check requis ne gouverne pas les PR, il gouverne la branche : le contrôle du titre reste informatif EPIC #2104, #2106
0042 Un aperçu qui ment est refusé, et l'exception se déclare dans la vue #2049, #1641, #1873, #1579
0043 La mesure fait foi en CI, pas sur le poste (amende 0037) #1873, #2129
0044 Le mécanisme de parallélisme se choisit sur la nature de l'attente, la borne se chiffre sur autre chose #2040 (EPIC #2116)
0045 L'UpgradeCode et le scope de l'installeur Windows sont des constantes d'identité, figées avant la première soumission winget EPIC #2104, #2110, #2213
0046 Une classe CSS a une seule feuille pour maison ; un cliquet refuse tout nom en double #1974
0047 L'identité de distribution est le projet Echonuit : produit « VigieChiro Companion », app-id fr.echonuit, éditeur Echonuit (fait évoluer #2108) #2240, #2213, #2111
0048 L'utilisateur possède ses fichiers : l'application observe la disponibilité de l'audio au lieu de l'archiver, et peut le référencer en place (reformule #1038) #1038, #2028, EPIC #1297
1038 La seule configuration qui vive hors de la base est celle qui dit où la base se trouve : fichier d'amorçage %APPDATA% / $XDG_CONFIG_HOME, lu avant tout le reste (absorbe #2187) #1038, #2187 (EPIC #2258)
1874 La CLI rend l'URL des fiches sans ouvrir de navigateur ni interroger la plateforme #5505, lot #1874
1881 Le numéro d'une ADR est celui de son chantier, pas un compteur : le compteur est clos à 0048 #1881
2112 On ne signe pas les installeurs : le produit s'arrête à la notification de mise à jour, la limite est écrite là où l'utilisateur la rencontre, et les deux coûts annuels sont dans l'ADR pour que la question se repose sur un prix #2112 (EPIC #2104)
2213 Un dispositif qui ne peut pas conclure rapporte ce qu'il a vu ; un geste manuel ne réussit pas en silence ; un épinglage se mesure aussi en âge #2213 (fait évoluer ADR 3501)
2465 Une ADR déclare comment elle est vérifiée (certaine / probable / humaine) ; cliquets dans l'en-tête, loupes, rapport hebdomadaire EPIC #2465
2525 Un fait booléen porté par une entité centrale (construite en des dizaines d'endroits) vit dans une table latérale de présence, pas dans une colonne du record : V10 passage_equipment, V34 passage_opportuniste, V35 site_tiers #2525 (EPIC #2349)
2349 Une dérivation automatique (ici depuis l'API VigieChiro) ajoute mais ne retranche jamais : démarquer effacerait en silence les saisies manuelles des cas que la source externe ne connaît pas EPIC #2349 (décidé dans #2525)
2493 Une modale qui révèle un bandeau après ouverture appelle Modales.suivreLaCroissance, sinon les boutons du bas débordent #2493 (issu de #2486, #1534)
2433 Un dossier de transformés déjà présents s'importe par référence, sans brut : original placeholder, empreinte calculée à l'inscription (complète #2255) #2433 (EPIC #2258)
2385 Les chiffres et les relations de la documentation sont adossés au code par des gardes (balises d'inventaire, réciprocité des amendements, liens racine) ; étendu par #2386, clôt l'EPIC #2367 #2385, #2386, EPIC #2367
2358 Un compte rendu d opération lourde se rend en proportions, et ses règles tiennent par le type : largeurs liées aux quantités, ventilation exhaustive refusée à la construction, action suivante en pied ; chaque mention porte sa sévérité #2358 (lot 2 de l EPIC #2350)
2354 Le réessai réseau est gradué par profil (premier plan / arrière-plan), jamais aveugle (jamais un 4xx, estReessayable sur ReponseApi), toujours jitteré, Retry-After faisant autorité ; l'idempotence reste arbitrée à l'appel #2354 (lot 1 de l'EPIC #2350)
2352 La nuit biologique bascule à midi et se lit sur un axe fixe 18 h → 8 h, la fenêtre coucher/lever réelle étant matérialisée quand elle est calculable ; la même règle date les lignes de l'export #2352 (lot 2 de l'EPIC #2348)
2348 Un export d'image reconstruit ce qu'il exporte hors écran (jamais snapshot() du nœud affiché, dont l'échec est silencieux) et l'estampille de son contexte : identité, réglages, filtres en clair, provenance EPIC #2348
2554 La synchro amène chaque nuit à un niveau de complétude (structure → identité → contenu), le repli donnees est réservé au geste désigné, l'hydratation se fait en place sur le chemin de la réactivation, et le compte rendu ventile par cause sans jamais l'affirmer sans l'avoir constatée ; amende #0016 EPIC #2554
2357 Un lot applique N fois un geste qui existe déjà et n ajoute que ce qui relève du nombre : moteur séquentiel (le plafond de parallélisme reste celui d un passage), éligibilité locale annoncée avant de partir, annulation entre deux passages, échec qui n arrête pas le lot, et aucune option destructrice exposée en lot #2357 (lot 3 de l EPIC #2349)
2635 Un refus du modèle énonce ce qui manque (Besoin : connexion, fonctionnalité) sans nommer d'écran ni de commande ; chaque surface ajoute son geste (menu pour l'application, commande pour la ligne de commande) #2635 (suite de #2554)
2802 Un texte venu d'ailleurs (message d'exception, réponse serveur) se borne à sa porte d'entrée, qui est aussi le seul endroit où on peut l'enrichir ; ce que nous écrivons reste entier #2802 (suites de #2350)
2614 Une nuit opportuniste se filtre dans les vues agrégées au lieu d'être exclue d'office ; l'absence de marquage vaut « Protocole », et la lecture du marquage passe par un port distinct de l'écriture #2614 (suite du lot 2 de l'EPIC #2348)
2353 L'enjeu de conservation est le booléen que le PNA Chiroptères 2016-2025 désigne (19 espèces prioritaires, 17 présentes au référentiel Tadarida), joint par nom latin et stocké en table latérale ; rien n'est marqué par déduction taxonomique #2353 (lot 3 de l'EPIC #2348)
2351 Un nombre de contacts se lit contre le référentiel ACTICHIRO cité (source recopiée à l'écran et dans chaque export) ; le repli retient la première déclinaison fiable, pas la plus fine ; la saison et la région se déduisent, le milieu se choisit #2351 (lot 1 de l'EPIC #2348)
2581 Un état reste observé tant qu'il ne sert qu'à décider et se déclare quand il doit être montré : StatutWorkflow.RECUPERE vit hors de la file linéaire, la migration V37 rejoue le critère observé sans en inventer un second, et la valeur est déclarée en dernier pour ne pas décaler les comparaisons par ordinal() #2581 (lot 1, #2772)
2791 La commune d'un point se dérive une fois de son GPS (API Géo, best-effort, rattrapable) et vit en table latérale point_commune ; elle s'attache au point, jamais au carré (chevauchements) ; département et région se dérivent du code INSEE via la table unique RegionsFrancaises (ADR 2351 généralisée) #2791 (lot 0 de l'EPIC #2790)
2792 L'archive d'export « observations + sons » est un contrat : observations.csv à la racine (octet-identique à l'export CSV seul), sons dédupliqués sous sons/<dossier-session>/ (suffixe -s<id> seulement en collision), son introuvable compté jamais bloquant, pas de manifeste séparé (le CSV fait foi) #2792 (lot A de l'EPIC #2790)
3006 Le groupe api de la CLI est borné : lecture seule, pièges connus traduits en refus avant émission (max_results > 100, where= ignoré), échappatoire lectureBrute réservée au groupe par une règle d'architecture, sous-commandes volontairement discrètes en contrepartie de quoi le groupe ne grossit pas sans décision. Et : ce qui teste l'API se passe de notre client, ce qui teste notre client passe par lui #3006 (lot 4 de l'EPIC #2999)
2843 La convention typographique (pas de tiret cadratin) se tient par un cliquet sur les sources Java, pas par un nettoyage d un seul tenant ; la documentation Markdown est hors perimetre a dessein, deux populations dans un seul nombre pouvant se masquer #2843, suite de #2813 (cloture du chantier #2348)
2867 Une dette qu'on migre au fil de l'eau est épinglée dans une liste explicite qui ne peut que rétrécir (un « cliquet ») : les deux sens de variation sont rouges et le message les distingue, la destination de la migration est exclue dès la pose, pas de court-circuit sur un objet « déjà traité », et usage n'est pas mention #2867 (axe 5 du chantier #1771)
2941 Les cinq décisions prises en appliquant le cliquet typographique, avec les incidents qui les ont déclenchées : la mesure compte la prose, une zone se promeut dans la tranche qui l'amène à zéro, une zone qui ne balaie rien lève, une forme citée se taille au plus juste, la racine se balaie sans descendre (amende 2843) #2365
2951 Une exclusion de détecteur nomme le dispositif qui reprend l'objet écarté : une partition ne fait disparaître aucun objet des deux comptes, un court-circuit si ; deux exclusions de natures différentes ne partagent pas un if #2951 (chantier #1771), amende #2867
3018 Un outil (capture, banc, graine) compose son injecteur depuis RacineInjecteur.modules() et s'adapte par Modules.override, jamais en retirant de la liste : un injecteur amputé et une fonctionnalité désactivée produisent le même écran, donc la règle ne peut pas tenir par la vigilance. Une substitution reste acceptable seulement si elle est étroite et qu'elle est le sujet de l'aperçu #3018, finit #2669 et #333
3048 Face à un état dégradé, l'IHM peut retirer (un écran se relit d'un coup), mais une sortie machine dit : la structure reste stable, un champ nomme l'état, et ce qui n'a pas pu être établi cesse d'être affirmé (pas de comparaison inventée, pas de citation d'une source non chargée). Retirer une colonne de CSV casse ce que le retrait prétend protéger (précise 0014) #3048, suites de #3018
3068 Le déterminisme des captures porte sur ce que le produit rend ; une entrée extérieure au dépôt y échappe. On garde donc les tuiles OpenStreetMap et leur variabilité mesurée (médiane 1,22 %, max 2,51 %, révisé le 2026-08-05) : ces captures valent parce qu'elles montrent une vraie carte. Corollaire, restreint le 2026-08-06 : un diff est un signal partout sauf dans le rectangle de la carte, qu'un masque exclut de la comparaison (#3381) #3068, suites de #3018
3053 Quand un outil de capture désigne un contrôle par son libellé, il exige de le trouver et lève en nommant les libellés présents : l'abstention (findFirst().ifPresent) produit l'aperçu sans le geste, publié sous une légende affirmant le contraire. Repli de l'ADR 0025 §4 là où la constante ne peut pas être partagée (catalogues package-private) #3053, clôture des suites de #2967
2727 Une restauration complète vérifie la sauvegarde en place (pas de zone temporaire : restaurer 40 Go par-dessus 40 Go demanderait 80 Go libres) et replace un dossier à son emplacement d'origine s'il existe encore, sinon dans le dossier de travail. Les six tables à chemin suivent, pas seulement root_path : ne réécrire que la racine donne une base qui paraît juste et une application qui ne trouve plus rien #2727, lot 1 de #2720
2729 Un script de migration publié ne se modifie plus : son empreinte SHA-256 est inscrite avec sa version, et une dérive est un refus au démarrage, pas un avertissement. L'empreinte porte sur les instructions, pas sur le texte du fichier : un refus faux use plus vite la confiance qu'une alerte manquée #2729, lot 1 de #2720
2731 Un seul processus écrit dans un dossier de travail, garanti par un verrou de fichier système (que l'OS relâche à la mort du processus) et non par un fichier de PID (dont la validité n'a pas de réponse portable). La seconde instance graphique est refusée et non basculée en lecture seule : ce mode n'existe nulle part et le livrer à moitié serait pire. La CLI ne verrouille que ses opérations exclusives, pour ne pas casser l'usage scriptable #2731, lot 1 de #2720
2732 La décompression est bornée par deux gardes - l'inventaire annoncé avant le premier octet, les octets réellement écrits pendant la copie - qui tiennent ensemble une garantie unique : on n'écrit jamais plus que ce qui a été déclaré, et on n'accepte jamais une déclaration qui ne tient pas. Pas de plafond de taux de compression : une carte SD de recette se décompresse ≈ 140 fois et un enregistrement silencieux bien plus, or l'audio silencieux et une bombe sont les mêmes octets #2732, lot 2 de #2720
2736 Le jeton reste un fichier 600 et les sauvegardes ne sont pas chiffrées : un coffre système protégerait le mauvais actif, puisque les localisations d'espèces protégées vivent en clair dans la base du même dossier, et une clé de chiffrement n'a pas de bon endroit où vivre (dérivée d'un mot de passe, elle fait de la sauvegarde un piège au moment où elle sert). Le clair est assumé et annoncé : l'archive dit ce qu'elle emporte #2736, lot 2 de #2720
2861 Une donnee du point (sa commune) ne s affiche que sur une table dont une ligne porte un point : sur un agregat, un carre de 2 km chevauchant deux communes ferait mentir la cellule. Chaque table garde par ailleurs sa marque d absence (vide ou tiret), et la revue audio la traite comme du contexte, masque sur un passage unique #2861, lot 3 du chantier #3151
3082 Un critère de commande qui désigne (un lieu, une nuit, un taxon) refuse en nommant ce qui est présent : l'ensemble vide y est une faute de frappe. Un critère qui qualifie (une nature, un enjeu) rend vide sans refuser : c'est une réponse. Le test : « cette valeur peut-elle être fausse ? » #3082, clôture des suites de #2967
3092 Un filtre ne touche que la liste affichée : le résumé, le verdict et le code de sortie continuent de juger l'ensemble. audit-coherence --gravite INFO rend 1 si le workspace porte une erreur, sinon un script d'intégration conclurait que tout va bien. Corollaire : un filtre qui ne retient rien le dit, au lieu de laisser un en-tête suivi du vide #3092, passe 2 de la clôture
3093 Les trois chemins qui remettent des filtres (vue mémorisée, transport entre écrans, mémoire de session) rendent compte de ce qu'ils n'ont pas su replacer, et distinguent une valeur disparue (les données) d'un critère absent (l'écran) : les deux n'appellent pas la même réaction. Un écran gagne son bandeau en même temps que sa barre #3093, palier 1 du chantier #3092
3096 Une clé de critère sérialise les vues enregistrées : elle vit à un seul endroit quand elle est partagée (ClesCriteres), reste chez son écran quand elle lui est propre, et se renomme sans migration via nomsHerites. Les libellés sont une préoccupation distincte, qui doit couvrir jusqu'aux clés qu'aucun écran local n'offre #3096, palier 3 du chantier #3092
3095 Le domaine d'une puce se calcule sur les lignes que les autres critères laissent passer (Filtres.saufLui), sinon elle s'auto-effondre sur la valeur déjà retenue. Une valeur cochée devenue impossible est conservée et marquée, jamais retirée en silence. Et une facette cascade là où un sélecteur ne cascade pas : restreindre aide, mais retirer du menu ce vers quoi on veut naviguer gêne #3095, palier 2 du chantier #3092
3099 Deux puces de Sons & validation filtrent dès leur ajout, contre la règle « rien de coché n'écarte rien ». C'est acceptable parce qu'elles annoncent leur valeur : la capture montre « Taxon parent | Chiroptères » lisible sans déplier. Un critère qui filtrerait d'emblée sans le montrer serait, lui, un défaut #3099, palier 4 du chantier #3092
3151 Ce qu un ecran offre de chercher ou de filtrer, il doit pouvoir le montrer ; l inverse est libre. Montrer sans offrir laisse une information a lire, offrir sans montrer laisse un resultat a croire. Quatre applications ont appris que la surface n est pas forcement une colonne (les entrees d une puce en sont une), que le chemin compte - une puce ne sert pas la recherche libre, et c est ce qui a fait ecarter deux ecrans A TORT - et qu une table pleine garde sa colonne masquee au selecteur #3151
3157 Le domaine a trois niveaux géographiques, pas quatre : monitoring_site porte le numéro de carré et son nom convivial sur la même ligne. Le carré s'offre donc dans une seule entrée, « 640380 · Vallon », dont le préfixe identifie et le suffixe ne fait que nommer. Deux carrés homonymes s'en trouvent distingués, et #3145 cesse d'être une question #3157, lot 1 du chantier #3151
3158 Une vue mémorise le texte coché : requalifier une entrée le rend introuvable. Le socle demande au critère ce que la valeur désigne, chaque dimension déclarant où vivait son ancienne écriture (en tête pour le carré, en queue pour le point) - chercher un segment n'importe où ne rattrape jamais un carré, le point étant qualifié par lui. Deux candidates ne cochent rien #3158, lot 1 du chantier #3151
3168 Le departement d un point se lit deux fois (par son carre, par sa commune) et les deux lectures peuvent se contredire. L audit montre l ecart sans le trier : il n a ni la geometrie du carre ni la distance au bord, et un tri approximatif ferait croire les faux positifs deja ecartes. La severite INFO est un contrat de sortie - un AVERTISSEMENT ferait rendre 1 a audit-coherence sur le cas normal. Et deux ecritures qu on ne sait pas departager (Corse 20/2A, outre-mer 97/971) ne divergent pas : la comparaison s abstient #3168, lot 4 du chantier #3151
3361 base.css nommait trois polices dont aucune n est installee, ni sur un poste ni sur le runner : les deux retombaient sur sans-serif, un ALIAS que chaque systeme resout a sa facon. Le produit heritait donc de la typographie de la machine - trois allers-retours avec le garde de troncature, et surtout deux utilisateurs voyant des rendus differents sans qu aucun garde ne le voie. Noto Sans est embarquee (OFL 1.1, 1 Mo), chargee aux DEUX points d entree - l application et les 41 outils de capture #3361, suite de #3151
3374 Embarquer une police ne la selectionne pas : c est base.css qui la demande, et seuls deux FXML la declaraient. Sur onze scenes, dix naissaient d un new Scene(vue) sans elle et rendaient avec la police par defaut de JavaFX - differente de celle de la fenetre qui les porte, et differente d une machine a l autre. Un point de passage unique (Habillage) sert les fenetres comme les captures, de sorte qu un apercu montre l ecran de l utilisateur par CONSTRUCTION. Mesure : zero pixel d ecart CI/local sur l ecran qui porte la feuille, 28,8 % sur ceux qui ne la portent pas - il n y avait donc rien a regler cote anticrenelage #3374, suite de #3361
3350 --lieu ecartait le point au motif qu un code seul (« A1 ») designe autant de lieux qu il y a de carres et qu une ligne de commande n a pas de liste sous les yeux. L inventaire a dementi la premisse : les cinq surfaces qui offrent --lieu portent le carre ET le point. La regle devient c est la sortie qui desambigue, pas le critere qui se restreint, dont le corollaire porte la these de l ADR 3151 a la ligne de commande - lister-observations filtrait sur un lieu qu elle taisait entierement. Et ce que le refus enumere n est pas ce qu il accepte : y ajouter les points faisait passer la liste de 15 a 31 entrees pour n en montrer que six sous la borne #3350, suite de #3151
3348 La recherche libre de Sons & validation interroge le texte du commentaire, que la table ne montrait que par une icone de 50 px. L infobulle en donnait deja le contenu ENTIER - la piste « un extrait au survol » etait donc deja livree - mais ligne a ligne : elle rend le contenu atteignable, jamais balayable, or apres une recherche on trie du regard. Une colonne « Commentaire (texte) » masquee par defaut, contre son indicateur. La regle du chantier se formule un cran plus fin : ce qu un ecran offre de chercher, il doit pouvoir le montrer DE FACON BALAYABLE #3348, suite de #3151
3389 Embarquer une police ne suffit pas si elle ne couvre pas ce qu on affiche : un caractere absent part en repli vers une police du systeme, et deux machines ne replient pas sur la meme - sans que rien ne le signale. Huit caracteres etaient dans ce cas (→ ⚠ ☰ ≥ ≤ ▸ ← −) ; ils se remplacent, on n embarque pas deux fontes de plus pour huit glyphes. Le perimetre s arrete a ce que JavaFX rend : une sortie terminal a la police de sa console. Trois cadenas emoji, deja interdits par l ADR 0035, sont tombes au passage - un cliquet trouve ce qu une relecture ne cherche pas #3389, suite de #3361
3412 L ADR 3361 a cherche des familles nommees, et n a donc pas vu les deux feuilles qui demandaient leur police par l alias directement (monospace). Un alias n est pas une police : c est une demande que chaque systeme resout a sa facon, et le defaut se rejouait a l identique sur les chemins de fichiers. Noto Sans Mono est embarquee et nommee, l alias reste en queue comme filet. Le garde porte sur l alias, pas sur les deux cas trouves : corriger deux occurrences aurait laisse arriver la troisieme #3412, suite de #3361
3417 Le produit ne depend plus de la machine pour peindre, il en depend encore pour MESURER : ChoiceBoxSkin calcule sa largeur avec un noeud de texte hors du graphe de scene, donc sans feuille de style, donc avec Font.getDefault() - 82 px en CI contre 78 sur un poste, et le graphe en dessous herite du decalage. Refaire une passe CSS n y change rien, teste. La police systeme du RUNNER est donc alignee sur celle que l application declare : il n existe pas UN rendu utilisateur, et la seule reference non arbitraire est celle ou mesure et peinture coincident #3417, suite de #3389
3222 Une entrée externe se lit sous plafond, et le plafond vient d'une mesure sur une carte réelle : le journal du capteur pèse 1,9 Ko pour une nuit (il consigne des événements de session, pas un enregistrement par fichier), le plus gros corps rendu par la plateforme 446 Kio. Deux gardes comme à l'extraction - la taille annoncée avant lecture, les octets lus pendant - et un dépassement qui est un refus définitif, jamais rejoué #3222, suite du lot 2 de #2720
2744 La publication part à heure fixe (mercredi 6 h UTC) et non à chaque fusion. Le dépôt publiait 3 à 37 fois par jour, jusqu'à 31 versions dans la même journée - non pas des versions vides (95 % de feat et fix) mais atomisées : une version = un changement, donc aucune validable par la recette ni descriptible. La cadence pesait déjà sur une décision en aval, comptée parmi les raisons du déclenchement manuel de winget et Flatpak #2744, lot 3 de #2720
2745 Une vue trop riche se découpe en sous-vues (fx:include + contrôleur dédié), pas en extractions de méthodes : NcssCount compte les déclarations de champs, et les 82 champs @FXML du contrôleur audio pesaient 67 de ses 199 points quand vider ses deux plus grosses méthodes n'en rendait que 32. Et la sous-vue reçoit son ViewModel du parent : se l'injecter lui en donne un second, AudioViewModel étant non-singleton - l'écran se chargeait sans rien signaler, table vide et actions sans effet #2745, lot 4 de #2720
3269 Une commande qui filtre constate un ensemble source vide AVANT d'appliquer le moindre critère, et rend un résultat vide en succès dans le format demandé. Sinon un critère qui désigne (ADR 3082) refuse la valeur tapée - « Lieux présents : aucun », code 2 - alors qu'elle n'y est pour rien : il n'y a rien du tout, et n'importe quelle valeur aurait produit le même refus. Trois situations à ne pas confondre : rien en base, rien après filtrage, valeur absente. Corollaire de test : semer à la demande, un @BeforeEach qui sème toujours rend ce défaut structurellement intestable #3269, clôture des suites du chantier #3092
2746 L'outillage est bati AVEC le produit et partait AVEC lui : 80 classes et 47 points d'entree main dans le binaire d'un naturaliste. Le motif n'est pas le poids (600 Ko contre 21,6 Mo pour org/sqlite) mais la surface. Une classe de production franchissait la frontiere a l'envers - ExportGraphe appelait l'outillage pour l'export d'image de l'utilisateur - ce qui interdisait a la fois l'exclusion et la regle. Trois pieces dans l'ordre : un RenduPng qui recoit le geste, une regle ArchUnit, puis l'exclusion du jar. Resultat : 0 classe d'outillage et 3 points d'entree #2746, lot #2724
2748 Six situations sans rapport apparent portaient le meme symptome, le pire qui soit : un vert qui n'a rien verifie ressemble exactement a un vert qui a verifie. Aucune n'a ete trouvee par la CI. Une mesure vide n'est donc pas un zero, le detecteur se surveille lui-meme, et la fraicheur se mesure depuis l'historique au lieu de se persister - un artefact ou un cache deviendrait une seconde chose a surveiller. Rougir trop s'apprend aussi vite que se taire : avertissement sur un retard mineur, rouge sur une majeure #2748, lot #2724 ; couvre #2887, #3287, #3345, #3382
3366 javac n'est pas la norme, c'en est une mise en oeuvre, et le code qu'il seul accepte empoisonne target/classes puis echoue a l'EXECUTION, tres loin de sa cause. Mesure avant decision : 4 divergences reelles, dont 2 que le balayage textuel de #3228 avait manquees, et 1293 avertissements. Ce sont ces deux manquees qui tranchent - une garde ne voit que ce qu'on lui a appris, un compilateur voit ce qu'il refuse. Seules les erreurs bloquent ; module-info est exclu de la passe, renoncement assume #3366, suite de #3228
3406 Le fuseau d'une nuit est celui de son site d'écoute, Europe/Paris en dur : ces heures viennent de l'enregistreur planté sur le terrain, pas du poste qui dépouille. Le dépôt passait par ZoneId.systemDefault(), et la même nuit partait à la plateforme nationale en 19:00, 21:00 ou - depuis Cayenne - le lendemain. Le test ne le voyait pas : il vérifiait par un aller-retour qui reconvertissait avec la même zone, donc vert sous tout fuseau, y compris ceux où la donnée était fausse. L'outre-mer reste faux et c'est écrit : le dériver du GPS comme la commune (ADR 2791) est différé, pas ignoré #3406, suite de #3151
3501 Ce qui s execute dans un job privilegie est epingle, commite et revu ; le reste s execute sans privilege. L audit a trouve 28 actions sur 28 en tag mutable, l outillage installe par npx --yes dans le job qui publie, et un seul job faisant tout : trois formes d un meme defaut, ou la compromission d un tiers devient la notre au moment ou nos droits sont maximaux, sans qu aucun diff ne l ait montre. Reponse au cout : l epinglage ne fige pas, il rend chaque montee visible et differable. Decision prise au lot 3 et restee non ecrite pendant huit jours #3501, lot 3 de #2720
3479 Trois natures d ecran decident si une table s explore, avant de decider comment la filtrer : exploratoire (contrat complet), analytique bornee (parametres metier visibles, pas un catalogue), operationnelle ou transitoire (rien, et c est delibere). L uniformite visee est celle des regles, pas des composants : equiper une table de suivi d import ajoute un catalogue devant une liste qu on regarde defiler. Le contrat en dix points est acquis, pas vise - cette ADR ecrit ce qui est garanti. Extrait de l audit des filtres du 31 juillet, parce qu un audit se lit une fois et qu un contrat se relit #3479
2750 L ADR 2385 laissait le balisage facultatif. Quinze jours apres, mesure : les onze balises etaient justes, aucun chiffre en prose ne l etait - 21 tests bats pour 89, treize ecrans pour 16, 31 tables pour 33, ~3600 sequences pour 2109. Et personne n avait mal fait : un chiffre juste le jour ou on l ecrit devient faux tout seul. Donc : le code sait compter -> balise obligatoire ; il ne sait pas -> ecrire la phrase sans le nombre ; c est une mesure datee -> elle reste en dur, et c est juste. Corollaire : un decompte se prend sur l etat applique, pas sur le texte qui le produit (amende 2385) #2750, lot #2725
3450 Le cinquième garde « sur la forme du défaut » s'écrivait tout seul : refuser systemDefault() sur une heure locale. Confronté aux lignes fautives d'origine, il aurait manqué les DEUX moitiés - l'écriture portait son atZone deux lignes après ses types locaux, la lecture écrivait atZoneSameInstant, qui a l'air juste. Quand le défaut n'a pas de forme textuelle stable, chercher sa forme comportementale : la suite entière est rejouée sous America/Cayenne (territoire français, franchit minuit, sans heure d'été). Le fuseau passe par l'ENVIRONNEMENT, hérité des forks surefire : par -D, le job aurait pu être vert en ne vérifiant rien #3450, suite de #3406
3451 Une mesure de mutation signalait deux branches non couvertes ; j'en ai conclu un trou produit. Faux : le schéma déclare les trois bornes de nuit NOT NULL et le dépôt charge par le DAO. Une couverture de mutation dit « aucun test ne couvre cette ligne », jamais « cette ligne est atteignable ». L'invariant n'étant tenu que par SQLite, il est doublé d'un refus à l'entonnoir versParticipation - atteignable par construction en mémoire, donc testable, et vu rouge sur ses trois cas #3451, suite de #3406
3439 Les rectangles de masque des aperçus de carte étaient recopiés à la main, et personne ne les remesurait. Trois défauts : sous-couverture (144 lignes de carte dehors, ces fichiers changeant 8 fois sur 20 contre 1 sur 20 ailleurs) ; sur-couverture, la face grave, avec 55 % du masque de multisite-edition sur un tableau de données comparé à rien ; et une entrée de 23x24 px qui ne masquait aucune carte mais une estimation de temps restant. Les rectangles se dérivent désormais de la scène. Écrire sur disque entre le snapshot et la fermeture du stage change les captures suivantes : mesuré à 40 543 pixels #3439, suite de #3068
2753 Ce depot a UN mainteneur : 25 des 40 dernieres PR fusionnees par une personne, 15 par un bot. Et la mesure a recadre le constat - main n a aucune protection, pas seulement la meme revue que le reste. On n en pose donc aucune, et on l ECRIT : une seconde approbation n existe pas a effectif constant, et une regle qu on contourne apprend qu on peut contourner les regles. Les chemins sensibles (migrations, sauvegarde, workflows) portent une case dans le gabarit de PR, pas un garde - un garde de plus serait un dispositif de plus a surveiller (ADR 2748). Le bus factor se traite par l ecrit : la page « Reprendre le depot » #2753, lot #2725
3483 Le masque retire par l ADR 3439 cachait une estimation de temps restant : elle valait « ~13 s » en integration continue et « ~15 s » sur un poste, parce que l ecoule mesure entre deux appliquer est le temps que la MACHINE a mis a rendre l image precedente. Long a voir parce que le chiffre est plausible - il ressemble au produit. Ecarte : supprimer l estimation (c est ce que #146 et #2733 documentent), injecter une horloge (huit sites de construction, cinq ViewModels), redormir (125 ms font basculer l arrondi). L ecoule devient une entree posee par la capture, au meme titre que la fraction et le libelle ; le calcul reste celui de la production, et le garde porte sur tout ..outils... Le test a echoue en figeant les trois etats : la fraction est monotone, 0,126 pose apres 0,20 rend l estimation de 0,20 #3483, suite de #3439
3505 Le cycle decrivait la cloture et se taisait sur le travail - et ce silence etait rempli par une consigne fausse : ajouter-une-fonctionnalite.md numerotait « Tester » en etape 8 sur 8. Rouge-vert-refactor devient une boucle repetee a chaque petit pas, dont le REFACTOR est la troisieme phase de CHAQUE tour et non une etape de fin ; PIT tourne quand la boucle s arrete, pas a la cloture. Les ADR se coupent en deux passes : 0 relit l existant, 10 ecrit les nouvelles - les cinq ADR de #3151 portent toutes « suite de », aucune n etait nee ou le cycle la demandait. Les passes 1 a 9 gardent leur numero : 35 des 42 citations vivent dans des ADR immuables #3505, suite de la cloture de #3151
3482 Supprimer un passage laisse délibérément ses fichiers - l'audio est irremplaçable, la base se rejoue. Deux conséquences n'étaient prises par personne : la modale annonçait « toute sa nuit » quand les WAV restaient (la CLI, elle, le disait déjà - deux surfaces, deux histoires), et rien ne ramassait derrière, à plusieurs Go par nuit, jusqu'au mur du disque plein rencontré en vrai. L'audit gagne donc sa seule action qui écrit, parce que décider qu'un dossier est orphelin est son calcul : confronter le disque à la base. Bornée à la catégorie DOSSIER_ORPHELIN (le champ cible porte ailleurs un FICHIER), chiffrant la perte avant de la demander, et rendant compte de ce qui a résisté - le helper existant était best-effort et silencieux, juste pour un temporaire, faux pour des données d'utilisateur #3482, campagne de recette 2 (#3424)
3510 La passe 6 traitait la recette en deversoir (« ce qui ne peut pas etre automatise y va »), ce qui fermait un mode de panne et en laissait un autre : une case ecrite mais injouable a l apparence d une verification prevue, et elle se coche. Trois facons d y arriver sans faute de personne - la session proprietaire n existe pas (S7), la case atterrit dans une session de transit, ou aucune fixture ne porte le cas. Desormais : une capacite n est pas finie tant qu on ne sait pas comment la verifier a la main, et une case n est terminee que si elle est rejouable - geste, observation attendue, fixture. Etendre la spec du generateur fait partie de la passe : une donnee bricolee ne revient pas a la campagne suivante #3510, suite de #3505
3537 Un binding observe une Property, jamais SQLite : tant qu'une ecriture ne laisse pas de trace observable, un ecran ne peut que se rappeler lui-meme au retour de navigation, et rate donc tout ce qui survient pendant qu'il est affiche (#1376). Le port JournalMutations posait deux regles d'appel ; la seconde - une fois par operation metier - a tenu trois jours : RapprochementSites cree les sites en boucle en appelant le meme service qu'un ajout manuel, et ce service ne peut pas savoir s'il sert un geste ou une synchro de 250. La tenir imposait d'eloigner l'appel du point d'ecriture, donc de le rendre oubliable - en desarmant le mecanisme pour respecter sa propre grammaire. Tu ecris, tu signales, apres validation ; la rafale s'amortit chez le lecteur (250 signaux, 1 reveil). Trois inventaires successifs des ecritures ont ete faux : un grep en une ligne rate un DAO nomme sur la ligne d'avant, un balayage multi-lignes rate le SQL brut de l'import, et deduire l'effet structurel d'un compteur de compte rendu produit des faux negatifs. Meme constat que l'ADR 3498, sans l'inversion de charge qui la sauve #3537, lot 1 de #3536
3535 Un meme inventaire a diverge trois fois en une journee, et deux fois du fait du chantier qui ecrivait le matin la regle censee l eviter : etat des sessions de recette (3 copies, S7 ecrite le jour ou deux copies la disaient inexistante), liste des cartes d accueil (4 copies, 5 annoncees pour 7), masques d apercus (16 pour 19, deja corrige par #3439). Une copie perimee se lit exactement comme une copie juste : Markdown valide, mkdocs --strict muet, aucun test rouge - les trois ont ete trouvees par quelqu un qui LISAIT. Un inventaire a une source unique ; les autres pages la citent, et quand les publics different (brief, script de recette) elle se derive sous garde. Et souvent la meilleure reponse est de la SUPPRIMER : #3522 a corrige le meme cas le meme jour en retirant la liste au profit d une consigne de comportement, qui ne se demode pas. Generalise l ADR 3439 du code a la prose #3535, cloture de #3505/#3510
3498 L'IHM réserve le dossier de travail pour toute sa durée ; la CLI ne l'a jamais demandé, et un importer lancé en parallèle écrivait dans la même base sans que rien ne l'en empêche. Le verrou existait depuis le lot 1 de #2720 et nommait lui-même le cas « une IHM et une CLI » - les lots 4 et 5 ont travaillé la surface CLI sans le reprendre. Poser le verrou demandait de savoir qui écrit, et aucun signal ne le dit : le nom ment (metadonnees-passage envoie ; emplacements écrit, mais ailleurs, et reste donc lectrice), le service appelé classe lister-sites parmi les écrivains, et l'analyse d'appels sur les 65 commandes se trompe dans les deux sens (rate supprimer-site, signale lister-carres). D'où le sens choisi : on déclare les lectrices, parce qu'oublier une écrivaine se paie en silence tandis qu'oublier une lectrice se paie en gêne visible le jour même. Le garde n'atteste pas que le classement soit juste, seulement qu'un choix a été fait #3498, lot 1 de #3518 ; défaut trouvé à la passe 1 de la clôture de #2720
3500 BilanRestauration porte deux accesseurs, et les deux surfaces n'en lisaient pas le même nombre : l'IHM passait en AVERTISSEMENT, la CLI imprimait le même texte puis rendait 0 sans condition. Un script qui restaure et teste $? concluait à une restauration entière alors qu'une nuit manquait - le défaut que le lot 1 existait pour tuer, réapparu sur la surface scriptable. Le remède évident était faux : appelleUnRegard() est un ou de trois termes, dont « les dossiers ont atterri ailleurs », qui est le cas normal d'une restauration sur une autre machine. Le câbler tel quel aurait rendu 10 à l'usage principal de --complet, et un 10 permanent s'apprend à s'ignorer. D'où laisseUnManque(), plus étroit. Les deux surfaces divergent désormais, et c'est un choix de destinataire : l'IHM parle à quelqu'un qui lit le compte rendu, la CLI à un script qui n'a que le code #3500, lot 1 de #3518 ; défaut trouvé à la passe 2 de la clôture de #2720
3563 #3514 avait introduit la zone temporaire que l'ADR 2727 avait écartée avec un chiffre (« restaurer 40 Go par-dessus ses propres 40 Go demanderait 80 Go libres »), et personne ne l'avait relue : le pic passait à ~3x la donnée, sans aucun garde d'espace, alors que le port EspaceDisque existait. Le régime devient une conséquence de la place libre et non un choix figé : tout étaler si la place y est, une nuit à la fois sinon, refus chiffré en dessous. Le calcul est pur - le manifeste porte les octets - et se compte par dossier d'accueil, un total unique se trompant dans le sens dangereux quand un disque externe est rebranché. Dès la première bascule du régime dégradé, « rien n'a été touché » cesse d'être vrai : le refus est requalifié en incident. Amende l'ADR 2727 #3563, lot 1 (#3559) de #3518
3507 Le fichier qui dit où vivent les données s'écrivait en place : une interruption le laissait tronqué, et sa lecture - qui pardonne, à raison - repartait alors sur les emplacements par défaut. Deux décisions bonnes séparément, un défaut muet ensemble : l'application marche, et toutes les nuits ont disparu. Il passe par EcritureAtomique, et le garde porte sur la structure faute de pouvoir observer une troncature. Le détour par un flux d'octets n'est pas une lourdeur : store(OutputStream) écrit en ISO-8859-1 échappé quand store(Writer) écrirait du brut, et load(InputStream) relit en ISO-8859-1 - simplifier corromprait le premier chemin accentué venu #3507, lot 1 (#3559) de #3518
3514 Deux décisions qu'aucun code ne portait. Une destination qui contient un fichier inconnu de la sauvegarde fait refuser : basculer remplace la destination entière, donc restaurer deviendrait un moyen détourné d'effacer ce qui traînait là - trouvé par un test qui est passé au vert tout seul, un vert inattendu étant une trouvaille au même titre qu'un rouge. Et pas de journal de bascule : sa panne serait du même genre que celle qu'il répare, avec un dispositif de plus à surveiller (ADR 2748). On réduit la fenêtre au lieu de la rattraper - ce n'est pas de l'atomicité, et il ne faut pas le dire #3514, lot 1 (#3559) de #3518
3572 La sauvegarde complete etait le seul chemin d'ecriture volumineuse sans garde d'espace, et vers un support choisi par l'utilisateur - une cle, souvent plus petite que le dossier de travail. Mais la verification a montre pire : le dossier interrompu restait, InventaireSauvegardes le classait comme complet (il classe sur le prefixe du nom), et son manifeste - ecrit en dernier - etant absent, le restaurer empruntait le chemin d'avant #2726. Une sauvegarde tronquee se faisait passer pour une sauvegarde d'ancien format. Remede en deux moities : un refus chiffre avant la premiere copie, et un nom de chantier jusqu'a l'ecriture du manifeste. Renommer plutot que nettoyer a l'echec, parce qu'une coupure de courant n'execute aucun catch ; et le marqueur en tete du nom, un suffixe laissant le dossier passer pour complet #3572, suite de #3559
3574 Sept implementations d'un effacement recursif, et le meme nom ne voulait pas dire la meme chose : quatre comportements en cas d'echec - lever, lever sans le declarer, avaler, rapporter - dont deux sous le nom supprimerRecursivement. Une copie faite depuis le mauvais modele changeait le comportement en cas de panne sans rien casser de visible. Deux contrats, deux noms : supprimerRecursivement leve, effacerAuMieux rend ce qui a resiste avec la raison - le rapporteur en a besoin, et la lui retirer l'obligerait a refaire le parcours. Envelopper en UncheckedIOException reste une decision de l'appelant. Le premier test « continue apres un echec » etait creux : deux dossiers separes, donc rien sur le parcours - la mutation l'a dit #3574, suite de #3559
3573 Deux formateurs annoncaient des tailles differentes pour les memes octets, sous la meme etiquette : 4 000 000 000 octets valaient « 3,7 Go » ici et « 4,0 Go » la. Le releve par diviseurs - et non par noms de methode - en a trouve sept. Base 1000 retenue parce que c'est l'unite dans laquelle les supports sont vendus, et que nos chiffres servent a repondre a « est-ce que ca tient sur ma cle ? ». Une decimale sous dix, aucune au-dessus : consolider aurait sinon transforme « ~1,5 Mo » en « ~2 Mo » sur les annonces d'export. octetsLisibles n'avait aucun test, ce qui est aussi pourquoi les bases ont pu diverger ; et deux attendus etaient plies au formateur plutot qu'a leur propre fixture #3573, suite de #3559
3575 Deux pieces de l'ADR 3498 ne tenaient pas ce qu'elles promettaient. Sa definition disait « ni les dossiers du dossier de travail », alors que Cli.main amorce la journalisation avant tout : les vingt-trois lectrices ecrivent <workspace>/logs. Elle etait donc contredite par les commandes qu'elle decrivait - l'exception est desormais nommee, et elle est voulue : un incident doit laisser une trace meme sur une lecture. Et son cliquet recopiait 44 noms que ses deux assertions rendaient exactement derivables ; il devient un compteur, ce qui force autant puisque c'est le MESSAGE qui decide, pas la liste. Recul assume : le message ne designe plus l'intruse, il affiche les quarante-cinq #3575, suite de #3559
3624 La cloture des suites a trouve trois defauts que l'arsenal de tests ne pouvait pas voir : un fait vrai, une consequence visible, et aucun dispositif capable de rougir dessus. #3570 avait retire la pile de la console en promettant qu'elle restait dans un fichier - promesse que rien ne verifiait, dans un dossier qu'aucune commande ne nommait. Les fixtures d'apercu, ecrites en base 1024, publiaient « 432 Mo » la ou leur litteral disait 412 depuis l'ADR 3573. Deux ancrages, a choisir explicitement : un test qui traverse (bats, vrai fat-jar) quand le fait est mecanique, une fixture posee dans la base ou elle sera rendue quand il est visuel. Retirer un temoin sans verifier le nouveau, c'est deplacer la preuve hors de portee en la croyant conservee #3624, cloture de #3559
3560 Le lot visait deux outils ; en les ouvrant, la formule a recouvert trois pannes distinctes. dependency:analyze ne tournait pas du tout - lie a aucune phase, appele par aucun workflow, alors que ses exclusions avaient ete soigneusement reglees. Les deux issues concluaient sur une premisse fausse : archunit-junit5 n'etait pas le faux positif suppose, et la « variance faible » de la CI, mesuree sur sept executions, cachait deux runs au DOUBLE de la mediane sur trente. Et le dispositif ecrit pour la seconde est arrive injugeable : il allait chercher ses propres donnees, et son verdict n'allait que dans le resume. La garde de dependances bloque aussi en LOCAL, contre le principe du depot : la deplacer sous -Pquality-gate la desactiverait, le job build lancant verify sans ce profil #3560, lot 2 de #3518
3661 Dix scripts de CI sur onze portent un --auto-test lance par lint.yml - une discipline du depot depuis #2947, dont les cas vont jusqu'aux controles negatifs. Le onzieme, arrive avec l'ADR 3560, avait ses cas dans un fichier bats a part. La cause etait un releve FAUX, et de moi : chercher les tests dans src/test ne pouvait pas voir une discipline qui vit A L'INTERIEUR de chaque script. L'exception coutait plus que sa duplication - elle faisait attendre un fat-jar de 80 Mo a des tests de shell, avait rendu fausse une phrase de la doc, et brouillait ce que compte la balise tests-bats. Une seconde facon de faire DEPLACE ce qui l'entoure pour lui faire de la place #3661, suites de #3664
3664 Sur les trois suites des lots 1 et 2, deux portaient une premisse fausse - et avec les deux constats du lot 2 et le releve initial de #3627, cela fait cinq sur cinq le meme jour. #3632 annoncait trois sites, il y en avait neuf ; #3661 affirmait qu'un seul script de CI etait eprouve quand dix sur onze portent un --auto-test depuis #2947. Un grep qui ne trouve rien est une hypothese, jamais un constat. Ce n'est pas de la prudence : rejouer le releve a change le DISPOSITIF quatre fois sur cinq. Et ce qui a mordu, ce sont des dispositifs - cliquet, mutation, sonde -, pas une relecture : ecarte donc l'ajout d'une case au cycle, qui se coche sans se faire #3664, suites de #3518
3627 Le garde d'espace concluait « il y a la place » depuis un silence : un fichier illisible pesait comme un fichier vide. Mais le constat de départ était partiellement faux, et le sonder l'a montré : un dossier illisible ne se tait pas, Files.walk lève - et cette UncheckedIOException, n'étant pas une IOException, traversait le catch de sauvegarderComplet. L'utilisateur lisait « Échec, état incertain » (code 1) sur une opération qui n'avait rien touché : c'est un refus (code 2). Une mesure rend donc ce qu'elle a lu et ce qu'elle n'a pas pu ouvrir ; l'inventaire l'ignore, le garde refuse en le nommant, avant de comparer à la place libre - sinon on envoie libérer des octets pour un problème de droits. Parcours par file explicite, walk interrompant tout au premier dossier interdit. NOFOLLOW_LINKS sur le seul test de dossier : sans lui un lien vers un ancêtre fait tourner le parcours sans fin #3627 puis #3634, suites de #3624
3580 Le lot 4 devait brancher cinq ecrans sur la revision puis retirer RafraichirAuRetour, devenu un vestige. La cartographie a dementi la premisse : le signal de l'ADR 3537 est structurel, or ce que ces cinq ecrans rechargent au retour sont des update - un verdict, un depot, un statut - qui n'emettent pas. Le vestige suppose etait le seul mecanisme couvrant leur cas reel. Les deux coexistent donc par contrat : le retour voit les update, la revision voit les insert / delete. Un lecteur futur y verra une migration inachevee ; la supprimer compile, laisse les gardes verts, et casse les cinq ecrans sur ce pour quoi ils rechargent #3580, lot 4 de #3536
3651 Cinq ecrans portaient le meme triplet abonnement / pose / retrait. La duplication n'etait pas le probleme : les trois lignes ne se valent pas. Oublier la pose se voit au premier essai ; oublier le retrait ne casse rien de perceptible - RevisionDonnees est un singleton, l'ecoute survit a la vue, et dix ouvertures font dix rechargements dont neuf pour personne. Le Navigateur porte donc le cycle, l'ecran ne declare que son intention (SuitLaRevision). Le repere est la vue, pas l'etape : relibeller (#1213) retire et replace la meme etape, donc la pose doit etre idempotente - mesure a « expected: 1 but was: 2 » #3651, suite de #3580
3539 Un booleen lu au montage puis pose sur un controle : ce qui le rendait vrai peut changer, le controle ne rebouge plus. Plus insidieux que l'ecran qui ne voit pas arriver la donnee, parce que l'instantane est JUSTE a l'instant ou il est pris - rien ne se voit au premier lancement - et que les ecrans restent vivants dans la pile. Ce qui se decide au montage, c'est le cablage ; ce qui varie, c'est la donnee. Le balayage a releve 138 sites sur les trois mots-cles : zero defaut, et le seul jumeau reel n'en porte aucun - trois formes sur quatre sont invisibles au mot-cle #3539, lot 2 de #3536
3672 Deux ecrans sur quinze derivent leur libelle de navigation de la donnee, et les deux ont produit le meme defaut a onze jours d'ecart. L'arbitrage 3 de #3536 prevoyait qu'un deuxieme cas rouvre la decision : elle a ete rouverte et re-tranchee dans le meme sens - une correction locale en une methode contre une mecanique qui toucherait le chrome entier. Corollaire contre-intuitif : declarer EmplacementNavigation sur un ecran au libelle fige fabrique la contradiction au lieu de la corriger #3672, suite de #3455
3668 Un robot.interact(...) (ou un appel direct dans @Start) qui declenche occupation.occuper(...) sur le vrai RacineInjecteur tourne sur le vrai ExecuteurTacheAsynchrone, pas sur l'ExecuteurTacheSynchrone que les tests de vue/ViewModel recoivent par defaut : l'assertion qui suit doit attendre le signal du callback (WaitForAsyncUtils.waitFor sur un predicat observable), jamais le seul retour du geste - waitForFxEvents() vide la file du fil FX, il n'attend pas le thread d'arriere-plan qui doit encore la remplir. Defaut non reproductible en local, visible uniquement sous un fuseau CI plus lent, et qui accusait a chaque fois un test sans rapport avec la modification en cours #3668, PR #3716/#3722, audit #3717
3547 Bindings.createXBinding(calcul, dependances…) ne recalcule que si une dependance declaree s'invalide, et rien ne verifie que calcul n'en lit pas d'autres : ni le compilateur, ni PMD, ni un test. Les 63 sites du depot ouverts un par un : 61 complets, 1 inoffensif par un ordre (l'ecran charge avant de filtrer, et n'a aucun rechargement), 1 atteignable - la barre de statut de la vue audio, dont reinitialiser() repose la meme instance constante, donc zero invalidation mesuree (#3752). Verifier statiquement « lu ⊆ declare » est ecarte : il faudrait suivre les appels depuis la lambda, et une heuristique textuelle echouerait sur les references de methode, c'est-a-dire la ou les trois defauts se cachaient. Un cliquet compte les sites a la place : il ne verifie aucune declaration, il garantit qu'un nouveau site est vu. L'issue en annoncait 62 ; le 63ᵉ etait arrive deux jours apres sa redaction, sans que rien ne le signale #3547, lot 3 de #3536
3540 L'ADR 3547 declarait Verification : certaine en designant le cliquet qui compte les Bindings.create…Binding - or son propre texte dit que ce cliquet ne verifie aucune declaration. Un binding qui sous-declare le laisse vert : la ligne nommait un test incapable de rougir sur la decision, la forme exacte que l'ADR 3624 proscrit. Le cliquet et la regle s'ancrent donc separement : la regle par un regard consigne (l'inventaire des 63 sites), le cliquet par ce qu'il tient vraiment - aucun nouveau site n'entre sans etre vu. Trouve parce que la passe 0 a ete rejouee depuis le commit d'ouverture du chantier et non du lot : la fenetre courte ramenait une ADR au lieu de vingt-trois, et l'ADR 3624 etait dans les manquantes #3540, cloture du lot 3 de #3536
3760 Les deux barres du chrome demandaient plus de place qu elles n en avaient a la largeur d ouverture, et les deux mecaniques donnaient le meme trou : une HBox repartit le manque (chacun perdait 27 px, tout le monde tronquait un peu, titre et bouton Retour compris), un BorderPane donne a droite sa largeur preferee et laisse 10 px au centre. Personne ne decidait qui rend sa place. Trois natures de reponse, qui ne valent pas la meme chose : figer ce qui ne doit jamais s abreger, reduire la demande (le seul qui supprime le probleme au lieu de le deplacer), et assumer par abregeable. La troisieme fait TAIRE le garde de lisibilite : elle change un rouge en vert sans rien ameliorer a l ecran, et doit donc dire ou elle est posee et a partir de quelle largeur elle travaille #3760 et #3743, suites de la cloture du lot 3
3561 Le train de publication a ete branche sur une preuve des plateformes sans inventorier les chemins que la garde ferme - alors que l'ADR 0041 ecrit la procedure, et que l'ADR 2744 decide en toutes lettres qu'« un correctif urgent n'attend pas le train ». Le workflow_dispatch etait garde comme le schedule. Ce qui a tranche n'est pas le retard de ~50 min mais qu'un test instable et sans rapport aurait retenu un correctif de securite - mesure : un test vert a 8 h 14 et rouge a 15 h 34, meme commit, meme image (#3773). L'echappatoire n'est donc ni fermee ni invisible : une raison_du_contournement ecrite, refusee sous 20 caracteres, portee dans le titre du run. Deux pieges : null == '' est VRAI en expression GitHub, donc tester la seule entree aurait desarme la garde le mercredi ; et needs sur un job saute saute le dependant, donc le contournement aurait EMPECHE la publication #3561, lot 3 de #3518
3458 La modale de declaration demande a Vigie-Chiro si un carre y existe deja. Entre la question et la reponse, le numero peut changer - dans les deux sens : la saisie bouge apres la reponse, ou la reponse arrive apres la saisie. Les deux affichent un jugement sous un carre qu'il ne juge pas, c'est-a-dire la panne meme du chantier, avec la preuve visuelle du contraire. Deux mecanismes, un par sens : le verdict s'efface quand le numero change, et un resultat porte le numero qui l'a demande pour etre jete s'il ne correspond plus. Corollaire : une absence de reponse parle (« ce carre n'a PAS ete verifie ») la ou un controle automatique peut se taire sans mentir #3458
3826 L'ADR 3374 posait Habillage pour « les fenetres comme les captures » ; son garde ne parcourait que src/main, et ce silence sur les TESTS etait le trou - dix d'entre eux mesuraient une geometrie sur une scene montee a la main, donc avec la police de la MACHINE. Le mecanisme est un couplage d'ORDRE, pas une difference de plateforme : Typographie.installer() garde un static boolean, donc un test voit la bonne police si un voisin l'a installee avant lui. Mesure : meme commit, meme image macos-26-arm64, vert a 8 h 14 et rouge a 15 h 34 ; joue SEUL, il echoue. Invisible depuis un poste Linux, ou Noto Sans est une police systeme : l'experience d'isolement y est aveugle par construction, et elle a failli servir de preuve. La regle ne vise PAS tous les new Scene - une centaine de tests ont raison de l'ecrire - mais l'USAGE : construire ET mesurer #3826, lot 1 de #3802
3827 Deux affirmations vivaient depuis des mois sans etre verifiees, toutes deux sur le chemin d'AMORCAGE et sur le fichier du JETON : que ATOMIC_MOVE echoue sous Windows quand la cible est ouverte (le motif FONDATEUR du chantier #3518, reste decouvert), et que le jeton « reste protege par les ACL du profil ». Les deux sondes ont CONTREDIT leur issue : les quatre facons de tenir la cible provoquent le refus - un simple lecteur suffit -, et la protection est REELLE, exactement trois entrees ALLOW, l'equivalent de 600. Ce qu'on ignorait n'etait pas si la protection existe : c'est qu'on n'en savait rien. Une propriete se LIT desormais (ProtectionFichier), et ni POSIX ni ACL fait LEVER plutot que rendre true - annoncer une protection depuis une ignorance serait le faux vert qu'on combat. Trois assumeTrue tombent, dont un qui vivait DANS un helper et interrompait le test au milieu, emportant une assertion qui n'avait rien de POSIX #3827, lot 3 de #3802
3645 Le cliquet de dette de l'invariant « tu ecris, tu signales » certifiait gardees les cinq classes qu'il accusait : il parcourait tous les fichiers de test y compris le sien, dont la documentation nommait les cinq debiteurs, dans un fichier contenant par construction le nom du port cherche. Mesure, il ne nommait aucun debiteur sur cinq - ni descendre, ni rougir. Un detecteur textuel s'exclut donc de son propre corpus, comme LibelleDeNavigationTest ecarte Navigateur.java. Corollaire : un garde nomme le port - un () -> compteur[0]++ anonyme compte l'annonce sans qu'aucun detecteur puisse le voir, et BaseNeuveTest se faisait ainsi accuser d'une dette qu'elle n'avait pas #3645, suite de #3536
3828 Trois defauts d'affichage decouverts separement sont LE MEME : une decision que personne n'avait prise, et que la machine ou l'habitude avait prise a sa place - l'heuristique de picocli pour la couleur, le serveur pour l'instant, l'habitude pour trois rendus de date. Aucun n'etait un bug : rien ne plantait, aucun test ne rougissait. « NO_COLOR donne le dernier mot » n'etait pas faux, c'etait INCOMPLET DANS LE SENS RASSURANT - il n'y avait de dernier mot que pour eteindre. Deux formes d'horodatage nommees par leur USAGE, parce que le « a » lit bien dans une phrase et mal dans une colonne : le nommage a corrige un site tout seul, et m'a repris sur un autre ou j'allais renverser la decision de #3640 sans la voir. Deux familles restent dehors, aux exigences opposees : noms de fichiers (tri lexical) et lecture de ThLog (fidelite au producteur) #3828, lot 4 de #3802
3794 Le depot exige de son PRODUIT que ses inventaires soient prouves - CLI, captures, ADR, cliquets - et de sa PROPRE DESCRIPTION rien. Trois inventaires tenus a la main, trois derives : deux workflows absents du tableau, et ce sont les DEUX de securite - un inventaire non garde perd d'abord ce qu'on regarde le moins. Le defaut se reproduit pendant qu'on le decrit : #3771 annoncait cinq gardes manquantes, il y en avait six. D'ou la garde AVANT les corrections. Elle compare des FICHIERS, jamais des lignes - maven.yml en occupe cinq. Et elle ne juge PAS le contenu des colonnes : exiger un libelle pousserait a completer le tableau EN L'APLATISSANT #3794, lot 2 de #3802
3802 QUATRE fois sur cinq lots, le poste de developpement etait AVEUGLE PAR CONSTRUCTION : Noto Sans est une police systeme sous Linux, ATOMIC_MOVE y reussit quoi qu'on tienne ouvert, la vue ACL n'y existe pas, et PIT y tourne. Une suite locale verte ne disait rien - et une experience d'isolement a failli servir de preuve. Un defaut de plateforme se SONDE : un test jetable qui RAPPORTE au lieu de juger, dispatche la ou le defaut vit, lu, PUIS traduit en assertion. Les DEUX sondes de la campagne ont CONTREDIT l'issue qui les demandait. La sonde dit quel comportement cabler ; l'injection le rend rejouable partout - l'un sans l'autre laisse la moitie du remede non jugee #3802, suites de #3518
3806 Preparer une nuit opportuniste exigeait un site RATTACHE, or la synchro derive les sites de /moi/participations : deposer etait la seule chose qui aurait cree la participation qui aurait rendu le depot possible. Le remede pressenti - elargir a /moi/sites - a ete MESURE FAUX sur le cas courant : cette route filtre sur le proprietaire, et les possesseurs de carres sont rares (sonde #3669, compte reel : 0 site, celui des participations appartenant a un tiers). C'est donc GET /sites?q= qui rend le carre a qui le DEMANDE. Un numero ne designe pas un site - Point Fixe, Pedestre, Routier - donc on ne recupere que le Point Fixe et on le DIT plutot que de rattacher au hasard. La saisie de l'utilisateur survit (la plateforme ne stocke aucun nom libre), et le blocage de « Creer » est borne a la DECLARATION, l'edition d'un site deja connu etant le cas nominal #3806, suites de #3458
3769 --carre lisait UNE page sur 208 puis filtrait chez nous : le tableau sortait vide sur un carre qui EXISTE, et seule la ligne de bilan l'avouait. Passe au filtre serveur, que restait-il de --pages et --tout ? Ils sont REFUSES (code 2) et non acceptes sans effet : la recherche porte sur toute la collection, il n'y a plus d'etendue a borner, et les accepter en silence serait ce que le depot reproche a where=. Le denominateur ne disparait pas, il CHANGE DE NATURE : « 1 site lu : collection complete » serait exact et trompeur - on n'a pas parcouru, on a demande. Le refus tombe AVANT toute lecture de jeton, ce qu'un test bats exige en interdisant au message de parler de jeton #3769, suites de #3458
3960 La cloture du lot #3900 a trouve QUATRE gardes qui annoncaient plus qu'ils ne tenaient : deux bancs lisant un chrome.largeur que RIEN ne posait, donc jamais joues a 900 - la largeur ou l'elision sert ; un inventaire de 41 commandes garde par un plancher -ge 20 ; un cliquet qui plantait sur le premier sous-dossier venu, dans le fichier meme qui ecrit « un garde qui ment selon la machine ne vaut rien ». Un garde s'execute donc dans TOUS les cas qu'il nomme, verifie d'abord qu'il a obtenu ce qu'il demandait, et REND l'etat partage qu'il emprunte - TestFX reutilise la fenetre primaire, et un setWidth(900) laisse en place retrecit toutes les classes suivantes. Trois hypotheses sont tombees a la mesure avant la bonne : ce qui a tranche est d'avoir relance la suite avec les PROPRIETES EXACTES du job, pas un raisonnement. Un test qu'on ne sait pas voir rouge a ete retire #3960, cloture du lot #3900
3962 Le compte rendu et la CLI promettaient « Reprendre le depot » sur des archives refusees definitivement - et dans cet etat le bouton s'intitule « Televerser sur Vigie-Chiro », donc le texte nommait un bouton ABSENT de l'ecran. Cause racine : BilanDepot.echecs etait une List<String>, et definitif/cause etaient jetes A LA LIGNE MEME ou ils existaient - meme forme que #3688. On enrichit donc la DONNEE (EchecUnite) plutot que rendre les phrases prudentes : une phrase prudente protege la phrase, un type protege tous ses lecteurs. Corollaire : un geste se nomme pour la PART qu'il repare, se taire sur un lot mele perd un geste verifie. Ce corollaire et un titre qui disait « Nuit deposee » a 11/14 se sont vus EN OUVRANT L'APERCU, sur une bande ou seize tests etaient verts #3962, cloture du lot #3900
3854 Le refus du depot conseillait « synchronisez vos sites », geste dont la sonde #3669 a mesure qu'il ne ramene PAS un carre sans participation : le conseil etait inapplicable a ceux-la precisement, et c'est le parcours qui a produit #3458. JUMEAU du defaut corrige cote modale par #3806 - corriger l'un sans l'autre laisse le defaut vivant sous une autre forme. Un refus verifie donc qu'un geste s'applique avant de le nommer : recuperer si le carre existe en Point Fixe, activer sur le portail sinon. Injoignable NE TRANCHE PAS - ni « recuperez-le », ni « il n'existe pas » : affirmer depuis une ignorance est ce que l'ADR 3458 a ferme. La requete ne se paie que sur le chemin d'ECHEC, un test tenant qu'un depot qui aboutit ne cherche aucun carre #3854, cloture des suites de #3458
3798 L'ADR 3760 avait designe le fil d'Ariane comme PORTEUR du deficit de la barre du haut ; une HBox le REPARTIT, et ses cinq segments perdaient 39 px chacun a 900. Le principe etait donc tenu a l'etage de la barre et enfreint un cran plus bas, par le composant charge de le porter - et une repartition egale en pixels ampute inegalement : « Accueil » perdait 65 % de sa largeur, « Details du passage N° 1 » 26 %. Le fil elide desormais des segments ENTIERS, la proximite d'abord, l'ancre en dernier ; le menu « … » garde les retires, libelle complet et action. Le remede ecrit dans l'issue (premier + deux derniers) demandait 380 px pour 351 : un schema FIXE ne pouvait pas convenir. Meilleure part du chantier : abregeable est retiree des segments, donc LisibiliteCapture retrouve le droit de rougir dessus - un dispositif qu'on cesse de baillonner plutot qu'un dispositif de plus #3798, suite de #3536
3840 L'ADR 3537 reserve le signal aux ecritures STRUCTURELLES, ce qui laisse dehors les update - or Analyse affiche le taxon RETENU (COALESCE(taxon_observer, taxon_tadarida)), que le remplacer change. Le critere « les quatre comptes » n'explique donc pas pourquoi le produit reste juste : la fraicheur est portee par DEUX mecanismes, SuitLaRevision pendant qu'on regarde l'ecran, RafraichirAuRetour parce qu'on etait ailleurs. Ils ne sont PAS redondants ; retirer le second d'un ecran qui porte le premier casse la fraicheur en silence. Ma premiere version du test ne prouvait rien et restait verte sous cette mutation : la premiere validation INSERE (donc annonce), et son rechargement asynchrone relisait la base apres le remplacement silencieux. Un fait tenu par un autre dispositif que celui qu'on croit se demasque comme l'ADR 3624, en mutant ce qu'on pretend verifier #3840, suite de #3645
3667 Deux abstentions de la cloture, ecrites pour ne pas se re-debattre : la logique pure de la recette reste en portee test sans couverture de mutation (trois lancements PIT, trois fois zero mutant, la cause probable etant Mutating from target/classes - mais elle n est PAS etablie), et les deux essai() ne sont pas factorises (huit lignes partagees, et l ADR 3661 venait justement de supprimer le fichier commun). Ce que la premiere coute : l assurance repose sur 8 tests et un temoin passe a la main, la ou PIT avait trouve ailleurs 14 survivants qu une mutation manuelle n avait pas vus #3667, à la clôture de l'EPIC
3764 Le garde de recette ne connaissait que couvert / non couvert, et cette dichotomie allait compter comme prouves deux cas que personne n aurait regardes - un scenario perceptif CITE son cas, c est son seul lien vers le script. Trois etats donc, ou l etat est une propriete du cas (marque *perceptif*, posee en passe 6, avant qu un test existe) et non du test, qui declare seulement ce qu il pretend prouver. Les deux sources se confrontent et rougissent quand elles se contredisent : c est ce recoupement qui empeche la marque de deriver comme la prose avait derive #3764, tranche (a) de l'EPIC #3667
3774 Trois choix du montage, chacun avec une reponse plausible et fausse : t0 se mesure (arret moins duree) au lieu de s estimer, le clip se taille sur le test parce que c est ce que la JVM sait borner, et le controle porte sur la couverture et non sur la clarte des clips - l exiger ferait rougir un test de ViewModel qui n ouvre legitimement aucune fenetre. La premiere seance REELLE a refuse un alignement correct parce que les plages ne venaient que des tests cites : le travers evite par ailleurs, revenu par la fenetre du denominateur #3774, tranche (b) de l'EPIC #3667
3788 matchbox maximise tout ce qu il affiche, et a fait mentir deux dispositifs : les tests de croissance de fenetre ne POUVAIENT pas passer (une fenetre deja maximisee ne grandit pas), et les clips montraient une mise en page qu on ne livre pas - donc qui les jugeait jugeait autre chose. Aucun compteur ne le disait ; le defaut n a ete vu qu en extrayant une image. Corollaire impose par le calcul : le seuil de luminance descend de 50 a 20, sans quoi une boite de dialogue de 400x250 rendrait 36 et serait declaree « rien a l ecran » sur un banc pourtant juste #3788, trouvé pendant la tranche (c) de #3667
3801 Douze mutants survivaient sur SiteEditViewModel, dont NEUF sur une reinitialisation de champs qui reecrivait des valeurs deja en place : la production recharge le FXML a chaque ouverture, donc le ViewModel est toujours neuf. Mais la premisse « personne ne reutilise une instance » etait fausse du DEPOT : trois tests le faisaient, dont deux en faisaient un CONTRAT (#1380 sur la portee, #3458 sur le verdict). Le mono-usage est donc un RENVERSEMENT, et il se declare : preparer deux fois LEVE, au lieu de laisser un ecran a moitie rempli. Ce que la reinitialisation garantissait est reporte sur un cas qui lit l etat CONSTRUIT. Un faux vert pris par la remesure : un cas ecrit pour effacerRetour partait d un carre invalide, donc comparait AUCUN a AUCUN. PIT 83 % → 97 % #3801, dette de la cloture des suites de #3458
3462 Un utilisateur n a lance AUCUNE ecoute d une seance entiere : le bouton lecture etait invisible. La mesure deplace le defaut - son TEXTE est a 10,68:1 (seuil 4,5), c est la SURFACE qui etait a 1,17:1 du fond (seuil 3, WCAG 1.4.11). Defaut d AFFORDANCE, pas de lisibilite : eclaircir le texte, remede qu on aurait pris sans mesurer, n aurait rien repare. Un contour et non une surface plus claire, calcule : eclaircie ×3,8 elle plafonne a 2,35:1 et denature une vue sombre a dessein. #6b737b rend 3,77:1 sur la barre sombre ET 3,76:1 sur la claire, donc UNE declaration sert les deux themes. TROIS classes et non deux : AudioView.fxml declare sa feuille sur SA PROPRE RACINE, donc plus profond que les feuilles d ecran - a specificite egale elle gagne, et la surcharge serait juste dans le fichier et sans effet a l ecran. DEPASSE l ADR 0046 (une classe = une feuille) sur un cas qu elle n avait pas prevu, la feuille tierce, et son garde ne peut pas le voir : il balaie src/main, le jar est hors champ. Le contraste se mesure donc SUR LE RENDU, seul dispositif qui attrape une montee de version deplacant la cible #3462, finitions de recette (#3424)
3464 TROIS fois dans le meme chantier, une rangee HBox a mis un controle loin de ce qu il designe, et trois fois le test etait vert : « Copier » a ~500 px du chemin qu il copie (#3464), la meme configuration prete a se reproduire (#3882), et le lien « Voir cette version » ABREGE EN ELLIPSE a 111 px pres (#3876). Meme mecanisme : le LIBELLE portait hgrow, donc il prenait toute la largeur et comprimait ses voisins. Le ressort va donc a un Region VIDE. Un controle qui DESIGNE le texte voisin se pose contre lui ; un controle qui ne designe rien - « Choisir… », qui ouvre un selecteur - peut vivre au bord. La propriete « ce bouton se lit comme designant ce texte » n est PAS assertable : le test cliquait et verifiait le presse-papier, il passait avec le bouton a cinq cents pixels de sa cible. C est la passe 8 qui l attrape, et l ADR 3672 est respectee - il y a trois cas, pas deux, et le troisieme vient d un garde #3464, finitions de recette (#3424)
3470 Un utilisateur a lu « java.lang.reflect.InvocationTargetException » et rien d autre de tout l incident. Le message n etait pas ABSENT mais PRESENT ET INUTILE, ce qui explique qu aucun test ne le signale : un texte non vide ressemble a un message. Le defaut n est PAS propre a la reflexion - TOUS les constructeurs (Throwable) de la JDK posent le toString() de leur cause comme message. On montre donc le message le plus profond QUI PARLE, jamais celui du maillon qu on tient. Ce n est PAS « prendre la cause racine » : la plus profonde peut etre un NPE muet, et derouler jusqu au bout appauvrirait l alerte en ayant l air de la corriger. La troisieme condition - ecarter un message qui n est que le toString() de sa cause - vient d un ROUGE INATTENDU ; sans elle on remplacait un nom de classe par un autre. Trois chemins non nominaux tenus, dont la chaine CYCLIQUE que initCause permet #3470, finitions de recette (#3424)
3947 L ADR 3470 avait ecrit la regle et n avait aligne QU UN appelant : huit autres composaient leur message a la main, dont le filet global de la CLI. L obstacle suppose etait faux - la regle ArchUnit EXCLUT le socle commun, rien n aurait rougi. Ce qui faisait tenir le montage etait l INLINING par javac d une constante de compilation, invisible et cassable sans rien faire rougir. CauseLisible descend donc en commun.model, et la constante du libelle s INVERSE : la vue cite le modele. Le repli « ou regarder » devient un PARAMETRE : la CLI n a pas de menu principal, et lui en designer un aurait mis une consigne inapplicable dans un terminal - le defaut de 3470 deplace d un cran par sa propre correction. Le cliquet ne compte que les TROIS formes decidables ; la forme nue est indiscernable d un refus metier #3947, cloture des finitions de recette (#3424)
3978 Habillage.poser verifiait la presence de base.css pour decider si le trio etait pose. Vrai de MainView, faux d EcranReglages - seul FXML a declarer palette+base sans design. Le symptome n a paru que dans la GALERIE : en production l ecran est empile dans le chrome dont il herite, et l utilisateur a toujours vu le produit. On en a tire un diagnostic faux et un correctif qui contredisait l ADR 3374 en silence, par la route qu elle ecarte. Un point de passage garantit l ENSEMBLE, jamais un de ses membres ; et son garde vit sur LUI, pas sur ses appelants. Troisieme occurrence du meme motif sur cette classe, et le garde d idempotence n en a attrape aucune : il rejoue sur une scene deja habillee, quand les defauts naissent au PREMIER appel #3978 et #3985, cloture des suites (#3424)
3990 La meme commande ecrit sa date DEUX FOIS differemment : « 15/06/2026 » dans son texte, « 2026-06-15 » dans son --json. Ce n est pas une incoherence - un format d echange est une INTERFACE, pas une preference d affichage, et le franciser casserait les scripts et le tri lexicographique. Le test du --json assertait huit cles et NI date NI deposeLe : rien n empechait de le franciser par souci de coherence, et rien ne l aurait signale. Les deux cles sont desormais assertees - une decision de NE PAS changer n est tenue que si un test rougit quand on la defait. Hors decision : deux commandes portent des DATETIMES a decalage, ou la question est de FUSEAU et non de format #3990, cloture des suites (#3424)
4002 Une remarque sur DEUX boutons en a corrige 29, et chaque correctif a REVELE le suivant : styler « Copier » a fait ressortir « Choisir… », styler les boutons a fait ressortir le ☰, l habiller a fait ressortir sa HAUTEUR, l aligner a fait ressortir sa LARGEUR. Les quatre fois la CI etait verte, et les quatre fois c est un oeil exterieur qui a vu. Les huit gardes de rendu du depot jugent un controle ISOLEMENT - un texte tient dans son cadre, une surface se detache de son fond - aucun ne juge une RANGEE. On n en fabrique pas : un test d egalite des hauteurs rougirait sur des differences voulues. Ce qui etait mecanisable l a ete : un jeton de hauteur, sur la valeur que les boutons rendaient DEJA. Trois causes supposees ecartees par la mesure avant la bonne, et deux auraient « marche » - rogner jusqu a ce que le garde passe est indiscernable d avoir corrige la cause #4002, cloture des suites (#3424)
4013 Le banc a rendu ✅ sur un film ou RIEN n arrive : tous les viser passaient - ils prouvent qu un bouton etait la et qu on a clique dessus, jamais que le clic a FAIT quelque chose. Le seul geste sans libelle verifie tombait a cote depuis qu une feuille de style avait deplace le socle de 4 px, et le film montrait 34 s d un formulaire jamais rempli. UNE exigence par parcours, a la fin : controler aussi le choix du point a coute trois reglages de coordonnees, alors que l exigence finale le SUBSUME - sans point rattache, l import ne part pas. Elle se pose sur la barre d etat, qui ne defile pas : un controle dans le corps de la page varierait avec ce qu il controle. Le balayage vertical tolere un reflux de CSS et l ANNONCE - pas de 8 px mais de 4 : deux pixels separaient le refus de la lecture juste #4013, suite de #3887
4021 L apercu du prefixe montrait le futur nom d un fichier que l import n ecrirait JAMAIS : TriParSerie retient la serie du journal, majApercu prenait nomsOriginaux.get(0). Pas un hasard de fixture - « 1648011 » precede « 1925492 » dans l ordre des noms, donc l apercu tombait SYSTEMATIQUEMENT sur la serie ecartee. Et l ecran avait l air juste : carre, passage, point, prefixe tous corrects, seul le fichier d exemple faux - sur le seul ecran ou l utilisateur doit comprendre ce qui sera pris et ce qui sera laisse. La regle de tri ne se reecrit pas, elle s APPELLE. Si rien n est retenu, aucun nom n est promis. La methode vit sur le RAPPORT : sur le sous-VM, PMD basculait la classe en God Class #4021, trouvé en filmant pour #4013
4028 Une PR bloquee 4 h 15 sur un apt-get en -qq, dans un job SANS butoir - GitHub laisse courir six heures. Le butoir de #3883 avait ete apprecie pour ce seul job ; vingt-six autres n en avaient aucun, dont ceux qui publient. Les valeurs viennent d une MESURE : environ 4x le maximum des 40 derniers runs reussis. La garde est la partie durable, pas les butoirs - vingt-six valeurs posees a la main se defont au premier job ajoute. Un butoir rend la panne VISIBLE et bornee, il ne la corrige pas : sitot pose, il a montre trois etapes pendant sur le meme apt sous des noms parlant d autre chose. Et un depassement se presente en cancelled, pas en failure #4028, clôture du chantier des films et de la CI (#4013)
4034 Trois etapes de trois workflows ont pendu le meme jour sur apt-get update, y compris SUR MAIN. Le remede avait ete applique a UNE des trois. Une porte unique borne, reprend, et n installe pas ce qui est deja la. Le cache de l etat INSTALLE a un perimetre ETROIT : il ne rejoue pas les scripts post-installation. Ce qui compte n est pas le paquet demande, c est ce qu il TRAINE - ffmpeg tire DIX paquets de polices, et le premier run qui a trouve le cache a fait tomber cinq cas du banc, drawtext ne trouvant plus de police. Un cache ne se prouve pas au run qui le REMPLIT : celui mesure avant fusion affichait Cache not found, le suivant est tombe #4034, clôture du chantier des films et de la CI (#4013)
3689 Depuis #3687 l ecran cesse de proposer une reprise sur une unite refusee definitivement, mais RIEN ne la rearme quand la cause exterieure est levee : une nuit dont toutes les archives ont ete refusees reste coincee. Les trois declencheurs evidents rearment tous A COTE de la cause - au lancement (un jeton se renouvelle a la CONNEXION), sur un geste « forcer la reprise » (le bouton qui ment, sous un autre nom), apres un delai (un droit refuse ne se repare pas seul). Une unite se rearme donc sur l evenement qui pouvait plausiblement lever SA cause : 401/403 par une reconnexion reussie, 400/422 jamais. Le prix : le statut n existait que dans le TEXTE de message_erreur, que le depot s interdit de relire - d ou une colonne cause_refus (V41), decidee a l emission #3689, suite de #3900
4071 Le cadrage disait « il n y a pas de troisieme voie » ; trois mesures l ont renverse HORS de Windows : le lanceur natif jpackage rend la sortie, l erreur separee et le code 2 sous Linux, et arguments ecrit le mot dans le .cfg, ou il ne sert QUE si personne n a donne d argument. Un point d entree unique lit donc un mot ECRIT - ihm ouvre la fenetre, tout le reste part en texte - au lieu de deduire d une absence, figure que ferme l ADR 3828. Deux enveloppes sur la MEME classe principale, la console reservee a Windows ou le sous-systeme est inscrit dans l en-tete PE a l edition de liens. Le second lanceur HERITE des arguments du premier : sans la cle, vigiechiro tape seul ouvrait la fenetre. Un cas n a pas d equivalent sur ce chemin - une borne abaissee par -D - et il SAUTE en le disant plutot que de rendre un vert creux, ce qui a fait ouvrir #4075 #4071, suite de #619 et #2104
4079 Le train du mercredi a REUSSI et n a rien livre : tag, CHANGELOG et Release crees, puis installers et publish SAUTES, brouillon sans un seul asset, run vert pendant huit jours. La sortie tag valait pourtant v2.186.0 : la condition n etait pas fausse, elle n a JAMAIS ete evaluee. GitHub propage le « saute » de facon TRANSITIVE, et un if: sans fonction d etat est enveloppe en success() && (...) sur tout le graphe amont. Le piege a ete arme par une amelioration : #3770 a mis en needs une garde que le train programme saute toujours. !cancelled() reprend la main, needs.X.result == 'success' referme ce qu il ouvre - seul, il publierait sur un amont ROUGE. La garde est la partie durable : deux if: corriges a la main se defont au prochain needs ajoute en amont, c est ainsi que le defaut est ne. Un vert de garde n est PAS un artefact parti #4079, EPIC livraison (#2104)
4103 Le Flatpak etait publie par un workflow MANUEL : rien ne reclamait ce geste, donc le paquet retardait sur les releases et une publication reussie qui le laisse en arriere est un etat parfaitement VERT. Mesure en verifiant sur un poste que la CLI de #4071 marchait : le manifeste extrayait le .deb 2.185.0 quand la 2.187.0 etait publiee, donc la commande absente du paquet pendant que la doc l annoncait. DEPASSE l ADR 2744, qui avait tranche « rien a rebrancher » : elle raisonnait a moyens constants - release: released ne part jamais au GITHUB_TOKEN - et workflow_call n est PAS un evenement, il s execute dans le run de l appelant. Le train appelle donc flatpak.yml apres avoir retire le brouillon. needs: publish et non installers : le checker interroge releases/latest, qui IGNORE les brouillons. Le chainage ne s observe qu au premier train, release.yml ne tournant pas sur les PR #4103, suite de #4071
4111 Les clips de recette se tournaient A LA MAIN, et recette-filmee.yml posait lui-meme la condition de son branchement - le harnais de recette, aujourd hui en place (EPIC #3667 clos, 403 cas lus). Meme defaut que l ADR 4103 sur un autre dispositif : une version publiee sans tournage laisse en ligne les clips d une version anterieure, etat parfaitement VERT. Pire que pour un paquet : un clip a TOUJOURS l air juste, puisqu il montre un produit qui fonctionne. Le tournage part donc avec le train, apres publish - ni la veille, ni le matin, ni a chaque commit, qui sont trois suppositions de DATE quand la recette valide une VERSION. Et la pre-version dit desormais ce qu elle montre : automatiser sans nommer la version aurait produit des clips justes et INDATABLES, le defaut deplace d un cran. Cout mesure : 5 min pour 58 clips. La premiere redaction rangeait capture-vues.yml dans le meme cas : FAUX, il tourne deja sur chaque push et chaque PR - un artefact COMMITTE suit le code, un artefact publie a cote suit les versions #4111, suite de #4103
4134 TestFX reutilise LA MEME fenetre primaire dans un fork : une classe qui la dimensionne, la deplace ou la FERME laisse cet etat a toutes les suivantes, et seulement dans l ordre ou la repartition les a mises. Le defaut est revenu CINQ fois (#1940, #1967, #3452, #4130, #4145), toujours signale par une classe qui n y etait pour rien. L ADR 3960 disait « rendre l etat » et les deux bancs le faisaient - ils reposaient la LARGEUR. Mesure : figee a 900x300 la fenetre ignore la scene suivante ; apres sizeToScene elle vaut 33x270, puis 369x504. LA VALEUR N EST PAS LA PROPRIETE. Un banc ouvre donc la sienne, initOwner sur celle du harnais, et la referme avec lui. Deux gardes : sur les SOURCES (aucun Stage recu n est fige) et sur la PROPRIETE (on pose une scene plus haute, la fenetre doit suivre). sizeToScene DEFIGE : le premier jet du garde de propriete l appelait avant de mesurer, et son mutant a SURVECU - il defaisait le defaut avant de le chercher. Le plancher de 600 px (#3452) masque la mesure si les deux scenes tiennent dessous. La classe qui HEBERGE le garde de #1940 etait la cinquieme fautive : elle prenait le Stage du harnais comme modale, et « Echap ferme la modale » le fermait pour tout le monde Amendée par l'ADR 5663 : la plateforme de test écrit l'état de la JVM sans le rendre, dans un fork qui n'est qu'à elle #4134, clôture de l'EPIC #4133
4142 Sur les 360 cas de recette non couverts, environ 220 vivent dans des sessions dont l objet est HORS de l application - serveur reel, carte SD, vrai poste, vrai terminal. Un clip a frontiere bouchonnee y est CONVAINCANT ET CREUX : il ne devient pas faux, il devient MUET SUR SON PROPRE OBJET, ce qui est pire parce qu on le regarde en croyant savoir. S4-33 ecrivait deja sa reserve de lui-meme, et RIEN ne l exigeait. Tout cas cite declare donc sa portee, SANS VALEUR PAR DEFAUT : c est le compilateur qui pose la question, a l ecriture, quand celui qui ecrit sait encore ce que son scenario truque. Ecart assume avec Jugement, qui porte un defaut parce qu une SECONDE SOURCE le contredit quand il est faux - la portee n en a pas. Une portee hors application exige une reserve, et elle seule ; la reserve doit figurer SUR LA PAGE du clip, personne ne lisant une annotation en regardant une video. Resultat le plus utile : les 57 cas couverts sont TOUS a l ecran, ce qui dit ou est la difficulte. Categorise les cas COUVERTS, pas les 403 declares #4142, EPIC #4133
4166 La revue des clips a formule la meme remarque TROIS FOIS sous trois formes - « on devrait voir la connexion avant de voir que le bouton existe », « il faudrait la meme video avec la creation qui AJOUTE un carre », « ne montre pas ce qu il doit » - avant qu on entende qu il s agissait d un seul principe. Un bouton grise, un bandeau masque, un voile qui a cede, une liste qui n a pas change : ce sont des ABSENCES, et une absence n a pas d image. Un cas qui fait juger un etat montre donc cet etat ET son contraire, dans le meme clip - dans le temps, par le voisinage, ou via un cas jumeau que le script nomme a cote. Corollaire : un clip qui remplace le GESTE par son effet montre une consequence dont la cause est hors champ. La regle n oblige pas a FABRIQUER le contraire : quand il semble introuvable, demander d abord « sur quelles donnees ai-je mesure ? » - S1-17 a ete dit infilmable au vu d une fixture de deux sites, et le voile dure un demi-seconde sur cent cinquante carres #4166, EPIC #4133
4188 Cinq constats de la revue des clips disaient la meme chose sous cinq formes : annuler ne cree rien n avait aucun endroit ou se voir, la fenetre se ferme, la fiche s ouvre aucun ecran d arrivee a montrer. Ces tests montent Modale*.fxml SEULE, et le clip montre une modale flottant sur du NOIR - ni cause ni effet, c est-a-dire rien de ce qu un cas existe pour faire juger. Un cas qui passe par une modale se filme donc avec les DEUX ecrans qui l encadrent : celui d ou part le geste, fait par un clic sur son bouton, et celui ou l on retombe, tenu assez longtemps pour qu on voie ce qui a change. Il n y avait AUCUN obstacle technique : les modales du produit s ouvrent en show(), jamais en showAndWait - la raison qu on se donnait ne valait que pour les Alert du socle. La confusion a coute cinq clips illisibles et deux classes baties sur un double inutile. Les classes qui montent une modale seule gardent leurs ASSERTIONS, pas leur cas #4188, EPIC #4133
4234 L affordance #789 tient en deux temps : un geste impossible se ferme, et son motif nomme ce qui manque. Quatre cas de recette existaient pour faire juger le SECOND, et aucun ne le montrait : ils lisaient le texte de l infobulle par programme, l assertion passait, et le film ne montrait qu un bouton gris. « Ne montre pas ce qu il doit », disait la revue - le constat portait sur la moitie du cas qui n etait pas filmee. Un cas dont l objet est qu un geste dit ce qui l empeche FAIT PARAITRE ce motif par le survol, et l attente de son apparition est une ASSERTION : un motif qu on ne peut pas faire venir n existe pas pour l utilisateur. Ecarte : afficher le motif en permanence, ce serait changer le produit pour filmer le produit ; et Tooltip.show(...) pose par le test montrerait une bulle surgie de nulle part #4234, EPIC #4133
4235 Le preambule d un scenario filme pesait 494 lignes pour cinquante cas, et les trois plus lourds 47 a 69 lignes POUR UN SEUL CAS : ecrire un cas neuf revenait a recopier celui du voisin. Le point decisif n est pas la : FenetreDuBanc EXISTAIT DEJA et faisait ce qu il fallait, et trois classes sur onze ne l utilisaient pas - elles avaient copie un preambule anterieur a sa creation. Une abstraction que rien n impose est contournee par le prochain copier-coller, c est-a-dire par ce qu elle pretendait supprimer. On pose donc le garde D ABORD, puis l abstraction. Le garde porte une liste d attente NOMMEE ET FINIE quand la migration ne peut pas se faire d un coup - une liste, pas un interrupteur - et un compteur d inspection qui refuse zero. Et il mesure la propriete, pas un proxy : chercher la chaine MainView.fxml a declare fautive la premiere classe migree, qui monte le chrome sans le nommer #4235, EPIC #4133
4248 Le banc bash filme l'ÉCRAN (x11grab), donc le pointeur y figure parce que le système l'y dessine. Le banc Java rend le GRAPHE DE SCÈNE (Scene.snapshot), où le pointeur n'existe pas et où une touche pressée ne laisse aucune trace : une modale s'ouvrait sans qu'on voie ce qui l'avait ouverte (« dans S1-27, le clic qui ouvre la modale n'a pas le halo »). Un banc qui filme de l'intérieur dessine donc lui-même le geste : halo de l'appui, flèche ancrée par sa pointe, badge du raccourci. Il n'invente rien, il observe les événements par des filtres qui ne consomment pas. Corollaire assumé : pas d'événement, pas de dessin - un test qui lance le Runnable d'un accélérateur sans presser la touche ne produit aucun badge (#4242), et le défaut est alors dans le test #4248, EPIC #4133
4274 Deux tournages du même scénario ne placent pas leurs gestes aux mêmes instants : comparer l'image n°40 de l'un à l'image n°40 de l'autre compare DEUX MOMENTS DIFFÉRENTS, et rend un écart qui ne parle que de cadence. À la fin du clip le scénario est POSÉ - mesuré, l'écart y retombe sous 0,01 % pour 48 cas sur 51. On compare donc la DERNIÈRE image, accompagnée de la présence du cas et de la durée du clip. Contrepartie assumée : on compare la destination, pas le chemin, et cette limite mord précisément là où l'ADR 4166 demande le plus - un cas qui montre un état ET son contraire a son sens dans le CONTRASTE entre deux moments, dont l'image finale ne garde qu'un #4274, EPIC #4295
4287 Le bruit n'est pas une propriété du dispositif mais DU CAS : deux tournages du même commit sur deux runners donnent une médiane de 0,008 %, 48 cas sur 51 sous 0,05 %, et trois qui montent jusqu'à 0,809 %. Aucun seuil unique ne tient - le pire plancher AVEUGLERAIT 48 cas pour se protéger de trois (un libellé changé vaut 0,364 %, il passerait dessous), la médiane ferait CRIER ces trois-là à chaque tournage. Un écart se lit donc contre le plancher de son propre cas, tenu dans un fichier que --plancher accumule en gardant le PIRE observé. Le fichier porte le nombre de paires qui l'ont produit : un plancher tiré d'une seule paire ne prouve pas qu'un cas est stable, seulement qu'il l'était cette fois-là #4287, EPIC #4295
4296 L'ADR 4274 ne retenait que l'image finale, et sa contrepartie mordait précisément là où l'ADR 4166 demande le plus : un cas qui montre un état ET son contraire a son sens dans le CONTRASTE, dont la fin ne garde qu'un côté - plus un cas respectait 4166, moins la comparaison le couvrait. Mesuré sur 51 cas et deux paires, soit 102 mesures : le plancher de la PREMIÈRE image vaut 0,000 % sans exception, contre 0,008 % de médiane et 0,809 % au pire pour la dernière. Stable ne suffisait pas - une mesure toujours nulle peut être fidèle ou AVEUGLE : vérifié, deux cas différents ont des premières images distantes de 2,4 à 3 %. On compare donc les deux bouts, chacun contre son plancher, et le classement retient le plus grand des deux rapports. Les montages du début ne sortent que s'il a bougé, sans quoi cinquante fichiers identiques noieraient les deux qui comptent #4296, EPIC #4295
4309 On reprochait au pire observé de ne jamais redescendre, et un centile était proposé. Les données l'écartent : les maximums isolés étaient des clips à deux fins, qu'il aurait cachés. Le pire reste la règle ; aucun rapport ne se calcule contre moins de 0,0105 %, la moitié d'un chiffre changé ; et le fichier compte les paires écoulées depuis que chaque plancher a été approché, pour que la mesure nomme celui à relire. #4309, lot 4 de #5933
4249 Avec forkCount=1C, l'index qui relie un cas à son clip était écrit par AJOUT : cinq lignes pour neuf clips bien présents sur le disque, et rien ne le signalait. Un fragment par JVM nommé par son PID a tenu sous Linux et cédé sous macOS - trois fragments pour quatre JVM, le système ayant réattribué un PID pendant le tournage. L'identité est donc pid + UUID, et l'index se RECONSTRUIT depuis les fragments sous FileLock à chaque fermeture de JVM. Le défaut était invisible à tout signal automatique (clips présents, tests verts, index construit) et le premier test l'avait figé comme comportement attendu : il vérifiait que le second écrivain remplaçait le premier #4249, EPIC #4133
4264 CadreVisible lisait les bornes de ses nœuds depuis le fil du test, onze appels partant de main. JavaFX ne refuse pas franchement : le symptôme n'était pas une exception mais DEUX INSTABILITÉS qui rougissaient ailleurs, une fois sur cinq, très loin de la cause (#4200, #4187). L'idiome existait pourtant déjà chez AttenteAvantClic. Un helper partagé ROUTE DONC LUI-MÊME : ce n'est pas à son appelant de savoir sur quel fil il se trouve, puisqu'un helper est justement appelé par du code qui l'ignore. Le garde fait UN SAUT, la propriété étant inter-procédurale, et il a été FAUX DEUX FOIS avant d'être juste : vert sans avoir inspecté un fichier (filtre sur un chemin amputé de son préfixe), puis vert sur le vrai défaut (un robot.interact voisin, sans rapport avec les lectures, satisfaisait la règle « le fichier route quelque part »). Les deux erreurs ont été trouvées en MUTANT le code surveillé, aucune en relisant le garde #4264, EPIC #4133
4251 Sept chemins composaient leurs lignes en interrogeant la base POUR CHACUNE - jusqu'à onze requêtes par nuit dans l'audit. Le coût CROÎT AVEC L'INVENTAIRE : nul sur les jeux d'essai, maximal chez qui a le plus de données. On lit donc PAR LOT avant de boucler, sauf les tables de volume (originaux, séquences) qu'un chargement d'un bloc échangerait contre un défaut de mémoire. Le garde compte des REQUÊTES, jamais des millisecondes : la première mesure d'un processus coûte ~300 ms quelle que soit la donnée, lire le code sous-compte (six annoncées, onze réelles), et une session voisine fait varier les relevés du simple au double. LotsDeParametres est CONSERVÉ mais son motif était FAUX - SQLite accepte cinquante mille paramètres, mesuré, pas quelques centaines #4251, #4271, #4278, #4286, #4293
4291 Filmés contre un bouchon, les ~220 cas dont le verdict se lit hors de l'application donnent un clip convaincant et CREUX (ADR 4142) - et le bouchon n'est pas un homme de paille : 135 lignes, la seule ressource sites, aucun If-Match, aucun refus de max_results. Filmer contre la vraie plateforme lève cette limite et en crée trois. Un clip connecté ne se compare pas : son écran suit des données vivantes, le plancher de l'ADR 4287 y mesurerait la plateforme au lieu du rendu, donc pré-version à part et refus explicite côté comparaison. Le secret ne dépasse pas son pas, parce que rien d'autre ne peut le rattraper : le rôle Lecteur est déclaré et AUCUNE route ne l'accepte, GET /moi compris - un jeton en lecture seule n'existe pas. Le jeton meurt avec le run, donc il ne peut pas être celui du contrat hebdomadaire, qui vit de durer. Le premier tir a rendu « Tests run: 0 » et un BUILD SUCCESS : poser -Dsurefire.groups ne lève pas l'exclusion, et un dispositif qui ne sélectionne rien réussit tranquillement. Sa première décision n'était gardée par rien ; elle l'est depuis #4331, par un garde qui n'analyse pas le YAML mais EXÉCUTE le refus qu'il juge (ADR 4331) Amendée par l'ADR 5641 : le refus de comparer vaut pour la plateforme nationale ; un clip tourné sur la plateforme de test, sur un état de départ déclaré, peut se comparer sous le plancher de bruit de l'ADR 4287 #4291
4406 Dix-sept cas de S8 ne decrivent pas une recuperation mais l ECRAN D APRES, et aucun n interroge la plateforme. Mesure : BancDeRecette#montrer cree un espace de travail NEUF a chaque scenario, donc pas de preambule partage - les dix-sept paieraient dix-sept recuperations reelles. L etat de depart se declare dans un fichier lisible et un generateur deterministe le materialise, comme les cartes SD, plutot que de s enregistrer depuis une execution. La tension avec A4 est regardee en face : une base engendree est une ENTREE, ce que les cas observent reste rendu par le PRODUIT ; un cas qui asserterait sur la spec tomberait sous A4. La peremption d un enregistrement disparait avec lui #4406
4444 Le back réel tourne en local jetable, et 22 cas de recette attendaient une écriture. Mesure : le motif était posé au BLOC puis recopié, et les 22 se séparent en sept obstacles, dont huit cas à l'observable purement local qui relèvent de l'ADR 4406. Un back local ne sert jamais de préambule à un cas filmé et ne produit AUCUN clip : sur localhost la latence est nulle, et les cinq cas de transfert y sont les PLUS creux au sens de l'ADR 4142. Il sert de banc d'étalonnage, où s'écrivent hors ligne les sondes d'écriture manquantes, tirées ensuite contre la participation de rebut ; l'écart entre les deux tirs EST la mesure de dérive. Le témoin reste borné par l'ADR 0020, dont les trois défauts renvoyaient 200 et se relisaient. Le renversement qui justifie le banc : aucune des 64 routes authentifiées n'accepte le rôle Lecteur, donc la lecture seule du tournage connecté ne tient que par le câblage Amendée par l'ADR 5641 : le back local devient une plateforme de test qui vit en CI, confrontée régulièrement à la plateforme nationale ; le transfert, la durée et la lecture des écritures restent hors de sa portée #4444, EPIC #4416
4331 Une regle de CI vit parfois dans un run:, c'est-a-dire du code executable range dans une chaine de YAML. Le reflexe est d'y chercher un motif, ce qui juge le TEXTE d'un programme au lieu de son comportement. Mesure : verifie-jeton-vivant.sh avait six cas verts sur sa fonction de verdict, et affichait « HTTP 000000 » des qu'on le lancait - curl -w '%{http_code}' ecrit deja « 000 » quand la connexion echoue ET sort non nul. Le defaut avait traverse trois ecritures. Le garde extrait le shell et l'execute, l'appel se separe du verdict, et le verdict se prend sur le MESSAGE : avec des leurres qui echouent, toute execution sort non nulle et un garde qui lirait le code serait vert quoi qu'il arrive. Ce qui ne peut pas etre extrait le declare (api-live.yml, #4385) #4291
4334 Le portage de la méthode venait d'une ligne de 127 commits ; 21 d'entre eux ne servaient qu'à couper le lien avec un dépôt disparu, et les reprendre aurait effacé 1 589 renvois #N qui ouvrent de vraies issues, 35 ADR et le CHANGELOG. Ils ne sont pas portés, l'article A27 non plus, et la constitution saute de A26 à A28 en disant pourquoi. Le principe qui en sort dépasse ce chantier : un dispositif porté REMESURE ses seuils sur l'arbre qui le reçoit, le cliquet de la javadoc valant 2 470 là-bas et 3 641 ici. Vérification humaine assumée : une décision de ne pas faire ne laisse pas de code, et rien ne peut la garder EPIC #4334
4339 Deux fois dans le même chantier, du texte est entré sans avoir été écrit ici : dix-sept cadratins dans les compétences OpenSpec, dix-sept apostrophes courbes dans les SVG de Mocodo. Vérifié aux octets, la source .mcd porte l'apostrophe droite et l'outil substitue au rendu. Ce qui vient d'un outil amont ne se réécrit pas : l'exemption se déclare, NOMINATIVEMENT, avec sa raison et la mesure qui la prouve. Jamais par préfixe : un septième fichier amont doit faire rougir le garde plutôt qu'entrer en zone franche #4339, #4377, EPIC #4334
4447 Quatre fois dans un même palier, un banc filmé a buté sur une frontière qu'aucune machine d'intégration ne franchit - Open-Meteo, un dialogue modal qui fige TestFX, l'absence de carte son, l'analyse Tadarida - et quatre fois la même décision a été prise sans être écrite. La suppléance se fait A LA FRONTIERE, jamais en deçà : on substitue le port, le confirmateur, le périphérique, et le câblage réel du produit prend le relais. Bouchonner un service n'est pas une suppléance, c'est fabriquer l'écran (ADR 4142). Ce que la suppléance retire au clip se déclare sur la page des clips, à côté du lecteur - « ce qu'il démontre » puis « ce qu'il ne démontre pas ». Et le geste de l'utilisateur reste joué : on clique « Lecture » avant de poser playing, on importe avant de semer #4447, EPIC #4416
4515 Suite de 4339, et sa limite. Les six compétences OpenSpec décrivaient un cycle qui ignore le nôtre, et le canal prévu pour y injecter nos conventions, openspec/config.yaml, n'accepte de règles que sur quatre artefacts et de consignes que sur deux opérations : aucun point d'accroche pour propose ni explore, les deux gestes d'ouverture. Un arbre amont s'adopte donc quand la convention à y inscrire n'a aucun autre canal, jamais parce que sa typographie déplaît. L'adoption se paie en une fois : réécriture, retrait nominatif des exemptions, provenance déclarée, et un garde pour ce qu'elle met en jeu. 9 entrées hors couverture deviennent 3 #4515, EPIC #4511
4516 Amende 4515 et 4339. Les six compétences adoptées avaient laissé six commandes en anglais amont : le même flux en deux versions, et c'est la périmée qu'un humain invoquait. Le générateur ne les engendrera pas, car .claude/commands/ est déclaré hérité par l'outillage et une compétence est déjà une commande : un inventaire ne se duplique pas, il se cite (A5). Six relais d'une ligne, nommés par le geste et non par le fournisseur, remplacent le préfixe opsx. Les dossiers gardent leur nom d'outil, et c'est protecteur : mesuré, un renommage fait cohabiter douze compétences là où il en faut six. L'adoption est enfin gardée, --force faisant tomber les marqueurs de 12/12 à 0/12 #4516, EPIC #4511
4517 Le premier changement OpenSpec du dépôt, sur le lot 0 de l'EPIC #3848. Une nuit relue ailleurs revient avec un avis signé, rangé à côté du nôtre et jamais fondu dedans : une validation naturaliste s'attribue, et deux avis divergents ne sont pas une anomalie à réduire. Deux colonnes additives sur selection_sequence, sur le patron de V26 qui a logé l'avis du validateur du MNHN à côté de celui de l'observateur. La voie générale, retirer le UNIQUE de listening_selection, est écartée sur la mesure : 23 classes lisent le verdict d'un passage. Décision de ne pas faire : l'avis du relecteur s'affiche, il ne vote pas #4517, EPIC #4511
4627 Amende 4517. Le paquet d'emport porte la sélection et non toute la nuit, et la sélection est figée : deux tirages indépendants de trente séquences sur une nuit qui en porte cinq cents ne se recouvrent que sur deux, donc deux avis ne se compareraient pas. Figer la sélection est ce qui rend les colonnes de 4517 opérantes, pas une restriction ajoutée. Coût assumé : le relecteur ne peut plus contester l'échantillonnage. Coût en code : aucun, le plan recevant la liste qu'on lui donne #4627, EPIC #4511
4565 Prolonge 4516. Cinq compétences maison nommaient une chose plutôt qu'un geste et sont renommées ; trois gardent leur nom parce que tdd, mutation et worktree désignent un métier ou un objet que la profession appelle ainsi, et qu'une règle vaut par ce qu'elle rend trouvable. Le comptage annonçait 353 occurrences, dont 178 pour le seul mot mutation ; l'ouverture des citations en rend 22 qui désignent vraiment une compétence. Un comptage n'est pas une lecture #4565, EPIC #4511
4342 Les décisions d'ergonomie argumentaient chacune dans ses propres termes, si bien que deux ADR pouvaient invoquer deux principes contradictoires sans que rien ne le montre. Mesure : 71 ADR rattachées aux huit articles d'usage, AUCUNE ne nommant d'heuristique. Le vocabulaire devient clos et vit dans une annexe, les dix heuristiques de Nielsen, les deux notions de Norman, six lois de la Gestalt et cinq critères WCAG. Une matrice engendrée nomme celles que rien ne sert, et le cliquet vaut 71 : il descendra au fil des chantiers, jamais à zéro, car toutes les décisions d'un article d'usage ne parlent pas d'usage #4342, EPIC #4334
4359 Rien ne disait ce qu'une javadoc doit porter, et la mesure le montre : 3 641 lignes de prose au-delà de huit par bloc, sur 713 blocs dans 572 fichiers, ramenées à 739 sur 319 blocs par les tranches du lot 2. Trois endroits, un rôle chacun : le code porte l'intention, la javadoc dit le contrat et s'adresse à qui appelle, l'ADR dit pourquoi et la javadoc la CITE au lieu de la redire. La dette se tient par un cliquet ouvert à sa valeur mesurée, pas par un nettoyage (article A9) #4359, EPIC #4334
4343 Rien ne disait à qui écrit une ADR, une page ou un message de commit sur quoi se relire. Toute prose qu'un humain lira hors de l'échange qui l'a produite passe la grille de la compétence humaniseur avant d'être commise, et les sept tics de CONTRIBUTING.md en sont le sous-ensemble opposable : la grille sert à relire, les sept servent à refuser. Vérification HUMAINE assumée : aucun motif textuel ne décide si une emphase informe. Trois loupes relèvent ce qui se compte, le cadratin, la javadoc narrative et le pictogramme #4343, EPIC #4334
4366 Le pictogramme d'alerte n'apporte pas l'information : il annonce qu'il y en a une. Mesure : 1967 occurrences du signe sur les fichiers versionnés, dont 1 485 en PROSE une fois écartés le contenu montré, les blocs de code, les chaînes littérales et le signe cité comme jeton. Ce qui doit alerter se dit dans la phrase, ou dans l'encart que le format prévoit. Cliquet à 0, et le garde rend des SUSPECTS : retirer le signe ne suffit pas, une ligne qui ne dit l'alerte QUE par le signe demande d'être réécrite #4366, EPIC #4334
4368 CONTRIBUTING.md énonçait la règle depuis #4343 et rien ne la tenait. Mesure : 188 apostrophes courbes dans 68 fichiers, dont douze seulement dans des chaînes littérales, c'est-à-dire montrées à l'utilisateur ; deux écrans affichaient alors deux apostrophes différentes pour le même mot. Les douze sont corrigées et la zone tenue à zéro. Le garde ne lit ni les commentaires, ni le brief, ni les tests : un cliquet à 188 aurait fait porter une relecture de 68 fichiers à un défaut qui n'en concernait que trois #4368, EPIC #4334
4395 L'article A30 veut que la javadoc CITE l'ADR au lieu de la redire, et le renvoi #N est cette citation. Le même article ouvre un cliquet de 739 lignes de prose à résorber : la citation vit dans la prose qu'on coupe, et un renvoi perdu ne casse rien, il cesse d'ouvrir. Mesure : 3 531 issues distinctes citées dans 1 006 fichiers, dont 1 572 dans les fichiers dont la ligne d'origine offre une javadoc déjà contractée - qui, elle, n'en porte aucun. Un PLANCHER, de polarité inverse au cliquet : descendre est la perte, monter est à déclarer #4395, EPIC #4394
4453 L'article A31 énumérait les surfaces où la prose se relit, et le corps d'issue comme celui de PR n'y figuraient pas - alors que clore-une-issue en fait les DEUX textes qui se relisent dans six mois sans le fil. Le déclencheur y était pour quelque chose : « avant d'être commise » ne peut atteindre un corps de PR, qui n'est jamais commis. Mesure ici sur cent corps : dix-sept refusés, cinquante lignes, trente-neuf cadratins de prose et onze élisions sans apostrophe, dont dix PR ouvertes le jour même de la décision. Un garde de CI en refuse la part mécanisable, informatif comme celui du titre #4453, chantier #4334
4472 Le cliquet 4359 ne compte que les lignes /// : raccourcir une javadoc en poussant son récit trois lignes plus bas le faisait DESCENDRE sans que rien ne soit résorbé. Un compteur séparé, jamais mêlé au premier - les mêler laisserait un raccourcissement compenser un débordement, total stable et verdict vert. La mesure rassure et c'est pourquoi elle vaut d'être tenue : 4 656 blocs, médiane 2, aucun au-dessus de 15. Seuil à 8, cliquet à 24 #4472, chantier #4394
4468 Le lot 2 ne mesurait que ce qu'il RACCOURCIT, jamais ce qu'il a LU - et effacer de la prose sans l'avoir lue faisait baisser le compte, donc le cliquet récompensait la suppression à l'aveugle. Un second cliquet, au grain du FICHIER : il tient qu'aucun fichier neuf n'échappe à la relecture, et qu'aucune javadoc relue ne se réécrit en douce, son empreinte changeant. Il ne tient PAS que la lecture ait eu lieu, ce qu'aucun script ne peut vérifier, d'où probable. Ouvre à 1 979 fichiers, manifeste vide ; aujourd'hui à 0, tout le corpus relu #4468, chantier #4394
4576 La règle R1 veut six chiffres, zéro de gauche compris ; les DEUX sources qui rendent un numéro l'amputent - grille_stoc et le référentiel embarqué, soit 13 342 mailles sur 137 481. L'amputation ne se voit pas : un numéro à cinq chiffres est plausible, et chaque lecteur qui le compare sans le savoir obtient un faux négatif silencieux. Deux l'ont fait pendant des mois, dont l'emprise cartographique, qui ne criait pas : elle se rabattait sur son repli, et un carré de département 01 à 09 sans point géolocalisé n'était pas tracé du tout. Le format se rétablit donc à l'ENTRÉE, une fois par entrée - réparer le point de comparaison ne guérit que le lecteur qui se plaint, jamais celui qui se tait #4576, chantier #4573
4577 Deux questions se ressemblent : « quel carré couvre cette position » est de la GÉOMÉTRIE, « ce carré existe-t-il en Point Fixe » est du PORTAIL. #733 les a confondues, et ce chantier a refait la confusion pendant trois lots. Le carroyage national est pourtant embarqué depuis #325 - 137 481 mailles - et reproduit la plateforme au centimètre : 374,9 m mesurés contre un centroïde à 4 cm. Le geste se calcule donc hors ligne et reste offert sans jeton, dans le cas d'usage même qui a ouvert le chantier : une relève chez soi, un import le lendemain #4577, chantier #4573
4578 Trois classes convertissaient des degrés en mètres avec deux valeurs pour la même grandeur : 111,0 km par degré pour DESSINER, 111 132 m pour MESURER. L'écart de 0,12 % ne se voit pas sur une maille de 2 km, et déplace le seuil des 50 m qui juge deux candidats indiscernables. Unifier coûte dans les deux sens - la mesure dérive, ou toutes les captures cartographiques changent pour un dessin identique à l'œil. Les deux précisions restent, portées par UN type qui dit l'usage à côté de la valeur : la passe 7 avait d'abord documenté la divergence dans une seule des trois classes, ce qui n'avertit que qui ouvre celle-là #4578, chantier #4573
4610 Sur une frontière, plusieurs carrés sont à distance STRICTEMENT égale, et un écart de distance décide qui est trop proche pour être départagé. Deux classes posaient ce seuil, à 50 m et à 100 m, en écrivant DEUX FOIS la même justification. Les valeurs restent : proposer écrit un numéro que l'observateur validera sans le relire - faux et plausible, il contamine le préfixe de tous ses fichiers - tandis que contrôler commente un numéro déjà écrit, où l'excès de zèle accuse à tort quelqu'un qui avait raison. Un seul type les porte, comme l'ADR 4578 l'avait fait pour les conversions : une divergence documentée dans une seule classe n'avertit que qui ouvre celle-là #4610, EPIC #4671
4621 Sur une frontière, « le carré le plus proche » ne désigne rien : deux centres à 997,7 m chacun au milieu d'un côté, quatre à 1 412 m au coin, et 5 m de décalage font basculer le premier. La grille ne stockant que des CENTRES, sa représentation ne peut pas porter la convention d'intervalle semi-ouvert qui trancherait - aucune question ne rendra la bonne réponse, parce qu'il n'y en a pas une. Les candidats se nomment, rangés par NUMÉRO pour que l'ordre ne suggère pas la préférence que la phrase refuse #4621, chantier #4573
4656 Le chantier de code mort a rencontré sept familles de copies, et sept fois la même réponse : aucune n'attendait d'être factorisée, toutes étaient le résidu d'un geste remplacé par une meilleure forme. Devant une méthode morte, la question n'est donc pas « qui l'appelait ? » mais « où vit le même geste aujourd'hui ? ». Les deux ne mènent pas au même endroit : la première invite à rebrancher ou extraire, la seconde fait voir que le travail est déjà fait ailleurs. Factoriser les six executer aurait redonné un nom propre à une requête concaténée sur un Statement brut, quand le dépôt est passé aux PreparedStatement #4656, passe 11 de la clôture
4659 Le dépôt écrit à TROIS endroits que tout chantier se clôt par douze passes, et rien ne le vérifiait : 43 EPIC clos sur 64 n'en portaient aucune trace. La cause n'était pas l'inattention - #4671 a été clos le jour même PAR les douze passes, bilan et artefact compris, et figurait parmi les 43. La compétence clore-un-chantier ne mentionnait nulle part le modèle à coller : qui la suivait à la lettre ne laissait aucune trace sans jamais rien oublier. La passe 12 colle donc la case, et un CLIQUET tient l'absence - il ne peut que descendre, et les 42 restantes sont assumées plutôt que rattrapées à coups de douze passes sur des chantiers clos depuis un an #4659, EPIC #4650
4671 L'ADR 4577 range « quel carré couvre cette position » du côté de la géométrie, donc du hors ligne, et le contrôle pose pourtant cette question au RÉSEAU. L'écran garde la plateforme parce que le contrôle en ligne distingue une issue de plus - Indisponible, qui SE TAIT - et que basculer supprimerait ce cas, ses tests et la nuance de #733 au profit d'une cohérence apparente. La ligne de commande, elle, contrôle hors ligne : ajouter-point est une commande locale, et y faire entrer un appel la changerait de nature. Deux sources, une seule règle de verdict #4671, passe 2 de la clôture
4682 L'ADR 4617 posait un cliquet unique sur les deux zones ; l'ADR 4587, écrite le lendemain pour les renvois, refuse cette forme : « surtout pas un seul sur les deux ». Les deux se sont croisées sans se voir, et le défaut était actif : le chantier #4656 venait de ramener la production à zéro, si bien qu'une méthode morte y réapparaissant pouvait être payée par un NcssCount retiré d'un test, total inchangé et garde vert. Deux cliquets désormais, le pire des deux verdicts, et un seuil de production à zéro qui se lit comme un refus et non comme une marge à resserrer #4682, chantier #4685
4685 Le garde des captures a accusé à tort (#4642) ; en le lisant, un mécanisme réel est apparu, grep -q refermant le tube sous pipefail, et il expliquait tout, sauf cet échec-là : 0 accusation sur 200 essais avec les 4 492 octets du manifeste, 40 sur 40 avec 888 893. Le correctif part quand même, mais il se déclare préventif dans le code, le témoin éprouve le motif et non le cas, et #4642 reste ouverte. Une correction dit ce qu'elle n'a pas pu expliquer #4685, passe 11
4475 Le stage primaire de TestFX est PARTAGE entre les classes d'un meme fork : figé par la première, il ne s'ajuste plus aux scènes des suivantes, qui échouent sur des noeuds « invisibles » très loin de leur cause. Le défaut est revenu QUATRE fois (#1940, #1967 qui prédisait son retour, #3452, puis les scénarios de connexion), trois fois sur la même classe témoin qui n'y est pour rien. 82 suspects, et le garde accepte sizeToScene que FenetreDuBanc prescrit. Le cliquet compte une FORME, une taille affirmée sans que la fenêtre la tienne, et non des classes qui figeraient : mesuré en fork unique, aucune ne le fait aujourd'hui (#4545) #4475, chantier #4462
4476 « Concern extrait de X (Extract Class) », « le geste vivait dans Y » : ces phrases racontent le refactoring, pas ce que la classe garantit. Douze tranches de #4394 en ont retiré à la main sans que rien ne les compte. Le cliquet ne cherche pas un motif mais un VOISINAGE, le verbe d'extraction et le nom de l'outil dans la même phrase : l'élargir au bloc compterait les mentions légitimes. Ouvrait à 62 suspects, resserré à 0 #4476, chantier #4462
4477 Une ADR qui raconte trois pages se lit moins qu'une qui en dit une, donc elle est moins citée, donc la décision qu'elle porte se reperd. Même famille que le cliquet 4359 : ce qui n'est pas compté grandit. 58 suspects sur 195 ADR #4477, chantier #4462
4488 Sept gardes ne lisaient que src/main/java, et AUCUNE ADR ne les y avait restreints : elles sont nees avant que la question ne se pose. Un cliquet ne se plaint jamais qu on lui retire du corpus, si bien que l angle mort grandissait sans rien faire rougir. Le corpus par defaut d un garde de code devient les DEUX arbres ; qui n en lit qu un le dit, avec sa raison. Mesure d ouverture : zero suspect cote test pour les sept, donc aucun cliquet ne bouge. 2635-refus-sans-surface reste bornee a la production, et c est une decision - ses trois suspects sont dans le test qui PROUVE l ADR 2635, lequel doit citer le glyphe du menu. Un cas de verifie_scripts.py tient le CORPUS la ou le temoin de chaque garde tient sa DETECTION : les deux se cassent separement #4488, passe 7 de la cloture de #4462
4490 verifie_scripts.py clot sur « les N scripts charges DETECTENT leur violation temoin », et la phrase affirmait plus que ce que la suite verifie : un temoin peut exister, s executer, passer, et ne rien tenir. Celui du cliquet de longueur d ADR n affirmait que isinstance(suspects(), list) (#4487). L article A2 disait deja le geste, mais il reposait sur la discipline, et la discipline lache quand ca va vite. La mutation devient mecanique : chaque garde perd sa detection, la suite doit rougir, tolerance zero. La liste se DERIVE des appels _charge plutot que d un glob, un glob vieillissant etant le defaut meme que le script attrape. Cout mesure : 1,2 s pour 23 gardes. La cecite est nommee - la mutation ne touche que les fonctions de module, et l unique temoin hors de portee est ecrit #4490, passe 9 de la cloture de #4462
4546 Les trois refus du garde du corps de PR sont typographiques ; « Ferme #N » n'est pas de cette famille. La forge ne reconnaît que close, fix et resolve : la demande fusionne verte, l'issue reste ouverte, et rien ne le signale. Ce n'est pas une forme malheureuse, c'est une promesse non tenue. #4350 avait écarté un garde parce qu'il aurait cherché ce qui MANQUE et rougi sur tout lot d'un EPIC ; celui-ci cherche ce qui est PRÉSENT, forme jamais légitime, et « Refs #N » reste vert. close est absent de la liste des verbes, « Close #N » étant un mot-clé anglais valide : le refuser ferait réécrire en français ce qui marchait #4546, passe 11 de la clôture de #4502
4571 L'ADR 0041 assume qu'on fusionne en rouge : l'information est visible, l'ignorer est un choix. Elle n'avait pas rencontré l'autre cas. #4560 a été fusionnée à 17:13:02Z avec zéro run sur son commit de tête - les sept sont nés à 17:15, deux minutes trop tard - et a laissé main rouge. Un rouge passé outre engage qui le fait ; une fusion sans verdict n'engage personne, faute d'avoir rien eu à lire. Le refus vit du côté du contributeur et non de la forge, parce que le coût d'un check requis est déjà mesuré et qu'un mainteneur unique dispose de toute façon du contournement. Le garde ne juge pas la couleur, et refuse quand il ne sait pas lire #4571, sas des suites #4562
5004 Les ADR 0041 et 4571 posaient qu'aucun workflow n'est déclenché par un événement produit avec le GITHUB_TOKEN. Depuis la 2.189.0, une PR ouverte avec ce jeton lance ses workflows : chaque mise à jour flatpak en laissait 5 à 9, nés sur une branche que la fusion immédiate supprimait, et morts rouges sans rien avoir vérifié. Une PR qu'un atelier ouvre et fusionne dans le même pas porte donc la marque de saut sur le commit de sa branche, et ce qu'elle transporte s'éprouve dans l'atelier. La conclusion des deux ADR tient, mais leur silence devient un choix du dépôt, réversible, que #5722 doit peser. #6213, lot #5004
4586 #4488 avait decide que les gardes de code lisent les DEUX arbres, et verifie_scripts.py le tenait par une liste ECRITE A LA MAIN, qui avait derive : dix entrees pour quinze gardes portant le chemin de l arbre de test. Six n etaient verifies par rien, et un cliquet ne se plaint pas qu on lui retire du corpus. Le corpus se declare desormais dans _commun.py, la liste se DERIVE de ce que chaque garde importe (15 contre 10), et un refus interdit de recopier un chemin #4586, chantier #4502
4587 Le plancher de l'ADR 4395 n'a jamais lu src/test, ou vivent 1 530 renvois que rien ne garde - dont 274 pointant vers une issue que la production ne cite NULLE PART, soit 151 discussions dont le seul lien dans le code est un test. DEUX planchers et non un : un compteur unique laisserait une perte d'un cote se compenser par un gain de l'autre. La disjonction se prouve par mutation dans les deux sens #4587, apres #4646
4636 L'inventaire du portage comparait des NOMS de fichiers, apres normalisation de deux conventions de nommage - et c'est cette difference-la qui avait rendu une loupe portee inerte, comptee comme presente et ne rapportant rien. Un releve lit desormais ce qu'un garde DECLARE : geste, ADR, population, seuil, verdict. Il montre sans juger, 33 ecarts sur 30 gestes au premier passage. Deux limites declarees : le predicat ne se compare pas, et l'appariement par le geste laisse deux gardes du meme sujet en deux absences #4636, EPIC #4634
4617 Une méthode privée jamais appelée a vécu à soixante-quinze lignes de la version correcte du même helper (#4554). Deux trous, qu'il ne faut pas confondre : le jeu ne portait que sept règles de conception, donc le code mort n'était couvert nulle part, production comprise ; et l'assiette laissait dehors 52 % du Java. UnusedPrivateMethod entre, en écartant les méthodes du FXMLLoader par leur forme et non les 42 contrôleurs entiers. Les littéraux dupliqués ne comptent pas en zone de test, où les répéter est le geste juste : ils font 1 366 des 1 428 signalements, et zéro en production. Le filtre vit dans le cliquet parce que PMD ne sait pas l'exprimer, quatre formes essayées #4617, sas des suites #4562
4598 Quatre PR rouges le même jour sur l'espace avant les deux-points. Le dépôt pratique deux conventions à un caractère d'écart, et c'est la plus écrite qui est fausse en PR : 62 des 100 derniers titres d'issue la portent, les 100 dernières PR fusionnées sont à zéro. Le défaut n'entre pas au commit, les quatre partant d'une branche aux sujets conformes et 286 des 297 sujets de branche l'étant : il entre à la frappe du titre, que gh pr create --fill impose dès qu'une branche porte plus d'un commit (10 des 30 dernières PR). Le remède ne crée aucune règle, il fait lancer verifie-titre-pr.sh avant l'ouverture. Aligner les titres d'issue est ÉCARTÉ : soixante-deux renommages pour couvrir un des quatre défauts #4598
4640 Un conflit se constate à trois valeurs et le dépôt n'en avait que deux : la base manquait, c'est-à-dire ce que nous avions vu la dernière fois. Sans elle, « l'utilisateur a modifié la météo » et « la plateforme l'a modifiée » sont indiscernables, et la garde de #4552 s'était rabattue sur la seule question que deux valeurs permettent, celle d'une course de quelques millisecondes. Le dépôt persiste donc un relevé des champs synchronisables, alimenté par les lectures qui existent déjà, sans aucun appel réseau ajouté. Relever l'étiquette à l'ouverture de la fiche est écarté sur mesure : l'ouverture ne lit rien de distant, et une étiquette ne dit ni quel champ ni de quel côté. La règle diffère par champ, les dates ayant chez nous la meilleure source et la météo aucun arbitre. La borne est écrite : ce relevé ne dit pas ce qui est vrai, il dit ce que nous avions vu #4640, EPIC #4640
4770 L'ADR 4490 rend l'article A2 mécanique - un garde neutralisé, la suite doit rougir - mais pour scripts/adr/ seulement. L'étendre aux gardes de méthode paraissait mécanique et ne l'était pas : la neutralisation AJOUTÉE en fin de fichier n'agit que si le fichier est importé, ce que fait le harnais des ADR ; un garde de méthode se lance, et son raise SystemExit part avant. Cinq gardes ont paru décoratifs, dont deux vus rougir sur un vrai défaut le même jour. Elle s'INSÈRE donc avant le point d'entrée, et la fonction d'auto-test en est épargnée - deux gardes nomment la leur sans souligné, et la neutraliser les faisait rougir parce que leur point d'entrée rendait une liste, non parce qu'ils avaient cessé de détecter. Six gardes sans point d'entrée sont nommés plutôt que sautés (#4788) #4770, suites de #4713
4713 Sept endroits affirmaient plus que la mesure, et aucun n'avait jamais rougi : les gardes lisent le Java, les ADR, les balises, les captures - pas la prose de méthode. AGENTS.md prescrivait sous « non négociable » une commande rendant 1 449 violations sur un arbre propre ; ouvrir-une-pr annonçait qu'un plancher périmé sort en 0 quand il sort en 1, et trois PR ont rougi le même jour ; TESTING.md donnait un exemple rendant BUILD SUCCESS sur zéro test - une commande VERTE SANS AVOIR JUGÉ, au moment précis où l'on doute d'une méthode. Le relevé de clôture a mesuré trois populations : 132 chemins cités dont 0 faux, 39 commandes dont 1, et 10 alternatives d'ADR TIRÉES dont 0. Deux cas sur sept se mécanisent, et la règle est étroite par construction : elle porte ce qui se lance, non ce qui se juge. Le corpus se dérive au lieu de s'énumérer, et le motif a été éprouvé avant d'être cru - sa première version signalait le gabarit -Dtest=A,B,C #4713
4712 Le mot « sous-chantier » n'existait nulle part : ni AGENTS.md, ni CONTRIBUTING.md, ni ADR, ni compétence. Entre « un chantier est réparti sur plusieurs PR » et « découper en issues reliées à un EPIC », aucun palier. Un lot multi-PR se retrouvait donc sous une case à cocher, sans périmètre écrit, sans bilan, sans les douze passes, et se terminait sans que personne sache s'il était fini. La forme observée enseignait l'erreur : #4511 porte sept lots et zéro sous-chantier, #3848 quatre et zéro. Plus de deux PR cohérentes, c'est un chantier, et la règle s'écrit là où elle était induite. Deux gardes mécaniques ont été mesurés puis écartés, le second parce que la recherche de la forge n'honore pas les phrases exactes ; la loupe pose la question au lieu d'y répondre #4712, sas des suites (#4562)
4711 Deux ecritures tiennent une concurrence optimiste cote client et se ressemblent au point qu'on les corrigerait ensemble. PublicationPoint compare deux lectures du meme appel, et c'est JUSTE : son corps vient de la lecture qui precede, avant.avecEnPlus(point), donc rien ne s'y perime. pousserVers faisait pareil et c'etait FAUX : son corps vient du passage local, saisi plus tot. La largeur de fenetre necessaire depend donc d'ou vient le corps envoye, pas de la forme de la garde. Sans cette ADR, un lecteur alignerait la premiere sur la seconde par souci de coherence, et ajouterait une table la ou rien n'en demande #4711, lot 1 de l'EPIC #4640
4755 Le lot 1 renoncait des que la plateforme avait touche la meteo depuis notre derniere lecture. Or qu'ils aient ecrit ne dit rien d'un DESACCORD : un collegue qui saisit la meteo pendant que nous n'y touchons pas ne nous contredit en rien, et l'envoi entier etait refuse, configuration comprise. La sortie n'est pas de choisir laquelle des trois valeurs envoyer : c'est d'envoyer la notre ou de TAIRE le champ, une cle absente laissant la plateforme garder la sienne. Le partage devient possible sans que personne n'arbitre. La condition est que taire et laisser tel quel coincident cote serveur : vrai d'un scalaire, faux du dictionnaire configuration que le PATCH remplace. Corollaire : faute de base, la lecture du haut d'appel EN TIENT LIEU, un repli se degradant par la valeur et non en doublant le mecanisme #4755, lot 2 de l'EPIC #4640
4768 V43 ne stockait du bloc meteo que le vent et la couverture, quand MeteoDepot en porte quatre : la base relue en manquait toujours deux, la comparaison les voyait divergentes a chaque fois, et AUCUN envoi ne partait plus sur une nuit portant une temperature. Une reference partielle ne rend pas la garde moins precise, elle la rend toujours vraie donc toujours bloquante - le contraire de l'intuition, et ce qui rend le defaut couteux. La table de reference et le type compare se modifient ENSEMBLE. Invisible parce que les bancs employaient le constructeur a deux arguments, ou l'oubli ne peut pas se voir ; et la premiere confirmation fut circulaire, un mock rejouant l'hypothese au lieu de la tester. Le seul rouge possible vit au DAO, sur l'aller-retour #4768, lot 2 de l'EPIC #4640
4841 Quatre fois de suite un motif est apparu, net, avec des chiffres a l'appui : Respiration avant une assertion, les parcours de bout en bout, waitForFxEvents suivi d'une assertion, un waitFor muet. Les TROIS premiers etaient faux, et le premier avait deja son sous-chantier ecrit dans son cadrage. Un chiffre isole mesure la population CHOISIE, pas le motif : quand 76 % des classes JavaFX figurent au releve des instables, n'importe quel sous-ensemble en rend 76 %. Le denominateur se mesure sur le COMPLEMENT, et les deux taux partent ensemble ou le motif n'est pas declare. Un ecart qui se compte en unites n'est pas un motif ; un facteur quatre en est un. Et un motif qui tient reste un MARQUEUR : un banc qui a ecrit sa propre attente est un banc qui a RENCONTRE le probleme #4841, lot 1 de l'EPIC #4804
4967 Quatre dispositifs lisaient « un EPIC », et trois en lisaient la fausse définition : le label seul, quand le dépôt en désigne aussi par le préfixe de titre [epic] ou [chantier]. Les deux cliquets de clôture filtraient à la requête, donc aucun prédicat local ne pouvait les élargir : sur 154 EPIC clos, 58 ne leur étaient jamais soumis, dont 23 sans aucune trace de clôture. Le cliquet 4659 passe de 42 à 65 sans qu'une clôture ait régressé, et le contrôle qui l'établit est que les 42 se retrouvent parmi les 96 que le garde lisait. La définition vit maintenant dans scripts/_commun/epics.py, partagée par les quatre #4967, lot de l'EPIC #5584
4974 #4847 voulait clore par un cliquet sur private void attendre employant waitFor. La mesure l'a refuse deux fois : les cinq methodes attendre restantes sont toutes legitimes, et neuf reinventions vivaient sous d'autres noms, dont celle du banc le plus instable du depot. Le compte valait donc 22 et non 15. Le cliquet lit les CORPS, jamais les noms : une methode privee, quel que soit son nom, dont le corps appelle waitFor. Il vaut 2 et non 0 parce que les deux doubleClicVersPassage sont des boucles de REPRISE qui disent deja ce qu'elles attendaient ; convertir l'une ferait sortir un AssertionError au premier essai, la ou son catch n'attend qu'une TimeoutException, et la boucle n'aurait plus que l'apparence d'une reprise #4974, lot 1 de l'EPIC #4804
4804 Le chantier #4804 reposait sur des mesures, et SEPT d'entre elles etaient fausses sans se signaler : une coupure reseau qu'un test provoque expres prise pour une panne, un garde VERT dont le mot REFUSE faisait ranger 20 tentatives sur 20 sous une cause fausse, une mutation jamais appliquee comptee comme tuee, un grep lisant le fichier au lieu de la methode, deux aides qui rattrapaient rangees parmi les muettes, trois heuristiques rendant trois comptes, et un banc repute instable qui detectait un vrai defaut du produit. Une mesure se controle donc avant d'etre crue, par le controle inverse, l'echantillon lu, le cas negatif ou le succes instrumente. Aucun garde ne peut la tenir : il faudrait qu'il connaisse l'intention de la mesure #4804, cloture, passe 11
5068 #4696 a ete fermee SANS remede, sur une mesure : le releve compte ce defaut a 1/1234 sur 21 jours et il n'est pas retombe, donc convertir 38 sites n'est pas ce que la mesure designe. Mais une dette fermee sans compteur cesse d'exister pour tout le monde, et 38 peuvent devenir 45 sans que rien ne le dise. Le cliquet vaut 38, la valeur mesuree. Il borne les sites EXPOSES et non les defauts : une reference tenue sur un noeud qui ne bouge pas est sans danger. Trois formes sont ecartees, chacune ayant fait surcompter : un selecteur litteral se resout au moment du clic, une constante String en est un sous un autre nom, une citation en commentaire n'est pas un appel #5068, lot 1 de l'EPIC #5041
4859 La suite abandonnait ses repertoires temporaires jusqu'a 13 730, remplissant un tmpfs de 16 Go, apres quoi elle echouait sur un message de quota qui envoie chercher une regression de code. Rien ne les comptait : un banc qui n'enleve rien est VERT et le restera, son defaut ne se voyant qu'ailleurs et plus tard. Un banc referme donc ce qu'il ouvre, par @TempDir, et un cliquet tient le compte, 202 a sa pose puis 4 au fil des lots, ce qui reste ne venant plus d un banc. Le compte est DIFFERENTIEL : compter le total ferait rougir le reliquat de la veille sur le poste de n'importe qui, et le garde serait desarme en une semaine. Il ne peut pas etre un test, la propriete ne s'observant qu'une fois tous les forks rendus : deux pas encadrent la suite dans le job. Limite ecrite : il attribue a la suite ce qu'une session voisine cree en meme temps, mesure a 237 contre 198 #4859, sous-chantier du lot 2 de l'EPIC #4804
4187 Un rouge de CI se rejouait a l'aveugle, et l'issue en tirait que la suite rougissait sur des pannes du runner. Sur 21 jours, 1 233 tirages et 55 relances, la mesure refuse ce remede : le runner pese 9 %, et 56 % des rouges rejoues sont nos propres bancs, qu'aucune conduite ne repare. Un rouge se classe donc avant de se rejouer, et un sur cinq seulement vaut un rejeu ; les autres reviennent au tirage suivant, chez quelqu'un d'autre. La cascade existe a deux niveaux et un seul etait modelise : 11 tentatives ne portent aucun test tombe, seulement une annulation disant qu'une etape voisine avait deja rougi. Ce qui se lit est la FIN du journal : lire le texte entier rangeait 20 tentatives sur 20 sous une cause fausse, un garde VERT imprimant aussi le mot REFUSE. Une cause non reconnue se nomme INDETERMINE plutot que de s'inventer #4187, lot 3 de l'EPIC #4804
4783 La grille nomme six traces d'outil depuis #4776 ; cinq se comptent par une expression et rien ne les comptait. Le relevé rend zéro sur 372 370 lignes, et deux précédents s'opposaient : le zéro des connecteurs se garde, onze occurrences n'ont pas justifié de règle. Ce qui les sépare est la forme de l'arrivée : un zéro se perd d'un seul collage, et la trace est quasi probante. Trois exemptions nominatives, dont la grille elle-même, qui rendrait 22 marques sans elle #4783, chantier #4748
4787 Trois cas sur six gardaient un NON-EFFET, et sur des raccourcis débranchés les trois seraient verts. Mesuré : retirer du produit la condition peutEnregistrer laissait le cas vert, un verdict étant déjà posé au moment de la frappe - aucune relecture ne l'aurait vu, c'est la mutation qui l'a dit. Le même défaut avait frappé deux fois dans le palier : « Annuler ne touche rien » vert parce que la modale ne touchait jamais rien, « les cinq plus contactées » vert faute d'une sixième espèce. Un cas qui garde une absence relève la présence DANS LE MEME CAS, et l'état où le non-effet est attendu se construit au lieu de se supposer #4787, EPIC #4416
4781 Un garde lancé d'un autre exemplaire mesurait CE dépôt-là sans le dire, et le lanceur des cliquets écrivait sur des verdicts pris ailleurs A3
4788 Six gardes sur quinze étaient sans preuve au titre de A2, signalés en sortant 0 : un signalement sans coût n'est pas lu A2
5692 check=False ne couvre pas un exécutable introuvable : un gh ou un git absent fait lever un FileNotFoundError avant tout code de sortie, et le dispositif s'arrête sur une trace au lieu de nommer la panne. Un outil externe absent fait donc REFUSER, par un filet qui attrape OSError ou une sonde shutil.which. Décidée par #5692 pour gh sans jamais être écrite, alors que trois scripts la citaient ; étendue à git par #6058, qui en portait 61 appels nus : gh reste à zéro, git descend par cliquet. #5584, lot #5692 ; #6213, lot #6058
4649 Deux gardes du dépôt interrogent la forge. Celui-ci devait balayer toutes les issues ouvertes et assignées ; la mesure l'a écarté, la population fautive passant de zéro à un puis de nouveau à zéro en une demi-heure, parce qu'on s'assigne une issue avant d'avoir tranché son chantier. Un balayage global aurait rougi chez tout le monde pendant cette fenêtre, ce que l'en-tête de 4659 dit avoir voulu éviter. La portée se resserre donc au lieu que la sévérité ne s'affaiblisse : le garde juge l'issue que SA demande ferme, et reste un butoir #4649, chantier #4643
4829 La règle qu'une issue appartient à un chantier vivait à quatre endroits en prose, et le lien nulle part : une case cochée à la main. Sur les vingt-trois entrées du sas #4562, vingt-deux étaient de la duplication et rien ne signalait la vingt-troisième, seule à porter un fait qui n'existait ailleurs. Le rattachement devient une sous-issue ; le corps d'un EPIC garde la description d'un lot, jamais l'index de ses issues #4829, chantier #4643
4902 Deux passes nommaient une compétence déjà convoquée ailleurs dans le cycle, avec des étapes taillées pour l'autre moment. La question s'est posée deux fois le même jour et les réponses sont opposées : trier-les-issues et la passe 9 sont deux gestes, donc deux compétences ; les passes 0 et 11 sont les deux bouts d'un même geste, donc une compétence à deux fonctions de garde nommées. Ce qui décide n'est pas le nombre de passes #4902, chantier #4882
4903 76 clips de recette qu'aucune passe ne regardait. Le raisonnement par la destination donnait la passe 4, qui écrit docs/ ; il est faux. Un clip visualise l'état de l'application, donc après la 7, et s'appuie sur le cas que la 6b pose, donc après elle. La passe 8 est la seule position possible, et elle y gagne un second objet : l'écran se juge sur ce qu'on y lit, le geste sur ce qu'il fait #4903, chantier #4882
4926 L'orchestrateur pose qu'une passe se conclut sur une mesure reproductible. La passe 6 en demande deux, et le dépassement était silencieux. Les deux ne mesurent pas la même chose : des tests ajoutés sans survivant éliminé passent sans juger, des survivants éliminés sans test dans la bonne famille durcissent ce qu'on regardait et non ce qui manquait. Seule exception, nommée des deux côtés #4926, chantier #4925
4828 L'ADR 4515 posait que la doctrine entre dans les fichiers lus au moment du geste, et le plus gros corpus de méthode était resté dehors : dix passes de clôture sur quatorze n'avaient de détail que dans une page que rien n'oblige à ouvrir. La colonne « Compétence » du tableau annonçait plus qu'elle ne tenait, et son cas le plus retors nommait une compétence qui porte de vraies étapes, celles d'un autre geste #4828
4890 Loger les quatorze passes dans autant de compétences a produit trois répétitions, une par compétence écrite : l'orchestrateur pose une règle générale et l'étaye d'un cas qui vient nécessairement d'une seule passe. Ce qui décide est de quelle passe la trouvaille est ; une preuve qui ne vient d'aucune reste chez l'orchestrateur. Tranché une fois sur les quatorze plutôt qu'au fil #4890, chantier #4946
4918 Le dépôt savait qu'un test peut être vert pour la mauvaise raison ; le cas miroir a mordu deux fois le même jour. Un auto-test qui n'observe que le code de sortie confond « ce contrôle a vu le défaut » et « quelque chose est allé de travers ». Un cas déclare donc ce qu'il doit voir, et une mutation qui casse la syntaxe est rejetée plutôt que comptée #4918, chantier #4946
4852 Deux features qui ne se connaissent pas rendaient un echec COMME UNE ABSENCE : enOptionnel aplatit quatre issues en un vide, detaillerSelection retirait la sequence illisible sans un mot. On reessaie une coupure, on ne reessaie pas ce qui n'existe pas. NOMMER plutot que refuser, un canal qui rend compte est ABSTRAIT et jamais par defaut, et l'avertissement passe DEVANT l'avancement. Le revers rend la regle applicable : avaler un cas est permis quand on l'ECRIT, et cinq occurrences sur six le declaraient deja #4852, cloture passe 11
4853 Deux suites d'une meme cause, et DEUX FOIS la mesure a refuse le remede demande. #4666 voulait extraire une regle dupliquee : la mutation a survecu, Path.resolve rend deja un argument absolu, les deux exemplaires copiaient du code du JDK. #4767 voulait desamorcer un constructeur : trente alignements sur toute l'histoire, TOUS designes par le compilateur, et le vrai cout etait le diagnostic. Une regle a pour foyer le type qui porte la donnee ; un remede que deux fichiers utilisent est une etagere, d'ou 86 sites ; et une decision de ne pas faire s'ecrit #4853, cloture passe 11
4922 Rien ne mesurait si l'usage d'OpenSpec progressait. La fraction « N capacites sur M » n'a pas de denominateur : le depot en offre cinq incompatibles. Un cliquet compte donc le DEFICIT, les clotures qui n'ont pas repondu a la passe 10, et une loupe montre la couverture sans juger. #4922
4846 AGENTS.md posait que les passes 1 a 9 gardent leur numero, 35 citations sur 42 vivant dans des ADR immuables. L'archivage OpenSpec ne pouvait aller a aucune extremite : il precede l'ecriture des ADR et conditionne le bilan. Une passe se range donc ou son effet est juste, et le corpus se renumerote par regle : ce qui designe une passe par son numero suit, ce qui raconte un fait date garde son compte. #4846
4992 La règle du critère de fin était portée par les quatre surfaces de méthode et par rien d'autre. Deux dispositifs la tiennent désormais, et aucun ne bloque : un rappel en commentaire au moment où un lot est ouvert ou édité, une loupe hebdomadaire sur le stock que l'évènement ne voit pas, la forge n'émettant rien au rattachement d'une sous-issue. Le rouge attaché à une demande de fusion a été écarté par trois auditeurs : il tomberait sur qui n'a pas la main. Le gabarit d'issue l'a été par la mesure, zéro corps de formulaire sur 1 563 issues. Un libellé opposable aussi, le critère s'écrivant de trois façons dont deux sortent de la compétence. Le stock ne descend que si quelqu'un lit le rapport, et c'est le prix assumé #4992, chantier du « fini quand » (#4961)
4984 Le modèle alertait quand l'enregistrement SORTAIT de la nuit astronomique, c'est-à-dire précisément quand l'observateur faisait ce que le protocole demande : enregistrer au moins de 30 minutes avant le coucher à 30 minutes après le lever. Le protocole est un PLANCHER, le dépasser est un fait et non un défaut, et la marge est une constante nommée du protocole, jamais une tolérance. L'énumération du modèle nomme un état du domaine - COUVERTE, INCOMPLETE, INDISPONIBLE - et la gravité se décide à la surface : le premier jet la nommait d'après les niveaux de sévérité, seconde échelle dans le modèle que l'amendement de l'ADR 0038 nomme, et que la passe 0 de la clôture a trouvée en relisant cette ADR-là. Le troisième niveau, la nuit interrompue en son milieu, n'est PAS livré et c'est dit : la complétude d'un cycle est consommée au seul import et n'est persistée nulle part. Déduire un trou d'un intervalle silencieux a été refusé par la mesure, une nuit calme et une nuit interrompue s'y ressemblant et le dépôt n'ayant qu'une seule nuit réelle dix-huit fois recopiée sous-chantier #4984, clôture passe 11
4961 La règle exigeait un critère de fin sans dire où l'écrire, et le dépôt en pratiquait trois : une ligne du corps de l'EPIC, le corps de l'issue du lot, la ligne « Ce que je vérifierai » du bloc de prise. Le critère vit dans le CORPS DE LA SOUS-ISSUE. Un lot n'est plus une ligne depuis #4829 mais une sous-issue native, si bien qu'une règle qui le range dans l'EPIC décrit un support quitté ; et l'énumération devient une donnée, ce dont la loupe de l'ADR 4992 dépend. Pas le bloc de prise non plus : il part en commentaire, et le corps est ce qui survit à l'onglet fermé. Le comptage qui a servi un jour à justifier de ne pas relire les critères mêlait 118 chantiers antérieurs à la règle et ne cherchait qu'une formulation : un comptage qui sert à renoncer se vérifie avant de renoncer #4961, clôture passe 11
5053 Un garde qui lit une source DÉRIVÉE n'a pas la population de sa source. Mesuré sur le rapport PMD : 425 fichiers et 1 493 violations, toutes en zone de test, la production n'y ayant aucune entrée parce qu'elle est PROPRE et non parce qu'elle n'a pas été lue. Compter les entrées aurait donné lus=0 en production et fait refuser une zone irréprochable. lus compte donc les unités vers lesquelles le garde a été POINTÉ : 1 226 fichiers de production, 854 de test. Le verdict distingue enfin « zéro violation » de « PMD n'a pas tourné sur cette zone » #5053, sous-chantier du compte lu (#5015)
4993 Montrer a l observateur ce que huit correctifs changent A L ECRAN supposait un avant/apres, donc le meme cas joue sur deux versions. Or le cas qui demontre un correctif est ecrit AVEC lui : il n existe pas dans la version d avant. Le raisonnement d ouverture en tirait un GEL DES FUSIONS, et il se mordait la queue - ecrire les cas etait l un des lots, donc le gel aurait bloque huit correctifs pendant tout le sous-chantier. Il reposait sur une premisse fausse : git garde le code fautif indefiniment, et un avant se reconstitue a tout moment, soit en appliquant l inverse de la production sur main, soit en partant de son parent pour y greffer le scenario. On ne defait que la PRODUCTION : le scenario reste celui d aujourd hui, sans quoi la paire montrerait deux gestes differents. Le test echoue alors, et c est voulu #4980, sous-chantier #4993
5015 Le compte des appels de verdict qui ne déclarent pas ce qu'ils lisent s'est arrêté à QUATRE, et ce plancher n'est pas de la dette. Trois sont des témoins du harnais, dont deux éprouvent précisément la sémantique du compte non déclaré : leur mettre lus= détruirait ce qu'ils gardent, en rendant les tests verts. Le quatrième signale des reliquats et sa population vide est sa RÉUSSITE, or lus=0 refuse. Un tel garde ne déclare rien et écrit pourquoi dans son propre fichier, avec ce que l'exception coûte : ici, un motif qui cesserait d'apparier rendrait « aucun reliquat » en silence #5015, sous-chantier du compte lu (#5006)
5054 Les premiers cas éprouvant le refus sur population vide affirmaient une seule chose : « quand on vide sa population, le garde rend zéro ». Ils passaient, et ils étaient DÉCORATIFS : la neutralisation de l'ADR 4490 remplace chaque fonction par lambda: [], si bien que l'assertion restait vraie sur un garde mort. Le faux vert du chantier, reproduit dans le cas écrit pour l'éliminer, et trouvé par le garde des témoins. Un cas affirme donc d'abord que la population DISCRIMINE, puis qu'elle se vide ; c'est la première assertion qui rougit sous mutation. Le corpus de l'ADR 4490 passe de 27 à 29 gardes #5054, sous-chantier du compte lu (#5015)
5087 La demande #5078 bumpait pitest-maven et ses dix-neuf checks sont passes au vert sans qu aucun n execute pitest. Trois bumps ont eu ce sort. La carte se DERIVE du pom.xml et des flux : sur neuf profils, ecj porte deux versions mais maven.yml l exerce en demande, et mutation porte les deux seules qu aucun flux pull_request n active. Elles se declarent donc dans un manifeste, avec ce qui les atteste, et un garde confronte le pom a ce manifeste - la valeur EST la marque, comme l empreinte de relus.txt. Un INVARIANT et non un cliquet : une divergence est fausse ou elle n est pas. Ce qu il ne fait PAS : tester pitest. Il refuse le SILENCE, le filet qui repond etant nocturne et refusant de juger une demande #5087, chantier #5584
5089 git ls-files et git diff --name-only ÉCHAPPENT les chemins non-ASCII par défaut, ce qui les rend invisibles à tout outillage qui teste ensuite l'existence du fichier, EN SILENCE. Mesuré le 1er septembre : une passe du graphe a écarté 50 fichiers de brief/ et pris 6 renommages pour 56 suppressions, sans qu'aucun garde rougisse. 101 chemins sur 3 203 étaient fautifs, tous sous brief/, et tous déjà en NFC : le défaut est le jeu de caractères, pas la normalisation Unicode. Un chemin suivi ne porte donc que de l'ASCII, à tolérance zéro. La règle ne dit rien de la casse ni des espaces, que core.quotePath n'échappe pas ; et la prose, les titres et le texte des liens gardent leurs accents, la tension avec l'article A24 étant assumée #5089, chantier #5088
5093 L ADR 4984 annoncait que le troisieme niveau, la nuit interrompue en son milieu, n etait PAS livre faute de donnee persistee, et que le lot #5030 la persisterait. Il l a fait, et #5093 l a rendue - mais pas comme un troisieme NIVEAU de couverture : comme un SECOND AXE. La couverture lit les heures contre la fenetre calculee, la completude lit le journal du capteur, et les quatre combinaisons existent : une nuit peut couvrir la fenetre ET s etre interrompue. Un niveau de plus aurait ordonne la gravite et force un arbitrage entre deux mesures qui ne se comparent pas. Chaque axe se replie sur son propre « je ne sais pas », le journal etant CIRCULAIRE : son silence ne prouve pas que la nuit fut entiere. Et la presentation ne conclut pas au-dela : le journal atteste sa propre fin, jamais celle de l audio, ce qu un libelle a pourtant affirme pendant des semaines (#5352) (complete 4984) #4980, lots #5030 et #5093
5125 Le format --contrat de #5009 portait quatre dispositifs, qui disent COMMENT un garde juge : cliquet, plancher, loupe, invariant. Le sous-chantier #5117 a porté scripts/adr à 41 contrats sur 41 points d'entrée, et trois d'entre eux ne rendent aucun verdict : rapport.py agrège, resserre_cliquets.py écrit, verifie_scripts.py éprouve les gardes eux-mêmes. « (sans objet) » aurait passé le garde en rendant ces trois natures indiscernables. Un point d'entrée qui ne juge pas déclare donc ce qu'il EST, le vocabulaire passe à sept valeurs closes, déclarées dans la seule constante DISPOSITIFS, et un mot hors de l'ensemble fait rougir. Élargir reste possible et coûte une ligne ; élargir en silence ne l'est plus #5125, sous-chantier #5117
5157 L'ADR 5125 a clos le vocabulaire des dispositifs sans dire lequel choisir quand un outil en fait plusieurs. Le sous-chantier C a d'abord écrit « ce que la CI appelle », règle muette pour trois outils sur vingt-quatre : l'un refuse mais n'est lancé qu'en auto-test, deux ne figurent dans aucun atelier. La règle retenue est ce que l'outil fait quand on l'appelle sans mode, parce qu'un contrat déclare ce qu'un point d'entrée EST et non ce qu'un atelier en fait. Un mot dont la raison ne se lit pas dans une aide s'écrit à côté du contrat #5157, sous-chantier #5154
5218 Cinquante scripts sont passes en Python, et l ADR 5188 disait que « c est une relecture qui trie ». La mesure dit le contraire : quatre fois un auto-test etait vert pendant que la sortie differait, et aucun des quatre n a ete trouve par un cas ni par la relecture du diff. Un portage se prouve en lancant les deux versions mode par mode, avec un leurre par outil absent, et le seul ecart tolere - l alignement en octets contre caracteres - se declare une fois #5218, sous-chantier #5215
5219 Cinquante fichiers ont change de nom, et le depot les nomme a des centaines d endroits. Ce qui DESIGNE suit le renommage, enforced_by, javadoc, appel de workflow, parce qu un pointeur faux ne date rien : il casse. Ce qui RACONTE garde le nom d epoque, parce qu une ADR est immuable et qu un fait date reste vrai. Mesure a la cloture : sur 65 renvois en prose a des scripts disparus, un seul etait devenu faux pour un lecteur qui agirait #5219, sous-chantier #5218
5257 L ADR 4490 exige qu un auto-test ROUGISSE quand on retire au garde sa detection. Mesure : sur 43 gardes de CI, 9 rougissent en PLANTANT avant leur premiere assertion, ce qui ne prouve rien. Un banc rend donc TROIS comptes dont la somme vaut sa population, et ne refuse que sur un decoratif. La 4490 affirmait aussi qu un faux positif serait « bruyant » : mesure a l inverse, un verdict « decoratif » se lit comme une trouvaille et non comme une panne d outil #5257, chantier #5215
5239 Une fois les gardes d images en Python, fallait-il lire les pixels par une bibliotheque plutot que d appeler ImageMagick ? Non : compare -metric AE -fuzz N% a une definition precise du « pixel different », et la remplacer changerait ce que le chiffre veut dire - tous les planchers mesures par cas deviendraient faux. La confrontation avant/apres reste possible, et elle a servi : 32 mesures sur les captures reelles du depot sortent identiques. Une bibliotheque l aurait rendue impossible. Et la couche qui juge tout le reste ne gagne aucune dependance #5239, sous-chantier #5235
5188 La cible des deux langages, Java pour la production et Python pour l'outillage, ne vivait dans aucun fichier du dépôt : seulement dans le corps d'un EPIC, que la clôture archive. Elle interdisait pourtant d'écrire un contrat shell, engageait tout auteur de garde futur, et portait une condition de levée qu'une règle introuvable ne lève jamais. Bash disparaît, ce n'est pas négociable, et là où il est toléré il doit aussi être remplacé : une tolérance est un délai daté dont la levée DÉCLENCHE la conversion. Un cliquet à 50, polarité descendante, empêche la seule chose qui rendrait la cible inatteignable, qu'on en ajoute #5188, chantier #5102
5201 Quatre chiffres du depot sont devenus faux en dix jours, aucun trouve par un garde : un nombre plus petit que la realite ne cloche pas dans une phrase. Mesure sur 52 candidats lus un par un : 23 ne sont pas des inventaires, 16 datent un incident, 13 sont des populations vivantes - dont UN SEUL est verifiable sans deviner sa definition. Trois questions dans l'ordre : le chiffre porte-t-il ? sa definition est-elle ecrite ? alors seulement s'ancre-t-il ? Aucun dispositif n'est livre, et c'est la decision #5201, chantier #5202
5175 Le garde des contrats annoncait confronter le champ population ; il le faisait pour 26 sur 67 et s'abstenait pour 41, en silence. La cecite avait laisse passer #5176. Cause mesuree : ce n'est pas la prose declaree qui bloque, c'est l'inference, 40 fois sur 40, tous calculant leur racine depuis __file__. Mais confronter ne conclut pas : quatre des cinq ecarts sont des descriptions PLUS PRECISES que le chemin. Le verdict dit donc ce qu'il a confronte, une loupe signale le reste, et aucun des deux ne refuse #5175, chantier #5006
5102 Le chantier qui donne aux gardes un --contrat pour cesser de les deviner a refait six fois le meme defaut dans les outils ecrits pour le combattre : une mention comptee pour un dispatch, une chaine de fixture lue comme un appel, un import replie invisible d'un motif, un temoin verifie existant, une population relevee par grep, un homonyme local. Quand un dispositif a besoin de savoir ce qu'une chose FAIT, il le lui demande : il la lance, ou il lit sa declaration par ast, ou il declare sa cecite. Une reconnaissance de forme reduit des candidats, elle ne conclut jamais #5102, chantier #5006
5169 L'ADR 2385 exige que la doc chiffrée se confronte au code, et exclut explicitement « une liste tenue à la main ». REMERCIEMENTS.md annonçait 92 contributeurs et en listait 90, et aucun code ne sait combien de personnes ont participé à la SAÉ : l'information n'existe pas dans le dépôt. Une balise d'inventaire peut donc s'adosser au document qui fait autorité sur sa propre population, à condition que ce document dise ce que le chiffre compte. Le garde tient une cohérence interne, pas une vérité extérieure : une personne oubliée de la liste fait baisser les deux nombres ensemble, et le fichier le dit #5169 et #5178, chantier #5162
5065 Le pré-check rendait « conforme » quand il n'avait rien pu juger, et se repliait en silence sur une autre fenêtre que le diagnostic. Un verdict distingue désormais trois états, jamais deux, et nomme la source de second choix sur laquelle il statue. Sœur produit de l'ADR 2748. #5065
5211 L'ADR 4992 assumait le silence du rappel de critère de fin par « la loupe hebdomadaire balayant le stock ». La phrase était fausse : la loupe ne lit que les sous-issues OUVERTES et ne passe que le lundi à 6 h UTC, donc sur 386 lots clos nés depuis la règle, 49 seulement ont pu traverser un de ses passages, soit 13 %, la médiane de vie d'un lot étant de 4,4 h. Trouvé sur #5684, où le rappel a commenté, a été ignoré, et le lot a été clos sans critère nulle part. Le rappel parle désormais à DEUX moments, le second à l'ouverture d'une demande qui ferme le lot, et il NOMME les lots muets. Rien ne refuse toujours : l'arbitrage de #4961 avait écarté le ROUGE, pas le signalement, et un refus tomberait sur 20 % des lots #5211, lot de l'EPIC #5584
5258 La section « batterie locale » d'ouvrir-une-pr annonçait quatre gardes rougissant en CI hors de rapport.py ; ils sont trente, et la page en nommait trois. Un garde confronte désormais ce que la page prescrit à ce que les ateliers lancent, et son cliquet est à zéro. Sœur de l'ADR 4745 : la prose de méthode est de la prescription, et une prescription se confronte à la machine. #5006, lot #5258
5278 Soixante-trois attentes lisaient le graphe de scène depuis le fil du test, là où Attente.queSurLeFil existe depuis #4408 pour le lire sur le fil FX. Un IndexOutOfBounds d'index égal à la longueur en CI est la signature de cette lecture concurrente. Cliquet à 63, dérivé des lectures de nœuds et non d'une liste de classes. #5277, lot #5278
5307 Le choix du dispositif de désignation d'un fichier était écrit douze fois en dur, dans douze contrôleurs de six paquets : il n'existait aucun endroit où le changer, et introduire un second dispositif l'aurait dupliqué douze fois de plus. Selecteurs est désormais le seul. Cliquet à zéro, qui ne borne pas une dette mais compte une population devant rester vide : manquer un site ne casse rien, l'écran oublié ouvre le dialogue du système et a l'air juste. #5307, chantier #5282
5329 ordre-alternatif rejouait la suite entière en fork unique et ordre inverse, tenant le chemin critique à 20,4 min et n'aboutissant pas quatre fois sur dix. Il est réparti en quatre lots dérivés de l'arbre, la graine tournant d'un passage à l'autre. Ce que la répartition coûte est nommé : une pollution entre deux classes de deux lots devient invisible sur un passage donné, et c'est la graine qui reconstitue la couverture au fil des passages. L'union des lots est confrontée au corpus classe par classe, un compte égal ne prouvant pas une couverture égale. #5329, chantier #5294
5310 Le réglage qui tranche entre les deux dispositifs de désignation vit dans Reglages, et aucun des douze écrans appelants ne l'a injecté. La fabrique devient donc un objet injecté, sa fenêtre restant un argument de méthode : ce que l'ADR 5307 refuse de lier dans l'injecteur est SelecteurFichier, dont le choix dépend d'une fenêtre inconnue de lui, et non la fabrique. Cette ADR précise la 5307 plutôt que de la contredire, une ADR ne se réécrivant pas. #5310, chantier #5282
5335 L'ADR 4659 tient la FORME d'une clôture, un garde comptant les EPIC clos sans trace ; rien ne tient sa PROFONDEUR, et cinq passes sur quatorze avaient été cochées sans être tenues à la clôture de #5277. Trois candidats ont été joués contre le seul témoin disponible, les deux traces de cet EPIC, et aucun n'est rouge sur la première puis vert sur la seconde : les 14 cases sont cochées des deux côtés et les 14 libellés ont changé. L'argument porte sur la famille et pas sur un candidat : une trace est un auto-rapport, donc un dispositif ne peut exiger que sa forme, et une forme coûte moins que le travail qu'elle atteste. Comparer la trace au delta est exclu par construction, les deux traces décrivant le même delta. La profondeur se tient par la relecture d'un tiers, et rien ne la refuse #5335, lot de l'EPIC #5584
5340 Un agent qui a fini ne savait pas quoi lancer : tout lancer coûte ~50 min, deviner produit un banc tantôt disproportionné tantôt insuffisant. La population déclarée depuis #5006 est de la prose, donc injoignable à un git diff, et l'inférer est un cul-de-sac mesuré (13 gardes sur 41). Un champ chemins facultatif s'ajoute, et un garde qui ne le déclare pas est lancé : la porte est juste dès dix déclarants sur 72, et le cliquet la rend précise par tranches. #5340, chantier #5294
5282 Le spike de convergence avait etabli que les deux raisons d'etre du banc bash etaient techniquement solubles cote Java, sans mesurer ni le cout d'un parcours porte, ni ce qu'un clip reel donnerait. Les deux manquants sont livres : une prise de 30 s ou le dialogue s'ouvre, le dossier se designe et le chemin arrive dans l'ecran, sans composition. Le cout va d'abord dans le mauvais sens - un parcours Java fait 158 lignes utiles contre 37 en bash - mais le total decide : 8 x 158 = 1 264 contre 8 x 37 + 3 360 = 3 656, l'orchestration bash disparaissant au lieu d'etre portee. #5311, chantier #5282
5334 Une assertion posee juste apres un geste asynchrone lit un port que le travail n a pas ecrit ; elle passe presque toujours, et son echec se classe « flake ». Trois criteres STATIQUES ont ete essayes sur les 64 sites d une forme de surface : l executeur declare en designe 48, « aucune attente devant » en designe 0 une fois les aides partagees suivies. Le defaut se cherche donc par MUTATION : ExecuteurTacheDiffere retarde le travail, et une assertion pressee tombe dans le trou a tous les coups. Neuf sites designes, zero defaut - le dispositif a etabli qu ils tiennent en NE rougissant PAS. #5334, chantier #5357
5281 Les enregistreurs deposent leurs WAV a la racine ; les seize specs de recette produisaient un bruts/ sans qu aucune ne puisse en decider. La branche du parc n etait donc jouee par aucune recette, alors que InspecteurDossier la gere expres. Le defaut de la spec devient la disposition du PARC, une seule carte gardant bruts/ pour que l autre branche garde sa recette. Un controle qui sert le produit ne peut pas etre plus strict que lui : carte_utilisable exigeait le sous-dossier et rejetait une carte reelle. #5281, chantier #5357
5285 Le banc de recette n'a pas de gestionnaire de fenetres, et ses clips montrent une scene nue ; un lecteur de la documentation doit savoir qu'il regarde une fenetre. La decoration est donc dessinee, ce que l'ADR 3788 n'interdit pas : son mensonge portait sur la MISE EN PAGE, et ce cadre-ci entoure une scene rendue a sa taille reelle. Le focus, lui, ne se lit pas avec isFocused(), qui rend vrai pour toutes les fenetres sous Monocle headless : il se lit a la modalite, et c'est la ligne la plus facile a « simplifier » a tort de ce chantier. #5285, chantier #5282
5345 Le banc de mutation neutralise chaque garde puis le relance : son coût croît linéairement avec le corpus. Le chantier #5294 y ayant ajouté six gardes, lint est passé de 9,6 à 11,3 min et est devenu le chemin critique : le dépôt s'est ralenti en se gardant mieux. Le banc ne mute donc que les gardes du diff. Deux replis le tiennent : toucher le fonds partagé mute tout, et sans base on mute tout. Une portée vide conclut en le disant, là où un corpus vide refuse. #5345, chantier #5294
5373 La porte de la batterie s'arrêtait au Python, alors que ce dépôt teste sa documentation comme du code : cinq classes Java lisent des .md. C'est ce qui a coûté un aller-retour en #5356. Les déclarer est la liste que l'ADR 3450 refuse, sauf qu'un garde la confronte à une population dérivée de l'arbre, donc une sixième classe non déclarée fait rougir. Une liste qu'un garde confronte n'est plus une liste. #5373, chantier #5294
5398 La porte écartait un garde à arguments en lisant sa sortie : première ligne commençant par « Usage ». Un vrai refus débutant par ce mot était donc retiré du compte des refus, et la porte finissait verte. Deviner ne marche pas : les deux gardes concernés emploient deux idiomes, SystemExit et argparse, avec des codes et des longueurs différents. L'exemption est donc déclarée et confrontée. La confrontation est asymétrique : une déclaration périmée refuse, un garde neuf non déclaré est simplement compté refus. #5398, chantier #5380
5407 Un garde qui refuse faute d'un prerequis rend un verdict qui ressemble a un defaut du diff : le cliquet 4617 a ete classe « environnemental » six fois de suite en une session, alors qu'il portait un depassement de seuil reel. Ce que le depot declare, il le pose - a la creation du worktree pour ce qui est bon marche, et depuis la porte pour ce qui depend du diff. Ce qu'il ne peut pas poser, il le refuse en le disant : une preparation muette qui echoue rendrait la porte moins sure qu'avant. Il propose une installation, il ne l'impose pas. #5407, chantier #5404
5376 Le remède évident au coût de la CI est le filtre paths:, et ce dépôt l'interdit. Deux décisions le condamnent : un job qui ne tourne pas ne rend aucun verdict (ADR 4571, qui exclut skipped de ses conclusions probantes), et un job absent du récapitulatif ne se distingue pas d'un job vert (ADR 2748). Le job tourne donc toujours et une étape décide ; quand elle dit non, il conclut « sans objet » en 5 à 9 s, facturés une minute. Chaque portée nomme son propre atelier, d'où une demande d'outillage qui rallume tout. #5376, chantier #5380
5414 Huit sessions travaillent ce dépôt et la méthode était écrite pour une : deux prises du même défaut à 23 secondes, une demande ouverte 9 secondes avant la fusion du même correctif. Le protocole ajoute quatre gestes, et aucun garde ne peut les tenir : un message ne laisse aucune trace, et la forge enregistre le compte jamais la session. L'ADR 4829 disait qu'une règle de plus en prose ne suffit pas ; elle avait une donnée disponible, ici il n'y en a aucune. Le choix est entre la prose et rien. #5414, lot #5412
5402 Le chantier annonçait trois lecteurs dans scripts/_commun/ et un seul existe : attache.py et index.py sont absents, et leurs deux sous-chantiers vivaient dans des cases à cocher, donc sans critère de fin et invisibles à la loupe 4992, qui compte les sous-issues. Un « non » à la promesse n'a que deux issues, livrer ou décider de ne pas livrer : ils sortent en #5463 et #5464, sans --parent puisqu'un EPIC fermé ne porte pas d'enfants ouverts. Le corps de l'EPIC restera faux après sa fermeture, et c'est le prix assumé : cette ADR est l'endroit où le lecteur qui bute sur l'écart trouve la raison. #5402, décision de clôture
5430 Les cinq gardes migrés passent de 0,18 s à 6,26 s, soit un facteur 35, parce qu'ils partaient de la lecture la moins chère de toutes. Ce que le motif rendait n'était pas le même verdict plus vite : String s = "}" tronquait le corps d'une aide, donc son lookup( disparaissait, donc l'attente qui lui délègue échappait à un cliquet à zéro - un faux négatif que rien ne distingue d'un succès. Le coût se circonscrit par les chemins du CONTRAT, jamais par un retour au motif ni par une restriction au diff, qu'un cliquet ne peut pas prendre sans rendre un compte partiel. #5430, chantier #5402
5452 Quatre exemptions reconnaissaient leur population à un IDIOME d'écriture - un souligné initial, un nom portant « auto » et « test », une définition locale de verifie, un cas.append - et les quatre laissaient passer ce qu'elles prétendaient couvrir. Dix-neuf détections étaient hors d'atteinte de la mutation ; mutées une à une, sept faisaient rougir leur auto-test et six survivaient. L'exemption se dérive désormais du GRAPHE D'APPEL, le nom n'étant conservé que comme filtre pour rendre le changement monotone : 119 fonctions sont entrées dans la portée, pour un garde reclassé. Frontière avec l'ADR 5398 : inférer d'une surface incidente reste refusé, dériver de la chose elle-même est prescrit, et quand aucune capacité n'est lisible on déclare #5452
5464 #5464 ecrivait sa frontiere en TROIS questions - qui appelle cette methode, quel type implemente ce contrat, ce champ est-il lu ailleurs - et ses trois lots ont livre la PREMIERE. La cause n est pas un renoncement mais un decoupage : les lots ne nommaient ni les implementations ni les champs, et personne ne les avait ecartes. Les deux restantes sortent en chantier enfant #5553 - 117 interfaces et 6 982 champs, mesures par arbre.py - ce qui applique l ADR 4712. La troisieme voie, clore en laissant la promesse a moitie tenue, aurait produit un bilan juste et une cloture fausse #5464, passe 0 de sa cloture
5532 Le lot 3 promettait un garde sur les methodes sans appelant externe. La mesure l a refuse : elles sont 10 376 sur 14 816, soit 70 % du corpus, dont 5 014 cas que JUnit appelle par reflexion, et le reste domine par des aides intra-fichier toutes vivantes - nettoyer en compte 77, zero appelant externe, toutes vivantes. L index sert donc a REPONDRE : son consommateur n a ni cliquet ni suspects, et son seul code non nul est l absence de l index, qui rendrait « aucun appelant » pour toute methode. Il est un releve, donc sans CONTRAT, donc hors des trois bancs : lui en donner un le ferait entrer au banc sans un mot #5532, chantier #5464
5533 L'ADR 5475 avait conclu qu'aucune position n'est fiable dans un refus, donc qu'il fallait en montrer deux lignes plutôt que d'inférer une structure que les gardes ne partagent pas. Sa prémisse est retirée plutôt que réfutée : on leur en donne une. Un refus déclare sa cause et son geste, la porte les lit OÙ QU'ILS SOIENT, et ce qui change n'est pas le nombre de lignes mais QUI décide lesquelles - la position hier, le garde désormais. Mesuré : 130 gardes peuvent sortir non nul, le code 2 est la convention avec 28 sites contre 22 en 1, et trois codes divergents sont nommés. Le repli à deux lignes reste la règle pour les gardes sans forme, et lit_le_refus rend None plutôt que de deviner : c'est ce qui permet de les convertir un à un #5485, chantier #5533
5539 Ce dépôt écrit des engagements datés dans ses issues, et rien ne les lit : les deux qui existaient ont échoué, l'un fermé treize jours avant sa propre date, l'autre échu sans que personne le voie. Une loupe les relève dans les deux sens, ouverte et échue, ou fermée avant sa date. Le signal n'est pas la date mais le VERBE qui engage : 45 issues ouvertes portent une date et 56 de ces dates sont passées, presque toutes des dates de mesure. Deux règles d'exclusion, dérivées de faux positifs réels : une ligne qui nomme une autre issue, et une citation entre guillemets. Une loupe et non un garde, parce qu'un refus ferait retirer la date pour livrer #5539, chantier #5538
5553 L ADR 5532 est ecrite au singulier, pour le seul index d appels. Le chantier en a livre deux autres sur le MEME modele Spoon, et la regle se transpose sans que sa raison se transpose d elle-meme. Mesure du 2026-09-29 : la part du corpus sans voisin externe vaut 69 % pour les appels, 22 % pour les contrats, et 92 % pour les champs - 8 196 sur 8 934. Le troisieme est donc le plus tentant et le moins defendable : un garde bati sur cette liste signalerait presque tout le corpus, donc rien. Les trois REPONDENT, aucun ne compte de suspects ni ne porte de cliquet, et leur seul code non nul est l absence de leur index. Ce qui n est PAS interdit : un garde sur un sous-ensemble motive, comme le UnusedPrivateField que PMD juge deja dans la classe declarante #5553, prolonge #5532
5562 L'ADR 5015 répond à « sur combien ? » ; ce chantier a rencontré trois fois la question d'après, de quoi cette population est-elle faite, et qu'en manque-t-il ?. Une médiane unique sur un coût bimodal a bougé de 74 % entre deux fenêtres sans que le régime change - 36,0 min à 82 % sans Java, 62,5 min à 39 %. Une mesure déclare donc la composition de ce qu'elle résume (l'effectif accompagne la médiane), nomme ce qu'elle n'a pas pu lire (une forge muette rend « indéterminée », jamais la classe négative : commits/<sha>/pulls rend vide sur un commit rebasé, et vide se lisait « sans Java »), et n'y figure pas (les deux mesures de durée sont croisées, maven.yml se mesurant lui-même depuis #3508). Distincte de l'ADR 4287, qui tranche un seuil : ici rien ne refuse, la conséquence est un rendu #5562, lots #5540 et #5521
5570 Le relevé des harnais incapables de nommer le cas qui lève COMPTAIT sans juger, et son contrat portait l'argument : « refuser dessus reviendrait à bloquer le dépôt sur une dette que ce relevé sert à rendre visible ». C'est l'argument d'un butoir, faux d'un cliquet posé à la valeur mesurée. Le compte était subi : lus=89 muets=74 en septembre, 93 et 75 trois semaines plus tard, sans que personne l'ait décidé. Et sa population s'énumérait par un glob non récursif : huit gardes dont la porte joue l'auto-test en étaient absents, six muets, donc un cliquet à 75 aurait verrouillé le mauvais chiffre et rougi le jour où la mesure aurait commencé à dire vrai. Cliquet à 79 #5570, lot de l'EPIC #5584
5572 Sept décisions traitaient déjà le même défaut - un dispositif rend un verdict sans avoir exercé ce qu'il prétend juger - sous sept vocabulaires, et cinq ne déclaraient AUCUNE relation : chercher les mots d'une forme ne rendait aucune des six autres. Huit instances en un mois sur cinq chantiers, et aucune trouvée par un garde : les huit l'ont été parce que quelqu'un a remesuré ce qu'un autre annonçait. Sept décisions correctes n'ont pas empêché la huitième, donc une huitième de la même facture n'empêcherait pas la neuvième. La remesure est due là où un verdict autorise à ARRÊTER DE CHERCHER, et remesurer veut dire dériver le même nombre par un chemin qui ne passe pas par le dispositif. Écarté : un garde tenant la liste de la famille à la main, qui serait le gage inerte de l'ADR 5483 écrit pour garder l'ADR qui le condamne #5572, chantier #4650
5579 Deux dispositifs lisaient le bloc relations: d'une ADR et n'en lisaient pas la même chose : neuf ADR sur 101. Le défaut n'était pas dans le motif mais dans la COMPARAISON, SUBIES étant un tuple littéral : amendée_par était vu et non reconnu, donc le garde d'encart sortait vert sur une ADR amendée qui n'annonçait rien sous son titre. La règle normalise désormais accents et casse au lieu d'énumérer, et refuse un verbe portant une espace, un verbe étant une clé. Six mutations, six tuées #5579, lot de l'EPIC #5584
5582 Deux décisions refusaient déjà le compteur unique sur deux zones - l'ADR 4682 pour le portail, l'ADR 4587 pour les renvois - et aucune n'avait été appliquée ailleurs. La passe 7 de la clôture de #4650 a croisé les cliquets non nuls du dépôt avec les zones Java que leur gage lit : il restait UN cas, l'ADR 4472, dont les 43 suspects se répartissaient en 24 de production et 19 de test. Un gain de cinq côté test payait donc une régression de cinq côté production, le cliquet restant vert. Le comptage se sépare, la règle ne change pas : le budget de huit lignes vaut des deux côtés, et rien n'établit d'asymétrie de norme - contrairement au portail, où 4617 écarte explicitement les littéraux dupliqués du test. Transposer le mécanisme sans sa justification aurait affirmé une asymétrie que personne n'a mesurée #5582, chantier #4650
5641 Tout ce qui parlait à Vigie-Chiro depuis les tests passait par la plateforme nationale, derrière un jeton de quatorze jours renouvelé à la main, et l'ADR 4444 tenait le back local hors de la CI parce qu'une copie figée dériverait en silence. Elle n'avait examiné que la copie seule. Un test connecté déclare désormais sa cible : la plateforme de test, montée par les tests (API épinglée, Mongo, faux S3 en TLS, front web), au quotidien, sans jeton et écritures libres ; la plateforme nationale, en confrontation régulière. Un test vert sur l'une et rouge sur l'autre est une dérive qui ouvre une issue, et son remède est de remonter l'épinglage. Gardé de 4444 : un transfert ou une durée ne se prouvent pas sur un lien local nu, et un contrat d'écriture n'atteste pas la lecture, d'où le front embarqué. humaine tant que rien ne tient la confrontation : deux tests tiennent déjà la plateforme et la cible d'un scénario (#5699, #5665), et la décision passera à certaine avec #5647 #5641, chantier #5640
5663 L'ADR 4134 veut qu'un banc ouvre son état au lieu d'emprunter celui du fork. La plateforme de test ne le peut pas : pour déposer sur le faux S3 en TLS, elle pose le contexte TLS par défaut de la JVM et les hôtes S3 admis, et ne les rend pas, montée une fois par JVM. Le fork est l'état qu'elle ouvre : toute classe qui la monte, par le banc ou par l'extension, porte le tag plateforme-de-test, que le build par défaut exclut et qu'un profil dédié joue seul. Écartés : un client injecté dans TransportVigieChiro (la production élargie pour un test), la restauration (l'ordre resterait la vraie dépendance), un magasin de confiance au lancement (le certificat naît avec le conteneur). Le cas qui tenait le tag ne voyait que les scénarios, et a été élargi aux tests d'API à la clôture Amendée par l'ADR 5746 : CibleLive est une troisième façon de monter la plateforme, que le garde compte #5663, EPIC #5642
5666 Le lot du job plateforme-de-test exigeait un cache de construction des images. Mesuré d'abord : 20 s en local pour l'image de l'API, une étape de 90 à 131 s en CI sur huit runs de main, et surtout un job qui tourne en parallèle et finit neuvième sur quatorze, loin derrière le plus long (535 à 912 s). Gagner vingt secondes n'avance pas le verdict, donc pas de cache. La question se rouvre si ce job devient le plus long de son run ; la mesure se refait sur plusieurs runs, jamais un seul. humaine, aucun garde ne tenant un rapport de durées qui varie d'un facteur deux selon le runner #5666, EPIC #5642
5746 Les deux classes du contrat live ne visaient que la plateforme nationale, et un saut par assumeTrue sort vert : la cible ignorée, les 29 sondes sautaient sans que le job rougisse. La cible se déclare par le profil (vigiechiro.cible, lue par CibleLive), jamais par l'absence de jeton ; sur la plateforme de test les verrous d'écriture tombent. Rien ne saute, et ce qui saute se dit : le job affiche ses sautés et refuse tout saut, l'état de départ portant ce que les sondes supposent ; deux diagnostics nomment le jeton ou une classe entièrement sautée. Amende 5663 : CibleLive est une troisième façon de monter la plateforme, et le garde la compte #5746, EPIC #5643
4356 #4356 proposait d'enseigner au bouchon de la ligne de commande les pièges que le client absorbe (max_results, RFC 1123, numero, 401/403/injoignable). Depuis #5643, chacun a sa sonde contre le serveur réel de la plateforme de test, à chaque demande. Le bouchon n'apprend rien : il répond ce que nous croyons que la plateforme répond (ADR 4142), et grossir en ferait une seconde source de vérité qui dériverait. La règle reste : tout comportement du bouchon cite sa sonde live. humaine : une décision de ne pas faire ne laisse aucun code à garder #4356, EPIC #5643
4650 Le lot #4554 a livré DoubleClicDeterministe, qui envoie l'événement à la ligne trouvée par son CONTENU au lieu de cliquer une position que la mise en page décide. Douze classes l'emploient sur seize sites. Quatre appels positionnels subsistent et les quatre sont légitimes - mais leur raison vivait dans TROIS commentaires qui ne se connaissaient pas, dont deux disaient la même chose, l'un renvoyant à « la même raison qu'au parcours jumeau ». Le garde ne refuse pas l'appel positionnel, il refuse l'appel positionnel MUET : la frontière reste un jugement, donc elle se déclare au point d'appel (ADR 5398). Il lit l'arbre et non un motif, la javadoc du helper citant doubleClickOn pour dire ce qu'il imite. Posé, il a trouvé le seul des quatre sites dont la raison n'était pas écrite #4650, passe 11
5483 Trois ADR se disaient certaine en nommant un gage incapable de refuser : un atelier hebdomadaire, cent dix-neuf lignes de prose, et le code que la décision régit. Fallait-il un quatrième niveau pour dire « tenu, mais en différé » ? Non, et c'est la mesure qui tranche : trois cas sur 187, de trois causes sans rapport, ne sont pas une catégorie qui manque au vocabulaire. Chacune avait un autre niveau juste - la 3802 en probable sur un garde joué à chaque demande, la 4993 et la 5239 en humaine. Un quatrième niveau leur aurait donné un abri au lieu de les faire corriger. Le vocabulaire clos est lui-même gardé : un verification: hors des trois valeurs fait rougir #5483, passe 11
5481 La porte lançait chaque garde NU quand les ateliers en lancent dix avec --verifie, et pour plusieurs le mode sans argument ÉCRIT au lieu de juger : sur une ADR modifiée, matrice-constitution.py --verifie rend 1 là où le même garde nu rend 0 et réécrit CONSTITUTION.md. Les arguments et les outils se dérivent désormais des ateliers, une forme et une seule, faite de drapeaux ; et ce que la porte ne joue pas se dit SOUS sa ligne de verdict, la position étant la décision. Le critère n'est pas « jouer ce que la CI joue » : elle lance aussi revoque_jeton.py. Limite nommée, celle de l'ADR 5157 : muette là où la CI est muette, vingt-quatre gardes hors atelier, aucun porteur de mode aujourd'hui #5481, chantier #5478
5475 La porte citait UNE ligne du refus d'un garde. Sur les trois refus réels d'une batterie, deux commencent par la cause et le troisième par un titre : aucune position n'est fiable, parce que les gardes ne partagent pas la structure de leur message. On montre donc les deux premières lignes non vides, chacune bornée séparément, plutôt que d'inférer une structure - ce que l'ADR 5398 venait de refuser. Assumé à l'époque : le geste de 4617 est sur sa troisième ligne et restait invisible. Amendée par l'ADR 5533 : le remède annoncé est livré, un refus déclare sa forme et la porte la lit où qu'elle soit ; le repli à deux lignes reste la règle pour les gardes sans forme déclarée, c'est-à-dire la plupart #5475, chantier #5478
5437 L'ADR 3802 disait qu'un test de plateforme passe par une couture, et son seul gage était un workflow HEBDOMADAIRE : quatre fixtures l'ont enfreinte en six jours, après onze corrigées en août. Un garde local refuse désormais l'appel POSIX non déclaré, cliquet à zéro, en acceptant les quatre formes que le dépôt employait déjà. Il lit l'arbre syntaxique et non un motif : sur l'état du 2026-09-06, le motif retenait SEPT fichiers là où le garde en retient deux. Le second motif du chantier, le modificateur clavier, n'a PAS été écrit : population illégitime vide, donc garde indémontrable #5437, chantier #5433
5433 « Ce système porte-t-il POSIX ? » s'écrit en production et dans l'arbre de test, et les unifier est refusé. Trois mesures : UN site d'appel en production, le seuil de #5075 non atteint (29 fonctions en 13 signatures là-bas, deux écritures d'une ligne ici), et surtout la branche qu'une couture injectable exposerait est un MUTANT ÉQUIVALENT, ce que le doc-comment d'attributsDeCreation écrivait déjà avant le chantier. Le test acheté exercerait deux issues indiscernables. Trois ADR déclinent un dispositif pour trois raisons distinctes : l'information manque (5414), la population est vide (5437), la branche est inobservable (celle-ci) #5433, passe 7
5628 L'ADR 3560 a choisi deux médianes glissantes contre un butoir, et ne disait pas de combien deux médianes doivent différer. mutation-ihm.yml a annoncé +59 % pour un écart valant 0,42 dispersion, à corpus constant et avec la même dispersion des deux côtés : rien n'avait changé que le tirage, et l'avertissement a fait chercher une cause inexistante. Un écart ne se conclut donc plus sans sa dispersion, et celle d'une médiane est l'écart absolu médian - l'écart-type groupé inclut le changement de régime, donc aucun des dix ateliers n'atteignait une unité, release.yml et ses +708 % compris ; calculé par fenêtre, il reste trompé par une population bimodale. Le minimum vaut un, mesuré dans le seul trou de la distribution, et la première dérivation était fausse pour avoir compté un atelier que la règle n'atteint jamais #5628, suite de #5615
5629 Le journal de l'enregistreur est circulaire : sa première ligne raconte souvent une nuit importée puis effacée de la carte. L'inspection s'en servait pour dire qu'une nuit était déjà importée, et le contrôle de cohérence pour juger la date. Les nuits d'une carte sont celles de ses enregistrements, le journal n'est cru que pour sa série et les nuits qu'il raconte, et sa première ligne n'est qu'un repli. #5629, lots #5600 et #5631
5669 L'ADR 5629 exemptait de tout jugement de date une carte de plusieurs nuits, parce que le journal circulaire n'en raconte parfois que les premières. L'exemption couvrait aussi un journal d'un autre déploiement qui n'en raconte aucune. Une seule nuit racontée suffit désormais à dire le journal cohérent, et aucune le dit étranger. #5629, lot #5669
5684 L'ADR 4967 justifiait une séparation de conception par un défaut d'outillage que #5673 a corrigé le même jour : sa conclusion pratique était caduque avant d'être lue. La séparation tient, pour une raison qu'elle ne nommait pas : une fonction pure se joue hors ligne, un refus non, puisque sortir en 2 n'est pas une valeur de retour. Les séparer est ce qui permet de voir les DEUX rouges. Elle amende 4967 au lieu de la réécrire, une ADR acceptée ne se réécrivant pas #5684, sas #4562
5707 Un geste du pointeur ne fait pas que bouger : il situe sa cible, et TestFX le fait sur le fil appelant en lisant les bornes de chaque candidat, ce qui itère les éléments de tout Path du sous-arbre - le caret d'un champ de saisie en est un. Une ConcurrentModificationException une fois sur 558 tirages. Le geste situe désormais sa cible sur le fil, et le point vient de robot.point(...) et non d'un calcul à nous : la première version prenait le centre de localToScreen, sans l'intersection avec la scène que TestFX fait, et le clic partait hors de la fenêtre. Un cliquet et non un banc : deux témoins Java ont été écrits et jetés, le fil JavaFX recalculant toute propriété partagée le premier et servant son cache au fil du test. Cliquet à 163, et la population de 5068 y est contenue, 38 sur 38 #5707, lot de l'EPIC #5697
5584 Le chantier traitait les dispositifs qui rendent un verdict sans avoir exercé ce qu'ils jugent, et sa clôture en a produit cinq de plus, toutes dans mes propres mesures, en une journée : une clé de matrice retapée rendait une colonne de ? ; un Closes #N non ancré lisait la PROSE d'un corps de demande comme une fermeture ; docs/ matchait dev-docs/, 16 au lieu de 0 ; deux motifs comptaient 77 puis 114 cas de test, tous deux faux ; et le motif du critère de fin comptait le RAPPEL lui-même comme une réponse. Aucune n'a rougi. Une mesure importe donc le motif du dispositif, ou l'ancre, et un texte qui documente un motif contient le motif. Ce qui les a attrapées est la DIVERGENCE de deux chemins, jamais la vigilance #5584, passe 11 de sa clôture
5700 Le contrôle de forme d'une ligne de tableau ne jugeait qu'un fichier sur les 651 du dépôt, et la passe 0 a trouvé quatre lignes amputées ailleurs, dont trois pipes nus écrits le jour même par la session qui livrait le contrôle. Il vit désormais dans scripts/_commun/tableaux.py et suit les DEUX dispositifs qui lisent déjà un tableau, l'index des ADR et la page des gardes, dont la forme a une conséquence lisible. Il ne devient PAS un garde des 651 : le dépôt est propre, donc un cliquet naîtrait sans marge, et je n'ai aucun témoin négatif pour les formes légitimes que je n'ai pas rencontrées #5700, passe 7 de la clôture de #5584
5774 Un garde rendait sa cause d'empêchement comme un élément de sa liste de constats, laquelle s'imprime sous le titre « Invocations d'OpenSpec qui n'existent pas » : un refus héritait du titre des constats, donc accusait le diff de ce qui tenait au poste. Son voisin avait la forme inverse, gardant REFUS : et perdant POUR REPARER :, donc son refus n'était pas lu comme déclaré. Huit corps de demande sur deux sessions les ont classés « environnementaux ». Deux canaux distincts désormais, et une liste vide reprend son sens : « j'ai jugé et c'est vert », jamais « je n'ai pas pu juger ». Rallonger la phrase du refus n'y pouvait rien, le titre étant imprimé AVANT la liste #5774, lot du sous-chantier #5762
5775 L'ADR 5407 avait décidé que le dépôt pose l'outil OpenSpec à la création d'un worktree. Mesuré un mois plus tard : sur les 23 arbres du poste, 12 n'en avaient aucun, parce que npm est introuvable dans le PATH d'un shell non interactif. L'échappatoire « chaque échec nomme sa commande » tenait en lettre et nommait précisément la commande qui ne peut pas s'exécuter. Le dépôt ne cherche donc plus l'outil, il demande au poste : le profil du shell que le poste déclare dit déjà où vit le sien, et cette déclaration est tenue par son propriétaire. Ni table de dispositions à maintenir, ni fichier non versionné à faire écrire, ni gestionnaire de version nommé. Et le script cesse de rendre 0 quoi qu'il arrive : la non-blocance était déjà la propriété du crochet, par son \|\| true #5775, lot du sous-chantier #5762
5790 Le graphe que AGENTS.md prescrit d'interroger d'abord était entièrement de structure : une page n'y entrait que par ses titres, et rien ne distinguait « je n'ai rien trouvé dans la prose » de « je n'ai pas lu la prose ». Une couche sémantique y est posée le 4 octobre sur un périmètre écrit : 577 pages, 3 090 nœuds, près de 7,9 millions de jetons. Trois parades se mesurent avant la fusion, dont le repli d'un nœud homonyme d'un titre, qui effaçait 62 identifiants de structure. La couche ne suit pas une page qui change, et la décision le déclare. #5790, lot 1 du chantier #5812
5677 Le ZIP était le mode de dépôt par défaut parce qu'on le disait « le plus rapide », sans mesure. Le retour d'expérience du porteur dit l'inverse : la compression prend du temps et du disque sans gain perceptible au téléversement, et le ZIP fait en plus perdre l'audio en ligne. Sans réglage, le dépôt part donc en séquences WAV ; un réglage posé est respecté. Le changement a révélé qu'un dépôt entamé en ZIP et repris en WAV renvoyait toutes les séquences à côté des archives déjà en ligne, sans rien dire : un dépôt entamé garde désormais le mode de ses unités déposées #5677, chantier #5596
5813 L'ADR 5790 nommait trois pertes silencieuses de la fusion des lots sémantiques. Le rejeu de l'outil sur des lots réels en a trouvé deux de plus, invisibles dans un compte de nœuds : une hyperarête sans identifiant tombe à la fusion suivante, même à vide, et 25 des 71 de la première extraction n'en portaient pas ; une réextraction remplace toute la couche de sa page, donc un identifiant non réémis est effacé. L'outil pose un identifiant stable, et refuse un lot de mise à jour qui lâche un identifiant sans le déclarer. #5813, lot 2 du chantier #5812
5597 Toute archive de dépôt était refusée par S3 en SignatureDoesNotMatch depuis juillet. Le serveur Vigie-Chiro signe l'URL d'une partie multipart sans Content-Type, et le client en envoyait un : en signature S3 v2 le type fait partie de la chaîne signée. Une partie part donc sans type, et ce n'est pas un oubli à réparer #5597, lot 1 du chantier #5596 (retour de terrain 2.193.0)
5598 Un 403 du stockage S3 était lu comme un refus de droits, et l'écran comme la commande conseillaient « Reconnectez-vous ». Samuel s'est reconnecté puis a redémarré, pour rien. La provenance d'un refus (l'API, ou le stockage) remonte désormais par le dépôt en parties, au lieu d'être devinée du statut ou du texte, et chaque cause nomme le geste qui la répare #5598, lot 2 du chantier #5596
5599 Le compte rendu d'un contenu refusé conseillait de régénérer les archives, et la génération répondait « préparez-le d'abord » sur un dépôt entamé : le geste conseillé était refusé. La génération est admise sur un dépôt entamé, et refusée pendant un téléversement, que connaît un registre en mémoire et non un drapeau en base #5599, lot 3 du chantier #5596
5601 Samuel a vu l'alerte « horaires non respectés » alors que son enregistreur s'était arrêté exactement à l'heure de fin affichée : la fin exigée se compare à la seconde et s'affichait tronquée à la minute. L'heure affichée s'arrondit désormais du côté qui tient le protocole, et la comparaison reste à la seconde #5601, lot 5 du chantier #5596
5607 Samuel a déclaré un carré absent de Vigie-Chiro en Point Fixe et ne l'a appris qu'au dépôt, sa nuit déjà importée. Trois endroits classaient le résultat de la recherche d'un carré, chacun à sa façon. PresenceDuCarre les remplace, le verdict dit ce qu'il implique pour le dépôt, et « Créer » interroge le portail quand l'observateur ne l'a pas fait #5607, lot 13 du chantier #5596
5720 Quand deux tranches veulent le même nom, l'import écrit la seconde en « _001 ». Kaleidoscope ne produit que des « _000 » : une nuit réactivée depuis un dossier qu'il a découpé ne retrouve aucun « _001 », et le compte rendu envoyait l'utilisateur chercher un fichier qui n'a jamais été sur son disque. Un perdant de collision se reconnaît à son nom, se compte à part, et reste compté parmi les manquantes #5720, lots 21 à 23 du chantier #5596 (#5717, #5719, #5720)
5676 Après un dépôt, deux boutons « Lancer la participation » coexistaient sous un titre resté « Marquer le passage déposé », et le résultat du clic partait dans le bandeau du haut : deux clics de plus ont reçu 400 Already PLANIFIE. Un geste a désormais un seul point d'action, son résultat se lit sous le bouton qui l'a demandé, et l'état « analyse demandée » se lit dans le relevé #5676, lots 14 et 15 du chantier #5596 (#5676, #5682)
5688 La modale de site lisait une position collée dans un champ, celle de point demandait deux champs Latitude et Longitude lus par un autre analyseur. Une seule règle lit désormais une position, dans un seul champ, au fil de la saisie ; le premier point se crée avec son site ; un point du site à 40 m ou moins se signale sans rien interdire #5688, lots 19 et 20 du chantier #5596 (#5687, #5688)
5784 Quand « Actualiser » rendait « Analyse terminée », il fallait quitter l'écran de lot et demander l'import au menu de « Sons & validation ». Le relevé qui trouve l'analyse terminée importe désormais les observations dans le même geste. Il ne remplace jamais celles qui existent, n'importe jamais à l'ouverture de l'écran, et l'application ne sonde toujours pas le serveur #5784, lot 24 du chantier #5596
5851 L'ADR 3498 fait d'une commande lectrice une classe qui porte un marqueur. etat-traitement-vigiechiro --importer lit sans l'option et écrit avec. Le marqueur porte donc une réponse, neFaitQueLire(), vraie par défaut, et le verrou du dossier de travail suit l'invocation et non plus la classe #5851, clôture du chantier #5596 (décision prise par le lot 24, #5784)
5824 Le dépôt part en séquences WAV depuis l'ADR 5677, et l'écran de lot ne lisait jamais la forme du dépôt : il offrait une étape « Générer les archives » sans objet, comptait des « archives » dans le compte rendu d'un dépôt de séquences et conseillait de les régénérer. L'écran et la commande lisent désormais la forme à un seul endroit, n'offrent que les étapes qui la servent, et nomment ce qui est parti #5824, lot 25 du chantier #5596, et #5835 trouvé à sa clôture
5857 Le périmètre de la couche sémantique (ADR 5790) retenait scripts/methode/relus.txt, un registre que 15 des 33 fusions suivantes ont réécrit : il sortait « modifiée » à presque chaque passe, pour une couche d'un seul nœud. Il sort du périmètre, nommément. Et parce qu'une page sortie du périmètre serait alors rendue « disparue » à chaque passe, une commande oublie retire sa couche et son empreinte ; elle refuse une page encore dans le périmètre. #5857, lot 4 du chantier #5812
5839 La carte d'un point alertait sous 200 m, « trop rapprochés pour le protocole ». Ce seuil est celui du protocole Carré du portail, que Companion ne traite pas ; le Point Fixe n'impose aucune distance entre deux points. La distance s'affiche sans se juger, et le seul voisinage signalé reste celui de la création, à 40 m (ADR 5688) Lot 26 du chantier #5596 (#5839), trouvé à la passe 7 de sa clôture
5859 Le fil d'étapes de l'écran de lot nommait « Marquer déposé » le geste que sa carte et son bouton nomment « Lancer la participation », et le disait fait dès que la nuit était déposée. Il lit désormais la liaison du bouton : même nom, et étape courante tant que la participation reste à lancer. La confirmation de « Réinitialiser le dépôt » suit la forme du dépôt, comme son infobulle Lot 27 du chantier #5596 (#5859), trouvé en montant l'artefact de sa clôture ; constat de recette S4-C03
5877 graphify update . ne relit pas la structure d'une page qui porte déjà une couche dans le graphe : ses titres dataient du jour où elle l'avait reçue, et 586 pages y étaient exposées, dont six en écart. rebuild.py --mets-a-jour relit donc la structure de toutes les pages .md du graphe, après l'outil et avant les ponts, sans recopier la règle par laquelle le moteur écarte une page couverte. Un titre que le disque ne porte plus sort du graphe, et la commande dit combien d'arêtes sémantiques tombent avec lui, et sur quelles pages. #5877, lot 6 du chantier #5812
5743 le banc des témoins classait le rouge d'un garde muté en trois états, et seuls les décoratifs entraient dans ses suspects : quatre gardes n'avaient donc rien établi pendant que sa dernière ligne disait verdict=ok, et le compte pouvait passer de 4 à 40. Un dispositif qui se déclare invariant borne sa population résiduelle par une liste nommée et non par un cliquet, qui échangerait un membre réparé contre un membre neuf sans qu'aucun chiffre bouge. Elle se vérifie dans les deux sens, et le second ne se juge que sur la population entière. #5743, lot de #5768
5904 Une session neuve, refaisant la couche d'une page avec la seule documentation du dépôt, a trouvé qu'une page réextraite perdait son hyperarête en silence : la fiche ne la nommait pas, l'audit n'en regardait aucune, la fusion rendait « 0 perdu ». 63 pages sur 589 en portaient une. La fiche nomme désormais les hyperarêtes, l'audit refuse celle qu'un rendu lâche sans la déclarer, et la fusion retire en le disant un membre qui ne désigne plus rien. fusionne écrit le graphe de son arbre et refuse un autre graphe. Et les ponts parcourent les pages que le graphe porte au lieu d'une liste de dossiers : 436 citations de classe s'ajoutent, surtout depuis openspec/. #5904, lot 7 du chantier #5812
5814 Une page modifiée gardait ses nœuds sémantiques d'avant, et savoir lesquelles se faisait par un git diff contre un commit tenu de mémoire. fusionne note désormais l'empreinte git de chaque page, et a-reextraire rend les pages modifiées, neuves ou disparues, avec leur raison : 14 pages le 5 octobre, comme un git diff indépendant. Il refuse au lieu de rendre une liste vide quand il n'a ni graphe ni empreinte. Et rebuild.py --mets-a-jour reporte les libellés des communautés par recouvrement de leurs membres, là où graphify update . les renomme toutes. #5814, lot 3 du chantier #5812 ; écrite à sa clôture
5868 Cinq pages de la racine, dont AGENTS.md, avaient perdu leur nœud de page : une passe de pont parcourait la racine sans y reconnaître de nœud de fichier, en fabriquait un second, et le suffixait _doc, que le moteur réserve au jumeau d'un document. Une citation part désormais du nœud de page, reconnu à sa nature, et les deux passes partagent ce choix au lieu d'en porter deux copies. Un pont ne fabrique plus de nœud de document : il ferait passer la page pour couverte, et le moteur ne relirait plus sa structure. #5868, lot 5 du chantier #5812 ; écrite à sa clôture
5867 Connecté en séquences WAV, l'écran de lot n'offrait plus aucune voie quand Vigie-Chiro refusait des séquences sans recours. Le repli manuel s'offre dès qu'une séquence est refusée définitivement pour une cause autre que les droits : la carte des archives reparaît sous celle du téléversement, sans numéro, et le fil reste à trois étapes. La règle se lit dans le plan enregistré, à un seul endroit, pour l'écran et pour deposer-vigiechiro. La carte porte le dernier geste, « Marquer le passage déposé », et deposer ne re-prépare plus un dépôt entamé. Le dépôt que l'application téléverse garde sa forme Lot 34 du chantier #5596 (#5867)
5644 Le tournage des clips connectés visait la plateforme nationale en dur. Il choisit maintenant sa cible, et un même scénario sert les deux quand il le peut : deux scénarios pour un même cas feraient deux sources de vérité. Celui qui n'a de sens que sur la plateforme de test, parce qu'il écrit, la vise explicitement et porte plateforme-de-test-seule, que le tournage national exclut. La condition que l'ADR 5641 laissait ouverte est mesurée : sur quinze paires, les cinq clips ont un plancher de 0,005 à 0,503 %, donc ils se comparent #5644, sous-chantier de #5640
5854 Les clips de la plateforme de test vont sur une pré-version que chaque tournage écrase : la comparaison n'avait qu'un côté à leur donner. Le job de publication la recopie sous un second nom AVANT d'y écrire, et l'ordre est la décision : recopier après garderait le tournage courant sous les deux noms, et la comparaison dirait « rien n'a changé » entre un tournage et lui-même. Écartés : tourner sur chaque tag de version, qui hérite de deux rouges connus, et lire l'artefact d'une exécution, qui expire #5854, lot 8 de #5644
5870 Un clip variait de 20 % entre deux tournages du même commit : même contenu, page défilée ailleurs. amenerDansLeCadre place sa cible par un quotient, et JavaFX garde ensuite le décalage en pixels, donc une carte qui grandit laisse la page en deçà de son bas. Un verdict qui est le dernier élément de sa page se montre par allerAuBasDeLaPage, appelé une fois son état arrivé, et l'aide refuse une cible qui n'est pas au bas. Ce qui établit le remède est la cause, reproduite par un banc, et non l'absence du défaut sur quelques paires #5870, lot 9 de #5644
5885 Le même clip rend 0,020 % avec ffmpeg 8 et ImageMagick 7, 0,134 % avec les versions du runner. Les planchers du dépôt venaient d'un poste : 32 clips sur 51 sortaient à plus du double pour un code identique. Le fichier dit son instrument, et l'outil REFUSE de comparer contre un autre, ou de le compléter, en nommant les deux. La mesure passe par un atelier qui n'écrit rien sur le dépôt. Amende l'ADR 4287 : un plancher repart de zéro quand son instrument change, garder le pire de deux instruments ne décrivant le bruit d'aucun #5885, lot 10 de #5644
5911 Sept clips ont deux fins : leurs paires valent soit moins de 3 %, soit de 9 à 26 %, parce qu'ils s'arrêtent pendant un import, pendant un fondu, ou sur une page que rien n'a calée. Leur écrire ce plancher rendrait la comparaison aveugle à tout changement plus petit. Ils sont nommés dans l'outil avec leur issue : la mesure affiche leur écart sans l'écrire, et la comparaison les annonce « sans plancher », pas « plancher inconnu ». Le critère est la dernière image, regardée, et non un seuil. Mis à jour le 2026-10-05 : six clips depuis que celui du menu de ligne de l'import cale sa page sur son compte rendu (#5952) #5911, trouvé par le lot 10 de #5644
5936 La première réextraction à plusieurs lecteurs, 37 pages en 4 lots, passait l'audit et la fusion sous « perdus du fait des lots=0 », et perdait pourtant un énoncé fondu dans un autre de même libellé et treize arêtes dont l'audit refusait la cible. Un libellé ne se partage plus : l'audit le refuse entre deux lots, et la fusion nomme l'énoncé que le moteur a fondu, sans refuser. La fiche range sous ailleurs l'extrémité d'une arête qui vit hors de la passe, et l'audit écrit une ligne pour un lot sain. #5936, lot 9 du chantier #5812
5931 L'ADR 5481 interdisait « une liste écrite dans la porte », l'ADR 5373 admettait une liste qu'un garde confronte, et les deux ne se citaient pas : zéro mention dans chaque sens. Ce que la porte nomme se dérive désormais des ateliers comme ce qu'elle joue, par la nature de l'argument et non par ressemblance avec la CI, qui rendrait dix-sept scripts dont installer_paquets.py. Une liste écrite reste admissible à la seule condition qu'un garde dérive la même population et refuse quand les deux divergent. Et une population déclarée se nomme, pour qu'un cas confronte le compte imprimé plutôt que la fonction #5915, lots #5884 et #5931 ; écrite à sa clôture
5939 Posée en langage courant, une question pouvait ne recevoir que du code : le moteur part des libellés qui ressemblent à la question, et un symbole de code homonyme captait le départ. « Pourquoi le dépôt se fait en WAV par défaut » ne rendait aucun des trente énoncés que la couche porte sur le sujet. Une commande du dépôt, couche_semantique.py cherche, pose la question aux énoncés, libellé et justification, et note la présence d'un mot plutôt que sa répétition. Elle se lance à côté de graphify query, pas à sa place, et refuse sur un graphe sans couche. #5939, lot 10 du chantier #5812
5941 Le chemin du crochet de commit ne relisait que le code : une page dont un titre changeait gardait ses titres d'avant jusqu'à la prochaine mise à jour complète. Il relit désormais la structure des pages que le commit touche, et dit les titres qu'il retire. Le code et les pages passent par une seule extraction : deux fusions de suite partiraient du même graphe, et la seconde effacerait la première. #5941, lot 12 du chantier #5812
5940 Les libellés des communautés se perdaient pour un quart à chaque reconstruction, et la règle de report n'y était pour rien : le graphe entier était repartitionné à chaque fois, et 388 communautés sur 1 119 en sortaient identiques pour 365 nœuds de plus. La reconstruction garde la communauté de chaque nœud qui existait et range un neuf chez la majorité de ses voisins ; les libellés se reportent par identifiant. La partition entière ne se refait que sur demande, par --repartitionne. #5940, lot 11 du chantier #5812
5862 La vue d'un passage ne savait rien du traitement : il fallait aller jusqu'à l'écran de lot pour savoir si l'analyse était finie. Elle porte « Vérifier le traitement », qui relève l'analyse et importe les observations par la règle de l'ADR 5784. Les phrases du traitement vivent dans le socle : les deux écrans lisent le même texte sans dépendre l'un de l'autre. Le résultat va au bandeau de retour, et la vue ne garde ni ne sonde aucun état. Lot 30 du chantier #5596 (#5862)
5975 Le repli manuel faisait générer des archives de toute la nuit. Joué sur le code du serveur, le scénario montre qu'il ajoute chaque fichier d'une archive sans chercher s'il est déjà là : une séquence déjà en ligne revenait en double dans les fichiers de la participation. Sur un dépôt entamé en séquences WAV, la génération lit le plan de dépôt et n'archive que ce qu'il ne dit pas déposé, pour l'écran comme pour exporter-lot ; quand tout est en ligne, elle refuse en le disant. #5975, lot 4 du chantier #5967
5930 Une branche ne se comparait pas à main avant fusion : la comparaison ne lisait que des versions publiées. Chaque côté est désormais une version ou un numéro d'exécution de tournage, repris avec les refus de la mesure, par les mêmes phrases : exécution conclue, un artefact de clips et un seul, non vide. Le garde les exige des deux ateliers face au même leurre, ce qui répond à l'objection de parité de l'ADR 5854. Un seul refus ne se reprend pas, celui du même commit, puisque deux commits sont l'objet d'une comparaison. Un artefact expiré se dit Lot 3 du chantier #5933 (#5930)
5970 La plateforme de test n'a pas de worker, donc une archive déposée y reste une archive, et ce que le serveur fait d'un son rendu deux fois restait une hypothèse. Un banc lui fait jouer la seule moitié du worker qui répond, l'extraction, par le code du serveur à la révision épinglée et sans le retoucher. Deux accès au stockage sont remplacés parce qu'ils ne décident rien de ce qu'on observe, et l'image de l'API porte unzip. Le worker reste hors de la plateforme. #5970, lot 3 du chantier #5967
5265 Trois bancs de mutation prétendaient la même chose sans la mesurer pareil, et chaque lot qui les alignait reposait la même question : ce qu'on écrit trois fois, faut-il l'écrire une fois, et ce qu'ils font différemment, faut-il l'unifier ? Ce qu'ils ont en commun est ce qu'ils rendent : le point d'entrée lu dans l'arbre, trois comptes dont la somme vaut la population, la déclaration invariant, une table nommée des non concluants. Leur mécanique reste propre à chacun, avec sa raison : d'où vient le corpus, si le banc s'y trouve, ce qui borne le second sens de sa table. La clôture écrit aussi dans l'ADR 4490 l'amendement que la 5257 portait seule, et complète la 4770. Clôture du chantier #5265
5987 Une publication qui s'arrête en chemin laisse un tag et un journal d'apparence normale, et aucune publication : il faut interroger la forge pour le voir, et rien ne le disait - 17 tags de version étaient dans cet état. Un garde le signale en fin de train, borné par la version et non par le graphe : est anormal un tag dont la version dépasse la plus haute version publiée. Deux bornes plausibles ont été écartées par la mesure, dont l'ancestralité, les commits de ces tags n'étant plus sur main. Il s'éteint de lui-même après un train réussi, et une forge muette le fait refuser au lieu d'alerter. #5987, lot 2 du chantier #6005
4775 Un commit est arrivé sur main sans le numéro de sa demande, parce que la fusion avait reçu un --subject. Le geste est écrit : fusionner nu. Le garde sur les sujets de main, lui, n'est pas écrit, par décision : il jugerait après la fusion, là où rien ne se répare, et il coûterait des exemptions et un cliquet pour un lien de journal perdu zéro fois. Mesuré sur 671 commits depuis le 29 août 2026 : une occurrence, aucune récidive. La page dit ce qui rouvrirait la question. #4775, lot 4 du chantier #6009
6069 Un clip sorti de la table des clips sans plancher y est revenu : deux tournages sur douze finissaient la page en haut, à 21 % des autres. Son dernier geste s'arrêtait dès que la cible était dans le cadre, ce qui est vrai à plusieurs positions. Le dernier geste d'un clip pose une position et la vérifie au demi-pixel, et l'assertion de fin la relit après la tenue #6069, lot 11 de #5933
6135 La dernière image d'un clip variait de 0,3 à 0,9 % entre deux tournages du même commit, parce que x264 plaçait sa dernière image clé selon le rythme du tournage et qu'une image immobile garde la qualité de cette clé. Les clés tombent à pas fixe de 25 images, sans coupure de scène, et l'encodeur finit la séance sur un pas entier de copies de sa dernière image, après l'avoir bourrée jusqu'au multiple. À source constante, l'écart tombe à 0,000 %. Les planchers se remesurent depuis zéro, et ne valent que pour cette chaîne (#6150) #6135, lot 17 de #5933
6002 Quarante et une attentes de fin classées une par une : quatorze lisaient un libellé qui n'est jamais vide, deux la présence d'un bouton que la modale déclare dès son chargement. Elles ne pouvaient pas expirer, et sous une étape retardée des cas passaient sans l'avoir attendue. Une attente de fin porte sur un état que son étape seule produit ; un état attendu à plusieurs endroits a son aide (InspectionConclue.attendre), et la vacance se prouve par le retard de l'ADR 5334. Prolonge l'ADR 5334 #6002, #6105 et #6134, lots de #5933
6060 Pour relire sur la fiche web ce que Companion écrit, la plateforme de test sert le front web de Vigie-Chiro. Il est construit dans l'image de l'API, à sa propre révision épinglée, et l'API le sert à sa racine (FRONTEND_HOSTED) : même origine, adresse d'API relative /api/v1 figée à la construction, aucun CORS. Deux origines, un relais nginx et une image à la demande sont écartés #6060, lot 1 de #5645
6022 L'article A10 interdit de faire taire un avertissement, quatre surfaces le répétaient, et rien ne le vérifiait : deux méthodes mortes ont vécu cinq semaines sous @SuppressWarnings("unused"), que PMD honore. Un garde refuse désormais, sans marge, l'annotation et la marque qui font taire le portail. Sa liste de valeurs admises est fermée, unchecked et rawtypes, parce qu'une liste de refus laisserait passer all. La marque NOPMD se refuse là où PMD la lit, en fin de ligne de code, et pas dans la prose qui la cite. Ce que PMD honore a été mesuré sur une classe jetable, pas lu dans sa documentation. Première décision rattachée à A10 #6022, lot #6114
4462 WCAG 2.5.8 demande qu'une cible cliquable fasse au moins 24 × 24 px. Le garde qui tient ce seuil avait été porté du dépôt de référence sans la décision qui le fonde : son contrat disait « sans ADR », et la matrice d'ergonomie rangeait wcag-cible parmi les heuristiques que rien ne sert. Une cible cliquable ne se déclare pas sous 24 px, sur six types de nœud. Le garde ne lit que les dimensions chiffrées écrites dans un FXML, soit trois cibles sur 147 : les autres tiennent leur taille de leur police, et la page dit ce qu'il ne voit pas #4462, lot de #5006
6142 Une tâche de fond écrivait le champ du dossier de l'écran d'import depuis son fil, tous les bancs de l'import la jouaient et aucun ne l'a vue : JavaFX ne vérifie pas le fil d'une écriture de propriété. Une tâche de fond rend une valeur, appliquée au retour sur le fil JavaFX. Un espion de test relève toute écriture d'un nœud montré faite hors de ce fil et fait rougir le cas, et un garde refuse une classe à toolkit qui ne le porte pas. Il ne voit que ce que les bancs jouent. #6142, lot de #5697
6175 Avec une transformation par cœur, l'import ne laissait aucun cœur à l'interface : l'écran gelait jusqu'à 442 ms et la sonde du banc voyait 16 à 42 images par seconde. Une tâche de fond qui calcule mène de front la moitié des cœurs du poste (ParallelismeDeFond), et l'import la lit. Mesuré sur un poste à 16 cœurs : plus aucun écart de plus de 100 ms pendant la transformation, pour 15 % de durée en plus dans l'interface. Un test compte les transformations en vol dans un vrai import. La compaction du dépôt et la réactivation gardent leur borne, faute de mesure. #6175, lot de #6178
6171 Le banc de l'IHM relevait de 203 à 758 ms à l'ouverture d'un écran après un import, pour un seuil de 200 ms. Mesuré en datant chaque ouverture : à chaud, l'image de 176 à 193 ms qui suit une ouverture est le dessin logiciel du banc, et n'existe pas en rendu GPU (122 ms au plus sur cent huit ouvertures). Le seuil se juge à chaud et en rendu GPU ; la première ouverture de chaque écran se publie à part ; le relevé écrit le dessin que Prism a réellement pris, et le banc se tire en GPU par -Drecette.prism.order=es2. Le seuil de 50 ms d'O5 reste non tenu (#6207). #6171, lot de #6178
6191 base.css déclarait la famille de police sur .root et aucune taille : un texte sans taille propre prenait celle du système, 12 px sous Windows et 13 px sous Linux et macOS, et un même libellé tenait sur un poste et se coupait sur l'autre. .root déclare 12 px. Ce que JavaFX mesure hors du graphe de scène n'en dépend pas : un ChoiceBox reste plus large de 13 px sous Linux et macOS #5496, lot #6191
6184 Un écran qui pose un écouteur sur un singleton s'y fait retenir jusqu'à la fermeture : la fiche d'un carré le faisait (#6170), l'écran des réglages aussi, trouvé par le garde à son premier tir. Un écran suit ce qui lui survit par une liaison, ou par EcouteFaible, qui inscrit l'écouteur faible et le fait tenir par son porteur. EcranQuitteEstRenduTest ouvre chaque écran qui reçoit un singleton observable, le quitte et le veut rendu, et tient son inventaire contre la composition. Les modales et le chrome sont hors du test, et c'est dit #6178, lot #6184
6183 Le job plateforme-de-test rougissait par intermittence sur une écriture sans réponse, et rien ne disait ce que l'API faisait alors. Ses journaux, versés depuis, ont montré la requête absente du côté de l'API, qui n'avait ni redémarré ni planté. L'image lance désormais l'API par gunicorn, comme l'amont en production, avec des workers synchrones qui ne gardent aucune connexion ouverte. Dix-neuf tirs sans cette chute ont suivi, dont dix verts de suite ; le mécanisme reste une hypothèse #6183
6197 Au début d'un import, l'image où la table de suivi s'affiche durait de 100 à 255 ms dans les relevés du banc de l'IHM. Mesuré sur main à cb9ed7676 : 162 ms au plus sur dix tirs par dessin, et c'est le coût d'une première mise en page, que les imports suivants du même processus ne paient pas. Elle se juge au premier import, le cas courant, tient O3 dans les deux dessins, et aucun remède n'est engagé. Quatre dépassements relevés sur le code d'avant #6209 ne sont pas expliqués #6178, lot #6197
6207 O5 demande l'ouverture d'un écran de la topologie sous 50 ms. La vue multisite et l'écran des sons s'ouvrent de 92 à 294 ms à chaud à 150 carrés en rendu GPU, parce que le navigateur les reconstruit à chaque ouverture, et leur durée varie d'un jour à l'autre. Le seuil reste et n'est pas tenu : l'écart est une dette de #6178. En chemin, les feuilles du chrome passent de sa racine à la scène, ce qui retire un coût de JavaFX qui croissait avec la session ; son gain en temps n'est pas établi #6178, lot #6207
6219 Des tests lisent pour de bon, dans un navigateur, ce que Companion écrit sur la fiche web, et vérifient des cas de recette marqués « hors-portée ». Les citer par @CasDeRecette les ferait entrer dans le tournage, qui attend un clip par cas cité : une portée dédiée a été livrée puis retirée le même jour. Un test qui ne filme rien ne cite pas ; le cas garde son marqueur, dont le motif nomme le test #6219
6161 L'import chargeait chaque WAV entier, et tombait au-delà de 2 Gio. La transformation lit l'en-tête puis le signal tranche par tranche, au bit près ; FichierWav.lire ne reste que pour la séquence de 5 s que la vérification d'identité analyse, et ArchitectureTest refuse tout autre appelant. Occupation après GC de 904 à 68 Mo ; un WAV de 2,15 Gio s'importe #6161, lot #104
6174 La réactivation régénérait dans java.io.tmpdir, un tmpfs sur ce poste : 7031 Mo de mémoire vive que la JVM ne voyait pas, et un poste figé. Un temporaire que le produit remplit naît sous l'espace de travail, un filet efface au démarrage ce qu'un plantage y laisse, et ArchitectureTest refuse hors des outils un temporaire sans dossier parent #6161, lot #6174
6256 L'ADR 6175 avait laissé tous ses cœurs à la réactivation faute de l'avoir vue à l'écran. Le banc de l'IHM la mène maintenant par sa modale : à tous les cœurs elle ne gèle pas l'écran, même restreinte à quatre (151 ms au plus). Elle mène pourtant la moitié des cœurs, par décision du porteur : plus de marge, du processeur laissé aux autres applications, une seule règle. Prix : rien sur seize cœurs, 10 à 30 % de durée en plus sur quatre #6246, lot #6256