Quality-Gate System — Critical Assessment, Catalog and Replication Playbook (Français)
Partie 1 — Verdict et classification de maturité
Section intitulée « Partie 1 — Verdict et classification de maturité »Note globale : A− / « Avancé ». Parmi les ~5 à 10 % de meilleurs projets. Le système met en œuvre de manière autonome plusieurs modèles explicitement reconnus par le secteur — ce qui constitue le signal d’alignement le plus fort (nous n’avons pas copié une liste de contrôle ; nous avons convergé vers les bonnes pratiques).
| Cadre de référence | Notre situation | Note |
|---|---|---|
| OWASP DSOMM (5 niveaux, 5 dimensions) | Niveau 3 solide, approchant le niveau 4 en intensité des tests et profondeur de l’analyse statique. La plupart des organisations se situent aux niveaux 1 à 2. | N3→N4 |
| OpenSSF Scorecard (18 contrôles) | Nous réussissons CI-Tests, Code-Review, Dependency-Update-Tool, Fuzzing, SAST, Signed-Releases (provenance), Token-Permissions, Vulnerabilities et Dangerous-Workflow. Lacunes : Branch-Protection désactivée sur main ; certaines actions ne sont pas épinglées. |
~7–8/10 |
| SLSA (4 niveaux) | npm publish --provenance + id-token: write + compilation hébergée par GitHub = N2, en voie d’atteindre le N3. Il manque un environnement de compilation renforcé/hermétique pour le N3 et au-delà. |
N2→N3 |
| SonarQube « Clean as You Code » | Philosophie identique : le mécanisme de cliquet garantit la non-régression (le nouveau code ne dégrade pas la métrique). Divergence : Sonar recommande peu de conditions ; nous avons environ 46 seuils (risque de lassitude). | Aligné, avec une réserve |
| Modèle Quality-Ratchet | Implémentation de référence : mécanisme de cliquet + dedicatedGate + tightenSlack + --require-tighten + omission contrôlée. Plus sophistiquée que la plupart des exemples publics. |
Exemplaire |
| DORA 2024 | Très performant sur l’axe de la stabilité. Risque : des seuils exigeants peuvent allonger le délai de livraison — atténué par la séparation des seuils rapides, mais avec une lacune de couverture (voir la Partie 2). | Solide (stabilité) |
| OWASP LLM Top 10 (2025) | Nous couvrons le risque nº 1 (injection de prompt) avec une protection à l’exécution + promptfoo (évaluation) + garak (red teaming). Outils standards du secteur. | Couvert |
| Tests par mutation | Stryker exécuté chaque nuit, seuils de 70/50, 8 modules critiques. Consensus du secteur (60 % pour l’existant / 80 % pour le nouveau code, exécution nocturne) — nous faisons mieux. Lacune : le score n’est pas encore soumis à un mécanisme de cliquet. | Presque abouti |
Partie 2 — Évaluation critique (points forts + faiblesses réelles)
Section intitulée « Partie 2 — Évaluation critique (points forts + faiblesses réelles) »Points forts (ce qui est au-dessus de la moyenne)
Section intitulée « Points forts (ce qui est au-dessus de la moyenne) »- Moteur de cliquet multi-métriques. Le cœur du système. 24 métriques dans
quality-baseline.json- 4 référentiels dédiés, chacun avec une direction (
up/down), une tolérance (eps), une marge (tightenSlack) et un indicateurdedicatedGate. Les éléments corrigés restent corrigés — c’est l’antidote à l’entropie de la base de code.
- 4 référentiels dédiés, chacun avec une direction (
- Défense en profondeur de la chaîne d’approvisionnement. SAST (CodeQL/Sonar) + secrets (gitleaks avec
useDefault) + SCA (osv/npm-audit/Trivy/Dependabot) + licences + fichier de verrouillage + SBOM + provenance SLSA + Scorecard + durcissement des workflows (zizmor). Peu de bases de code disposent d’une pile aussi complète. - Antidotes à la loi de Goodhart. Faire de la couverture une cible est un anti-pattern classique
(« lorsqu’une mesure devient un objectif, elle cesse d’être une bonne mesure »). Nous avons les
contrepoids : tests de mutation (mesurent si le test détecte le bug, et pas seulement
s’il exécute la ligne),
check-test-masking(empêche d’affaiblir les assertions pour réussir), seuils de couverture par module (imposent de tester le code à risque ÉLEVÉ, et pas seulement les parties faciles) etcheck-pr-evidence(règle stricte n° 18). - Barrières anti-hallucination / de cohérence. Une catégorie rare et précieuse :
check-known-symbols,check-fetch-targets,check-openapi-routes,check-docs-symbolsgarantissent que la documentation, les spécifications et les mécanismes de dispatch par chaîne pointent vers des symboles existants. Elles détectent la « dégradation » que le linting et les tests ne détectent pas. - Cycle de vie consultatif→bloquant. Les nouvelles barrières sont d’abord introduites en mode consultatif (elles ne bloquent pas les fusions pendant leur maturation), puis deviennent bloquantes à la fin du cycle. Cela réduit les frictions sans abaisser le plafond.
- Ignoré proprement lorsque l’infrastructure manque. Les scanners (
--ratchet) se terminent avecexit 0si le binaire ou le réseau échoue — une infrastructure manquante ne bloque jamais une PR légitime. Une ingénierie mature. - Culture codifiée. Les règles strictes +
trust-but-verify+ la liste d’autorisation des éléments obsolètes + la barrière de preuves transforment la discipline en vérification automatisée.
Faiblesses réelles (lacunes effectives)
Section intitulée « Faiblesses réelles (lacunes effectives) »- 🔴 La séparation des barrières rapides laisse encore une lacune structurelle.
quality.yml(PR→release/**) exécute désormais la vérification des types, les tests déterministes rapides et, à titre consultatif, un build de production pour les PR de code, mais n’exécute toujours pas l’ensemble complet des vérifications de PR de release deci.yml(cliquets de couverture, artefact de package, intégration, E2E, SonarQube). La motivation (la rapidité) est valable, mais la barrière doit se trouver là où la fusion a lieu (shift-left). La plus importante correction structurelle encore en attente. - 🟠 Risque de prolifération et de lassitude lié aux barrières. Environ 46 barrières + 25 jobs, c’est ÉNORME. Sonar lui-même avertit : trop de conditions provoquent une « lassitude liée aux barrières » et des débats sur les priorités, avec le risque qu’une barrière soit ignorée. DORA avertit que les barrières lourdes allongent le délai de mise en production. Nous limitons ce risque avec des niveaux consultatifs et des cliquets non absolus, mais il manque une revue périodique du retour sur investissement de chaque barrière (certaines micro-barrières de synchronisation de la documentation pourraient être consolidées).
- 🟠 Le score de mutation n’est pas encore soumis à un cliquet. L’antidote le plus puissant contre le contournement de la couverture reste consultatif. C’est l’élément en attente ayant la plus forte valeur (et il est déjà réalisé à 90 %).
- 🟡 Éléments consultatifs qui devraient être bloquants (avec le bon périmètre).
osv(vulnCount) etoasdiffsont consultatifs malgré des référentiels figés. Le caractère consultatif d’osv se justifie (une nouvelle CVE sur une ancienne dépendance bloquerait une PR sans rapport) — mais il existe un juste milieu (ne bloquer que les vulnérabilités CRITICAL+corrigeables, comme nous l’avons fait avec Trivy). Le caractère consultatif d’oasdiff signifie qu’une modification rompant le contrat peut être acceptée. - 🟡 La sécurité à l’exécution ne s’exécute que la nuit. schemathesis/garak/promptfoo/chaos/k6 s’exécutent la nuit. C’est une décision pertinente (ils sont lents et nécessitent un serveur actif), mais une PR peut introduire une régression de la protection contre les injections qui ne sera détectée que la nuit suivante.
- 🟡 La protection de branche sur
mainest DÉSACTIVÉE.BRANCH_LOCK_TOKENverrouille les branches de release, maismainelle-même n’est pas protégée. Scorecard/DSOMM le pénalisent. Une action du propriétaire est requise. - 🟡 Configuration par défaut de CodeQL ; semgrep non codifié. La configuration par défaut fonctionne (0 alerte), mais un fichier
codeql.ymlversionné offre davantage de contrôle ; semgrep s’exécute via une plateforme cloud externe et n’est pas versionné dans le dépôt.
Partie 3 — Catalogue complet des points de contrôle qualité (portable)
Section intitulée « Partie 3 — Catalogue complet des points de contrôle qualité (portable) »Les 12 catégories ci-dessous constituent le « système qualité » sous une forme réutilisable. Chacune présente l’objectif (ce qu’il faut protéger), les outils que nous utilisons et l’équivalent indépendant des outils permettant de le reproduire sur n’importe quelle pile technologique.
1. Style et formatage (déterministes, rapides)
Section intitulée « 1. Style et formatage (déterministes, rapides) »- OmniRoute : Prettier + ESLint via lint-staged (pré-commit), 2 espaces/guillemets doubles/100 col.
- Générique : un outil de formatage avec correction automatique + un linter, exécutés en pré-commit sur les fichiers indexés.
2. Types
Section intitulée « 2. Types »- OmniRoute :
typecheck:core(bloquant) +typecheck:noimplicit:core(consultatif) + cliquettype-coverageà 92.17 % + budget deanypar fichier. - Générique : vérification stricte des types dans la CI + métrique de couverture des types avec cliquet + budget de
any/échappatoires par fichier.
3. Tests (intensité)
Section intitulée « 3. Tests (intensité) »- OmniRoute : 2 exécuteurs sans chevauchement (Node natif + vitest), 8 fragments, couverture globale 60/60/60/60 + cliquet à environ 76 % + 8 seuils par module pour les modules critiques + tests par propriétés nocturnes + tests de mutation nocturnes.
- Générique : exécuteur(s) de tests + seuil de couverture absolu (anti-zéro) + cliquet de couverture (anti-régression) + seuils par module pour le code à haut risque (anti-Goodhart) + tests par propriétés pour la logique pure + tests de mutation nocturnes comme véritable mesure de la qualité des tests.
4. Politique de test (anti-contournement)
Section intitulée « 4. Politique de test (anti-contournement) »- OmniRoute :
pr-test-policy(le code de production exige un test),check-test-masking(bloque les assertions affaiblies),pr-evidence(toute déclaration de réussite exige un bloc de preuves),test-discovery(chaque test est collecté par un exécuteur). - Générique : barrière « nouveau code ⇒ nouveau test » + détecteur d’assertions supprimées/de tautologies + exigence de preuves (TDD ou test vivant) + garantie qu’aucun test ne reste orphelin hors des motifs glob.
5. Complexité et santé du code (cliquets)
Section intitulée « 5. Complexité et santé du code (cliquets) »- OmniRoute : avertissements ESLint (3769↓), duplication jscpd (5.72 %↓), complexité cyclomatique + nombre maximal de lignes (1800↓), complexité cognitive sonarjs (753↓), code mort/exports inutilisés knip (339↓), taille par fichier (gelée, réduction uniquement), dépendances circulaires (Tarjan personnalisé, bloquant).
- Générique : appliquer un cliquet à chaque métrique de santé (avertissements, duplication, complexité cyclomatique et cognitive, code mort, taille des fichiers, cycles d’importation). La direction est toujours « ne pas régresser ».
6. Sécurité statique (SAST + secrets)
Section intitulée « 6. Sécurité statique (SAST + secrets) »- OmniRoute : CodeQL (cliquet d’alertes = 0), gitleaks (
[extend] useDefault=true— critique !), SonarQube, règles de sécurité personnalisées (public-creds, error-helper, route-guard-membership, route-validation). - Générique : SAST (CodeQL/Sonar/semgrep) avec cliquet d’alertes + analyseur de secrets doté d’un jeu de règles par défaut hérité (une configuration personnalisée qui remplace les valeurs par défaut crée un angle mort) + barrières de sécurité propres au projet fondées sur des règles strictes.
7. Chaîne d’approvisionnement (dépendances)
Section intitulée « 7. Chaîne d’approvisionnement (dépendances) »- OmniRoute : osv-scanner + npm-audit + Trivy + Dependabot (SCA), license-checker (liste d’autorisation SPDX), lockfile-lint (HTTPS+sha512+registre),
check-depscontre le slopsquatting (liste d’autorisation + âge ≥72 h). - Générique : SCA multisource + liste d’autorisation des licences + contrôle d’intégrité du fichier de verrouillage + liste d’autorisation des dépendances avec vérification de l’âge/du typosquatting + robot de mises à jour groupées.
8. Chaîne d’approvisionnement (compilation et publication)
Section intitulée « 8. Chaîne d’approvisionnement (compilation et publication) »- OmniRoute : SBOM (CycloneDX + syft), provenance SLSA (
--provenance), OpenSSF Scorecard (hebdomadaire), durcissement des workflows (zizmor : artipacked→persist-credentials:false, empoisonnement du cache, autorisations des jetons). - Générique : générer un SBOM lors de la publication + provenance signée (SLSA L2+) + Scorecard planifiée + durcir tous les workflows (jetons avec privilèges minimaux, aucun identifiant persistant lors d’un checkout ne servant pas à publier, actions épinglées par SHA).
9. Contrats et API
Section intitulée « 9. Contrats et API »- OmniRoute : oasdiff (changements incompatibles OpenAPI), schemathesis (fuzzing contractuel nocturne), openapi-coverage (% de routes documentées, cliquet à 38.3 %), openapi-security-tiers (spécification par rapport à la protection des routes).
- Générique : comparaison des contrats détectant les changements incompatibles (oasdiff/buf) + fuzzing par propriétés par rapport à la spécification (schemathesis) + couverture documentaire avec cliquet + cohérence spécification↔code.
10. Documentation et i18n (anti-obsolescence)
Section intitulée « 10. Documentation et i18n (anti-obsolescence) »- OmniRoute : docs-sync (versions mises en miroir), docs-counts-sync (nombres dans la documentation par rapport au code), env-doc-sync, doc-links, fabricated-docs, cli-i18n, i18n-ui-coverage (
--threshold=65+ cliquet à 80.1 %). - Générique : synchroniser les versions/nombres/variables d’environnement entre la documentation et le code (une barrière, pas une relation de confiance) + valider les liens internes + couverture i18n avec cliquet.
11. Anti-hallucination / cohérence (la catégorie rare)
Section intitulée « 11. Anti-hallucination / cohérence (la catégorie rare) »- OmniRoute : known-symbols (répartition par chaîne ⇒ symbole vivant), provider-consistency, fetch-targets (appel
fetchdu client ⇒ route réelle), docs-symbols, db-rules (règles strictes nº 2/nº 5), migration-numbering. - Générique : pour chaque « source de vérité dupliquée » (registre, répartition par chaîne, références entre couches), une barrière prouvant que les deux côtés correspondent. Détecte la dégradation que la vérification des types et les tests ne détectent pas.
12. Résilience et domaine (propres au produit)
Section intitulée « 12. Résilience et domaine (propres au produit) »- OmniRoute : chaos (injection de pannes), heap-growth (fuite), k6 (endurance), promptfoo+garak (red team LLM, OWASP LLM Top 10), les 3 lois de résilience (disjoncteur/période de temporisation/verrouillage).
- Générique : identifiez les modes de défaillance de votre domaine et prévoyez une barrière pour chacun (même si elle est nocturne). Pour les applications d’IA : red team contre les injections. Pour les systèmes distribués : chaos + fuite + endurance.
Partie 4 — Plan de réplication pour tout projet
Section intitulée « Partie 4 — Plan de réplication pour tout projet »Construisez par phases, chacune apportant une valeur propre. N’essayez pas de couvrir les 12 catégories en même temps — cela provoque exactement la lassitude liée aux contrôles contre laquelle met en garde la Partie 2. Tout nouveau contrôle commence en mode consultatif et devient bloquant une fois stable.
La pièce maîtresse réutilisable : l’« anatomie d’un contrôle à cliquet »
Section intitulée « La pièce maîtresse réutilisable : l’« anatomie d’un contrôle à cliquet » »L’ensemble du système repose sur ce modèle à 3 fichiers. Commencez par le copier :
baseline.json— la valeur de métrique gelée +direction(up/down) +eps(anti-instabilité) +tightenSlack+dedicatedGate.collect-metrics.<ext>— exécute l’outil, extrait la valeur et écritmetrics.json.check-ratchet.<ext>— comparemetrics.jsonàbaseline.json;exit 1uniquement en cas de régression au-delà deeps;exit 0(ignoré sans erreur) si l’outil ou l’infrastructure manque ; avec--require-tighten,exit 1si la métrique s’est améliorée sans mise à jour de la référence (ce qui verrouille le gain).
Une fois ce mécanisme en place, chaque nouvelle métrique (couverture, complexité, avertissements, alertes SAST, taille du bundle, score de mutation…) n’est plus qu’une ligne dans la référence.
Phase 0 — Fondations (semaine 1)
Section intitulée « Phase 0 — Fondations (semaine 1) »La CI existe ; formateur + linter + vérification des types + 1 exécuteur de tests + seuil absolu de couverture (par ex., 60 %). La pré-validation exécute des contrôles rapides pouvant être corrigés automatiquement. Résultat : aucune PR ne compromet les fondamentaux.
Phase 1 — Le moteur à cliquet (semaine 2) — la fondation de tout le reste
Section intitulée « Phase 1 — Le moteur à cliquet (semaine 2) — la fondation de tout le reste »Implémentez les 3 fichiers ci-dessus. Gelez les références pour : les avertissements, la couverture, la complexité, la duplication, le code mort et la taille des fichiers. Résultat : à partir de maintenant, la base de code ne peut que s’améliorer.
Phase 2 — Analyse statique approfondie (semaine 3)
Section intitulée « Phase 2 — Analyse statique approfondie (semaine 3) »SAST (CodeQL/Sonar/semgrep) avec cliquet sur les alertes ; analyseur de secrets (héritez du jeu de règles par défaut) ; SCA (osv/Dependabot) + liste d’autorisation des licences + lockfile-lint. Résultat : les vulnérabilités connues et les secrets divulgués ne passent pas.
Phase 3 — Chaîne d’approvisionnement de la compilation (semaine 4)
Section intitulée « Phase 3 — Chaîne d’approvisionnement de la compilation (semaine 4) »SBOM lors de la publication + provenance signée (SLSA L2) + Scorecard planifié + durcissement des workflows (zizmor : jetons minimaux, aucun identifiant persistant, actions épinglées). Résultat : des versions traçables et inviolables.
Phase 4 — Intensité des tests (semaines 5–6)
Section intitulée « Phase 4 — Intensité des tests (semaines 5–6) »2e exécuteur si utile ; seuils de couverture par module pour les modules critiques (anti-Goodhart) ;
tests basés sur les propriétés pour la logique pure ; tests de mutation nocturnes → lorsque le 1er score est disponible, faites de
mutationScore une métrique à cliquet. Résultat : la couverture cesse d’être une métrique de vanité ; les tests détectent les bogues de façon démontrable.
Phase 5 — Contrats et analyse dynamique (semaine 7)
Section intitulée « Phase 5 — Contrats et analyse dynamique (semaine 7) »S’il existe une API publique : oasdiff (changement incompatible, bloquant) + schemathesis (fuzzing nocturne). DAST/équipe rouge chaque nuit selon les besoins du domaine. Résultat : les contrats ne sont pas rompus silencieusement.
Phase 6 — Anti-hallucination et domaine (semaine 8)
Section intitulée « Phase 6 — Anti-hallucination et domaine (semaine 8) »Un contrôle de cohérence pour chaque « vérité dupliquée » dans le projet. Contrôles des modes de défaillance propres au domaine (pour l’IA : équipe rouge contre les injections). Résultat : la dégradation structurelle et les défaillances propres au domaine disposent d’un filet de sécurité.
Phase 7 — Gouvernance (en continu)
Section intitulée « Phase 7 — Gouvernance (en continu) »- Cycle consultatif→bloquant pour chaque nouveau contrôle.
stale-allowlist: chaque suppression comporte une justification + un ticket ; toute suppression obsolète est détectée.evidence-gate: toute affirmation de réussite dans une PR nécessite une preuve (test ou test vivant).- Revue trimestrielle du retour sur investissement de chaque contrôle (supprimez ou cessez de financer ceux qui ne sont pas rentables — cela combat la lassitude).
- Transformez les règles strictes de votre projet en contrôles exécutables.
Principes transversaux (non négociables)
Section intitulée « Principes transversaux (non négociables) »- Cliquet, pas valeur absolue. Contrôlez la non-régression, pas une valeur fixe (sauf pour les seuils anti-zéro).
- Seuil absolu et cliquet ensemble. Le seuil empêche l’effondrement ; le cliquet empêche l’érosion lente.
- Anti-Goodhart par conception. Chaque métrique cible nécessite un contrepoids (couverture ⇒ mutation + anti-masquage ; seuils par module pour imposer le test du code difficile).
- Ignoré sans erreur. Une infrastructure manquante ne bloque jamais ; seule une régression réelle bloque.
dedicatedGatepour les métriques coûteuses. Les métriques nécessitant un binaire externe disposent de leur propre script (avec possibilité d’ignorer sans erreur), en dehors du cliquet central synchrone.- Placez le contrôle là où la fusion a lieu. Ne laissez aucun intervalle entre le contrôle rapide et la fusion réelle (leçon tirée de la séparation des contrôles rapides).
- Peu de contrôles bloquants, mais bien choisis. Sonar/DORA : trop de conditions = lassitude. Préférez le mode consultatif + cliquet à un mur de contrôles bloquants.
Partie 5 — Améliorations recommandées (priorisées, compatibles)
Section intitulée « Partie 5 — Améliorations recommandées (priorisées, compatibles) »P0 — meilleur ROI, presque prêt
- Mécanisme de progression du score de mutation (après que la 1re exécution nocturne de Stryker aura produit des valeurs). Antidote essentiel contre la loi de Goodhart appliquée à la couverture ; terminé à ~90 %.
- Combler la faille restante des contrôles rapides — promouvoir le build de production de
quality.ymlaprès sa semaine d’observation et continuer à déplacer les contrôles déterministes réservés aux PR de release vers le parcours PR→release. - Protection de branche sur
main(paramètre du propriétaire) — améliore le Scorecard et comble l’écart avec DSOMM.
P1 — utile 4. osv/oasdiff → bloquants avec le bon périmètre — osv uniquement pour les vulnérabilités CRITICAL avec correctif disponible (en deux étapes comme Trivy) ; oasdiff bloque les changements incompatibles. 5. require-tighten → bloquant (fin de cycle) — pérennise les gains sur les métriques. 6. Revue du ROI/temps d’exécution par contrôle dans ci-summary — identifier et supprimer les contrôles lents ou à faible valeur.
P2 — rendements décroissants 7. SLSA L3 — builder hermétique/reproductible (générateur SLSA de GitHub) si vous souhaitez passer au niveau supérieur depuis L2. 8. Configuration CodeQL versionnée dans le dépôt + semgrep versionné — davantage de contrôle et de reproductibilité. 9. Test de fumée DAST pour chaque PR — sous-ensemble rapide de schemathesis/promptfoo sur les endpoints présentant le plus de risques (pas seulement la nuit). 10. Tableau de bord de l’instabilité + métriques DORA — vérifier que les contrôles n’érodent pas la vitesse.
Partie 6 — Enseignements concrets des releases (contrôles à ajouter lors de la phase 9)
Section intitulée « Partie 6 — Enseignements concrets des releases (contrôles à ajouter lors de la phase 9) »Cette section consigne des incidents réels survenus lors de clôtures de releases lorsqu’un contrôle manquait, avec des éléments concrets et le contrôle proposé. Chaque élément est candidat pour la partie 5.
Enseignement de la v3.8.27 (2026-06-17) — la « faille des contrôles rapides » laisse les régressions déterministes atteindre le jour de la release
Section intitulée « Enseignement de la v3.8.27 (2026-06-17) — la « faille des contrôles rapides » laisse les régressions déterministes atteindre le jour de la release »Ce qui s’est passé. Lors du /generate-release de la v3.8.27, la PR de release (release/v3.8.27 → main)
a constitué la première exécution de la matrice ci.yml complète au cours du cycle intégré. Résultat : 12 échecs
simultanés — 3 tests déterministes + environ 9 instabilités/problèmes d’environnement. Aucun n’était une régression réelle du produit en production, mais
tous sont passés inaperçus, car les PR du cycle entrent dans release/** via le Fast QG
(quality.yml), qui n’exécute NI la suite de tests unitaires complète, NI pr-test-policy (masquage de tests), NI la
suite d’intégration complète, NI la vérification de parité des schémas. Les 3 échecs déterministes étaient les suivants :
- Test obsolète à la suite d’une modification de l’interface utilisateur —
permissions modal switch buttons declare button type: #4034 a ajouté un 4e bouton bascule (l’attribut d’accessibilitétype="button"a été conservé) ; le décompte=== 3du test est devenu obsolète. L’analyse statique aurait dû détecter cela dans la PR #4034. - Test obsolète à la suite d’une modification du packaging —
findMissingArtifactPaths ... root runtime files:dist/http-method-guard.cjsest devenu un chemin légitimement requis ; la liste attendue par le test est devenue obsolète. - Divergence due à une modularisation avec perte d’informations (le problème le plus grave) —
settings schemas accept ... unprefixed toggle: leupdateSettingsSchemamodularisé (schemas/settings.ts, créé par #3988) a divergé de la version canonique (settingsSchemas.ts) : 45 champs contre 85 — 40 supprimés + 6 divergents (qdrant*). Il s’agissait de code mort (l’exécution utilise la version canonique), donc sans impact réel, mais seul un test de parité écrit manuellement l’a détecté. #4030 a restauré 16 suppressions analogues provenant de #3988/#3993, mais celle-ci est passée entre les mailles du filet.
Contrôles proposés (phase 9) :
- G1 — Combler réellement la faille des contrôles rapides (étend P0 #2). Dans
quality.yml(PR→release/**), au-delà du contrôle des types et des tests concernés, exécuterpr-test-policy(masquage de tests) + la suite complète de tests unitaires déterministes (ou au moins les fichiers statiques/de parité, qui sont rapides et stables). Ainsi, les tests obsolètes et la suppression d’assertions sont détectés dans la PR qui les introduit — et non le jour de la release. Exclure les tests d’intégration/e2e (lents/instables), mais la couche déterministe NE PEUT PAS rester limitée au parcours PR→main. - G2 — Contrôle de parité de la modularisation (NOUVEAU, non couvert actuellement). Un contrôle qui, pour chaque symbole
réexporté par un barrel modularisé (
src/shared/validation/schemas/*, modulesproviderRegistry, etc.), compare la structure (clés dez.object, entrées de registre) avec la source canonique et échoue en cas de divergence (champ supprimé/supplémentaire). Il aurait détecté la suppression des 40 champs introduite par #3988 dans cette même PR. Il généralise les tests de parité écrits manuellement (qui n’existent que lorsque quelqu’un a pensé à les écrire). Peu coûteux : importe les deux et compareObject.keys(shape). - G3 — Triage déterministe des tests instables (support). Les tests de démarrage de LiveWS et les tests
integration-combo/breaker échouent en raison d’un délai d’expiration du serveur ou d’une cascade dans la CI (environnement), et non de la logique. Les marquer comme
known-flaky(mis en quarantaine avec une issue) afin que le rouge de la PR de release ne représente que de vrais signaux, et non du bruit masquant des régressions déterministes.
Principe : le contrôle doit s’exécuter là où la fusion a lieu (déjà indiqué dans les « Principes transversaux »). L’incident de la v3.8.27 montre que cela s’applique également à la couche de tests déterministes, et pas seulement au lint/contrôle des types — sinon, la dette liée aux tests obsolètes et à la modularisation avec perte d’informations n’apparaît que dans le parcours PR→main, par lots, au pire moment.
Sources (bonnes pratiques du secteur)
Section intitulée « Sources (bonnes pratiques du secteur) »- Modèle de maturité DevSecOps de l’OWASP (DSOMM) — https://dsomm.owasp.org/about
- OpenSSF Scorecard / SLSA — https://openssf.org · https://slsa.dev
- SonarQube « Clean as You Code » — https://docs.sonarsource.com/sonarqube-server/latest/user-guide/clean-as-you-code
- Cliquets de qualité (LeadDev) — https://leaddev.com/software-quality/introducing-quality-ratchets-tool-managing-complex-systems
- Amélioration continue du code par cliquet (Greiner) — https://robertgreiner.com/continuous-code-improvement-using-ratcheting/
- Rapport DORA 2024 sur l’état du DevOps — https://cloud.google.com/blog/products/devops-sre/announcing-the-2024-dora-report
- Bonnes pratiques en matière de tests par mutation (Stryker) — https://stryker-mutator.io
- La couverture comme anti-modèle (loi de Goodhart) — https://www.industriallogic.com/blog/code-coverage-complications/
- Top 10 de l’OWASP pour les applications basées sur des LLM (2025) — https://owasp.org/www-project-top-10-for-large-language-model-applications/
- Tests de contrat (oasdiff/schemathesis) — https://www.oasdiff.com · https://schemathesis.readthedocs.io
HagiCode
HagiCode est un espace de développement agentique qui associe workflows structurés, exécution multi-agent et vues Hero Dungeon.
Transformez vos idées en logiciels utiles grâce à un workflow agentique plus intelligent, rapide et agréable.

- SmartDes workflows structurés transforment une intention en parcours exécutable, de l’idée à la livraison.
- EfficientLes workflows multi-agents font avancer recherche, réalisation et revue en parallèle.
- FunHero Dungeon rend les longues sessions de code plus visuelles et collaboratives.