Gate ajouté (bloc « Fiches agents · colonne Job CI ») : on RECOMPUTE l'ensemble des jobs depuis la clé `jobs:` de ci.yml (la section `on:` push/pull_request/workflow_dispatch est AVANT `jobs:` et donc exclue ; jamais une liste à la main) et on exige que chaque token `*-tests` cité dans une fiche y figure. Direction fiche→ci.yml (le consommateur) : ci.yml peut définir des jobs non cités (légitime), une fiche ne peut pas citer un job absent ; la disparition totale de la colonne échoue AUSSI. 33 références vérifiées == jobs ci.yml ; 2 morsures (token de fiche `seo-tests`→`seo-suite-tests` fantôme · job ci.yml `rbac-tests` renommé → mord SIMULTANÉMENT les 4 fiches qui le citent : erpnext_backend/ifc_speckle/mobile/rendu), restauré vert, 7 gates re-verts. ci/README.md + activity log MAJ.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Le bloc e-NCF gate le FORMAT de l'identifiant ; le bloc cross-cohérence (2e surface) gate états émetteurs/champs de base/FormaPago ; mais AUCUN ne comparait l'IDENTITÉ de ce rôle à ses DEUX sources faisant autorité : (a) out/ecf_plan.json (byte-gaté) — chaque emission_events[] porte role_id + erpnext_role_name ; (b) rbac_50_roles.json (contrat) — le rôle porte portail:"compta". Le `portail` n'est PAS dans l'artefact ; il n'est vérifiable QUE contre le contrat.
Même classe d'IDENTITÉ que la Fiche Mobile / les Fiches Faisabilité ou les gardes CRM/workflow_vente, appliquée à une 3e surface distincte du MÊME README fiscal. Piège : la seule vérification existante (tests/) teste des FONCTIONS (ncf/résolution), jamais la prose. RÉAFFECTER l'émission à un autre rôle, le RENOMMER, ou DÉPLACER le rôle hors du portail compta (e-CF émis HORS Compta — séparation cassée) laisse la prose périmée pendant que l'artefact/contrat disent autre chose → l'agent ERPNext Backend câblerait le mauvais rôle émetteur.
Gate ajouté (ci/check_readme_claims.sh, bloc « Fiscal rôle émetteur ») : role_id/erpnext_role_name recomputés de emission_events + portail/nom Frappe du contrat, prose EXACTE ; cohérences croisées : tous les emission_events pointent UN SEUL rôle (fonction · non vide) · role_id unique au contrat · nom artefact == contrat (zéro-dup) · portail == compta. Un claim absent échoue AUSSI. 6 morsures vérifiées (README renomme role_id/nom/portail · artefact réaffecte les 2 events à ventes-directeur (5 mords cascade) · contrat déplace le rôle vers ventes · artefact diverge du contrat sur le nom), restauré vert, 7 gates re-verts. ci/README.md mis à jour.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Les blocs Fiches Faisabilité / Fiche Mobile ne gataient que les attributs du CONTRAT ; le bloc « triplets par workspace » ne gate que le COMPTE de rôles par Workspace (`nb_roles`), AVEUGLE à QUEL rôle. Rattacher le rôle mobile à `OTO Ventes` (SUR-EXPOSITION console : le dev mobile gagnerait l'accès au portail Ventes — la restriction même que la note #6 pose), retirer/déplacer le rôle rendu de `OTO Construction`, laissait la fiche périmée en silence pendant que l'artefact dit autre chose ⇒ l'agent ERPNext Backend câblerait le mauvais accès console.
Gate ajouté (nouveau bloc « Fiches agents · rattachement Workspace ») : index recomputé `erpnext_role_name → {titres de Workspace le portant}` depuis workspace.json (nom résolu du contrat par id, zéro duplication). 3 formes d'assertion : in_named (rendu — prose cite CE Workspace ET membership == {lui seul}) · in_any (ifc — membership ≥1) · not_in_named (mobile — assertion NÉGATIVE #6, rôle ABSENT du Has Role du Workspace nommé). Garde anti-typo : Workspace nommé absent de l'artefact ⇒ ROUGE. Claim absent ⇒ ROUGE (traçabilité).
9 morsures vérifiées (4 artefact + 5 fiche/bord) ; restauré vert ; 7 gates re-verts. ci/README.md (récap + paragraphe détaillé) + activity log + mémoire mis à jour.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Même classe que la Fiche Mobile (session précédente) — surface 03_agents/*/AGENT.md transcrivant à la main les attributs d'un rôle depuis le contrat, gatée (si tant est) seulement sur des comptes agrégés. Gate ajouté (bloc « Fiches Faisabilité », config-table par fiche : fichier · role_id · attributs restitués) : par attribut recomputé du contrat, prose EXACTE exigée ; permissions rendues en ORDRE CANONIQUE (read→R · write→W · create/delete/… en toutes lettres — élargir/rétrécir change la chaîne, `R/W/create` ne satisfait plus `R/W/create/delete`) ; verbe inconnu ⇒ ROUGE ; claim absent échoue AUSSI.
#6 (honnêteté) vérifié AVANT édition : la DESCRIPTION de ces deux fiches est une PARAPHRASE éditoriale (le contrat porte « (… — CLAUDE.md) » / « les modèles » que la fiche condense) — donc NON gatée verbatim (ne rien réécrire de correct pour un gate), seuls les attributs structurés (transcrits à l'exact) sont contraints. État courant : aucun attribut structuré périmé (12 recomputes == contrat).
11 morsures vérifiées (5 contrat + 6 fiche) : rendu Faisabilité +write (R→R/W) · rendu niveau 2→3 · rendu WA SRL→WAF · rendu rôle renommé · ifc Faisabilité R/W→R · fiche rendu File R/W/create→…/delete · fiche ifc R/W→R/W/create · fiche rendu module Faisabilité→Selling · fiche ifc WA SRL→WAF · fiche rendu nom_fr retiré (absent) · ligne contact ifc supprimée (INTROUVABLE) ; restauré vert, 7 gates re-verts. ci/README.md + activity log MAJ.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ces 4 figures sont Σ quantités · Σ(qté×prix_usd) · Σ(qté×prix_dop) · ⌈point_equilibre_pct × Σ unités⌉ calculées sur la fixture COMMITÉE fixtures/brief_bancable.json, le 52 % ancré sur CLAUDE.md #9 (« Point équilibre 52% pré-vente »). PIÈGE : la seule vérification existante (tests/) teste des FONCTIONS (l'arithmétique de recoupement _check_derived_arithmetic) avec des oracles HARDCODÉS dans le test — une copie de plus, jamais comparée à la PROSE du README. Éditer une typologie de la fixture (quantité/prix), en ajouter/retirer une, ou déplacer le point d'équilibre de CLAUDE.md #9, laisse les 4 chiffres du README périmés pendant que le générateur produit autre chose → le banquier lit un dossier faux (l'invention même que #6 interdit) — « vert trompeur » qu'aucune suite tests/ n'attrape.
Nouveau bloc « Faisabilité/bancable figures » dans ci/check_readme_claims.sh (avant sys.exit), même esprit que le bloc faisabilite/generator ancré sur CLAUDE.md #9/#10 mais appliqué à une surface dont la source de vérité n'est PAS un out/*.json : (1) recompute indépendant des 4 figures depuis la fixture commitée ; (2) cohérence croisée — le manifeste GÉNÉRÉ (bancable_gen validate, exécuté via subprocess stdlib pur, encoding utf-8) == le recompute (mord un générateur/fixture incohérents) ; (3) prose — un seul pattern d'identité exige les 4 valeurs EXACTES avec séparateur de milliers pour USD/DOP + la formule ⌈pct × Σ unités⌉ dont le pct == CLAUDE.md #9 et le total == Σ unités. Un claim absent échoue AUSSI (traçabilité).
État courant : aucun chiffre périmé (anti-invention #6, rien à réécrire) — le défaut est la surface ungated (module entièrement hors CI). 7 morsures vérifiées : README USD 8,560,000→9,560,000 (figure périmée) · README retire le séparateur de milliers (8,560,000→8560000) · README breakeven 21→20 (formule périmée) · README formule 52 %→55 % (dérive CLAUDE.md #9) · README supprime la ligne entière (INTROUVABLE) · fixture Studio qté 12→13 (5 morsures : units/USD/DOP/breakeven README périmés + manifeste) · fixture 2 Chambres prix_usd 320000→300000 (catalogue USD périmé) ; restauré = green : 4 figures == génération réelle · manifeste == recompute · pct 52 % == CLAUDE.md #9 · exit 0. Working tree byte-restauré via git checkout -- (JAMAIS git clean) · 7 gates re-verts. ci/README.md (ligne récap check-readme-claims) mis à jour · log 05_activity_log/2026-08-01.md. Auto-score 4Big 96/100.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Les deux blocs CRM/workflow existants gatent le COMPTE (« 9 états · 11 transitions ») ET l'énumération des transitions à séparation des pouvoirs (allow_self_approval=0), jamais l'identité des GARDES. Sources faisant autorité (byte-gatées par check_artifacts) : out/workflow.json (chaque transition porte `allowed` = le rôle gardien) + out/MANIFEST.json.roles_rbac_utilises[].erpnext_role_name (recomputé du contrat rbac_50_roles.json à chaque build). PIÈGE : les blocs COMPTE/séparation sont AVEUGLES à l'identité des gardes → RÉAFFECTER un pas monétaire (« Confirmer réservation » Réservations→Conseiller = élévation de privilège) · RENOMMER un rôle · AJOUTER un fantôme · en OUBLIER un laissait le README périmé pendant que l'artefact dit autre chose → l'agent ERPNext Backend câblerait le mauvais garde (le risque même que la table veut prévenir) — « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS de graphe/résolution RBAC, pas la prose) n'attrape. Même patron d'IDENTITÉ que la cross-cohérence PERMISSIONS Legal/CONFOTUR déjà gatée.
Nouveau bloc « CRM gardes » dans ci/check_readme_claims.sh (après le bloc Démo scénarios) : (1) identité d'ensemble — colonne « Rôle » de la table == {allowed} de workflow.json (set-diff · NFKD/casefold) ; (2) cohérence artefacts — {allowed} == roles_rbac_utilises du MANIFEST (aucun garde hors manifeste ni l'inverse) · ensemble NON VIDE ; (3) cross-cohérence par pas — les gardes des étapes SENSIBLES et uniques Confirmer réservation/Signer contrat/Approuver CONFOTUR (recomputés `allowed`, jamais figés) nommés EXACTEMENT dans leur ligne. Le (3) mord la RÉAFFECTATION vers un rôle DÉJÀ présent (rôle servant deux transitions) que le set-diff seul manquerait. Un claim absent échoue AUSSI.
7 morsures vérifiées : README réaffecte Confirmer réservation→Conseiller (absents=[réservations] + pas mordu) · artefact réaffecte Signer contrat→Conseiller (en trop=[contrats] + incohérence MANIFEST + pas mordu) · README rôle fantôme (en trop=[oto fantome]) · README retire un rôle (absents=[direction commerciale]) · artefact MANIFEST perd un garde (garde pas dans MANIFEST=[réservations]) · table supprimée (INTROUVABLE) · artefact réaffecte Approuver CONFOTUR→Directeur (rôle déjà présent, set INCHANGÉ, captée UNIQUEMENT par la cross-cohérence par pas) ; restauré = green : 7 rôles · colonne == {allowed} == roles_rbac_utilises · 3 étapes sensibles pinnées · exit 0. État courant : aucun garde périmé (anti-invention #6, rien à réécrire) — le défaut était la surface ungated. ci/README.md (table + détail « 3e surface workflow_vente ») mis à jour · working tree byte-restauré (git checkout --, JAMAIS git clean) · 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Le bloc « apply_plan » existant de check_readme_claims.sh (bloc 2) ne gate QUE la
ligne AGRÉGÉE « Génération réelle » (8 comptes consolidés). Les 3 colonnes
d'identité de la table run-book (README:38-46) sont data-derived de
out/apply_plan.json (byte-gaté par check_artifacts) : # = order · Responsable =
responsable (worker/vps/worker+vps) · Dépend de = les n°s d'ordre des depends_on.
Elles étaient un WILDCARD. PIÈGE : check_artifacts ne prouve QUE apply_plan==build
(byte-for-byte) et le bloc de comptes est aveugle à l'identité des lignes → passer
le Responsable de l'étape 4 (worker+vps→vps) ou retirer une dépendance de l'étape 6
(4,5→4) laissait la prose périmée pendant que l'artefact dit autre chose. Un
responsable périmé (étape VPS attribuée au worker) ou une dépendance périmée (Role
Profile importé AVANT les Role) est un hazard réel — le risque même que le run-book
veut prévenir — qu'aucune suite tests/ (qui teste des fonctions, pas la table
commitée) n'attrape. Même classe que la colonne « Type » de roleprofile_gen et la
table demo/scenarios.
Nouveau sous-bloc « 2bis) apply_plan — TABLE Run-book » : (1) IDENTITÉ par étape —
chaque ligne porte EXACTEMENT #=order + Responsable=responsable + Dépend de=n°s
d'ordre des depends_on (deps extraits par digits ⇒ robuste au séparateur/em-dash) ;
colonne « Étape » libre (paraphrase). (2) IDENTITÉ d'ensemble — {ordres des lignes}
== {ordres artefact} sans doublon (aucune ligne FANTÔME, aucune étape MANQUANTE).
Cohérences croisées (mordent un plan INTERNEMENT incohérent) : ordres contigus 1..N ·
responsable ∈ {worker,vps,worker+vps} · toute dépendance pointe en ARRIÈRE
(n° < n° de l'étape). Un claim absent échoue AUSSI.
8 morsures vérifiées : README étape4 responsable worker+vps→vps (câblage) · README
étape6 Dépend de 4,5→4 (dep manquante) · README étape3 1,2→1,2,5 (dep fantôme) ·
ligne FANTÔME #7 (7≠6) · étape 5 SUPPRIMÉE (INTROUVABLE + 5≠6) · artefact étape2
responsable vps→worker (README stale) · artefact étape2 dep en AVANT (graphe
incohérent) · artefact étape1 responsable hors domaine (robot) ; restauré = green :
6 lignes == 6 étapes · responsables/deps == artefact · ordres 1..6 · exit 0.
État courant : aucune valeur périmée (anti-invention #6, rien à réécrire) — le
défaut est la surface ungated. ci/README.md (table + détail « 2ᵉ surface
rbac/apply_plan ») mis à jour · working tree byte-restauré · 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Le §« Cœur du livrable : cross-cohérence » →Permissions du README legal/confotur
énumère À LA MAIN, PAR rôle, role_id + portail + actions (« mot pour mot les
permissions_cibles RBAC … ni ajout ni retrait ») : `ventes-confotur` (Ventes)
→ read/write/create/print · `legal-onapi` (Direction) → read/write/create ·
`legal-directeur` (Direction) → read/write/**submit**/report. Le bloc CONFOTUR
existant ne gate QUE le COMPTE (« 3 rôles ») — AVEUGLE à leur identité.
Ces 3 lignes sont DATA-DERIVED d'out/MANIFEST.json (roles_rbac_utilises[] : role_id
· portail · permissions, recomputé du contrat rbac_50_roles.json à chaque build) et
projetées dans out/doctype_confotur_application.json (permissions[] par nom de rôle)
— les DEUX byte-gatés par check_artifacts. PIÈGE : le compte « 3 rôles » ne voit pas
l'identité → PROMOUVOIR ventes-confotur à submit (élévation de privilège cassant la
séparation des pouvoirs dont is_submittable est déduit) · RETIRER une action ·
RÉAFFECTER un portail · RENOMMER un rôle · AJOUTER une ligne fantôme laissait la
prose périmée pendant que les artefacts disent autre chose → l'agent ERPNext Backend
câblerait le mauvais jeu de permissions (le risque même que la cross-cohérence veut
prévenir) — « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS de
mapping RBAC, pas la prose) n'attrape. Même patron d'IDENTITÉ que le catalogue RBAC
fixtures_gen (singleton set_user_permissions) et la cross-cohérence e-CF DGII.
Nouveau bloc dans ci/check_readme_claims.sh (après le bloc de comptes CONFOTUR) :
(1) jeu d'actions + portail de CHAQUE rôle recomputés de roles_rbac_utilises[],
prose exigée EXACTE (set-diff · casse normalisée) ; (2) identité d'ensemble
README⇔MANIFEST (aucun rôle fantôme NI manquant). Cohérences croisées en bonus
(mordent un artefact INTERNEMENT incohérent) : MANIFEST ⇄ DocType d'accord sur le
jeu d'actions par rôle · séparation des pouvoirs — submit porté par EXACTEMENT un
rôle (legal-directeur) et is_submittable==True déduit de sa présence (README:31).
Un claim absent échoue AUSSI.
7 morsures vérifiées : README promeut ventes-confotur à submit (en trop=[submit]) ·
README réaffecte legal-onapi Direction→Ventes (portail) · README retire report de
legal-directeur (absents=[report]) · README renomme un role_id (fantôme=[legal-conseil]
+ manquant=[legal-onapi]) · énumération supprimée (INTROUVABLE) · artefact MANIFEST
promeut ventes-confotur à submit (README périmé + séparation cassée + incohérence
MANIFEST⇄DocType) · artefact DocType is_submittable=false alors qu'un rôle porte
submit (incohérence interne) ; restauré = green : 3 rôles portail+actions == MANIFEST
· identité d'ensemble · submit singleton · is_submittable=True · exit 0. État courant :
aucun jeu d'actions périmé (anti-invention #6, rien à réécrire) — le défaut est la
surface ungated. ci/README.md (table + détail « 2e surface CONFOTUR ») mis à jour ·
working tree byte-restauré (git checkout --, JAMAIS git clean) · 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Le README `demo/scenarios` porte une table « Scénario | Projet | Audience | Angle »
(README:10-13). Le bloc « Démo » existant de check_readme_claims ne gate QUE
counts.modules_cites_uniques (le compte de modules du diagramme) — ses trois colonnes
d'identité étaient des WILDCARDS, et les libellés projets sont déclarés (README:91-92)
« proviennent verbatim de CLAUDE.md · §Projets » sans AUCUN ancrage vérifié.
Ces colonnes sont DATA-DERIVED de out/run_sheet.json.scenarios[] (id · projet ·
projet_libelle · audience), byte-gaté par check_artifacts. Le générateur ne saisit
aucune donnée métier (résolution RFC 6901 depuis le disque) ; mais check_artifacts
ne prouve QUE run_sheet==build (byte-for-byte) et la source scenario_spec.json (map
projets) recopie les libellés À LA MAIN → toute la chaîne peut DÉRIVER de CLAUDE.md
en restant byte-verte. PREUVE : classer P07 sous audience=client dans le README →
check_readme_claims EXIT 0 (le gate ne voyait que 10==10 modules). Un couple
projet/audience faux ferait pitcher au présentateur le mauvais scénario — le risque
même que la run-sheet veut éliminer — « vert trompeur » qu'aucune suite tests/ (qui
teste des FONCTIONS de résolution, pas la prose) n'attrape.
Nouveau bloc « Démo scénarios » dans ci/check_readme_claims.sh : (1) ANCRAGE — chaque
`P{code} {libellé}` du run_sheet == entrée « ## Projets » de CLAUDE.md (verbatim ·
source unique · même esprit que le catalogue projets dossier_vente) ; (2) TABLE —
chaque ligne porte EXACTEMENT id + `P{code} {libellé}` + audience (fin du wildcard ·
patron identique à la colonne « Type » de roleprofile_gen) ; (3) IDENTITÉ d'ensemble
— {ids des lignes} == {ids du run_sheet} == counts.scenarios (aucune ligne FANTÔME,
aucun scénario MANQUANT). Cohérences croisées en bonus (mordent un artefact
INTERNEMENT incohérent) : run_sheet ↔ MANIFEST d'accord sur (id,projet,audience) ·
id == S-{projet}-{AUDIENCE} · counts.scenarios == |scenarios| · ids non vides/sans
doublon. Un claim absent échoue AUSSI.
8 morsures vérifiées : prose renomme un id (INTROUVABLE) · prose classe P07 sous
audience=client · prose met le mauvais libellé projet · ligne FANTÔME S-P99-GHOST
(en trop) · artefact libellé « Aqua Terra Bay » DÉRIVE de CLAUDE.md · run_sheet↔
MANIFEST désync audience · counts.scenarios=3 (≠|scenarios|=2) · ligne S-P05-CLIENT
supprimée (MANQUANT) ; restauré = green : 2 lignes == run_sheet == counts (2) ·
libellés == CLAUDE.md §Projets · exit 0. État courant : aucune valeur périmée
(anti-invention #6, rien à réécrire) — le défaut est la surface ungated. ci/README.md
(table + détail « 2e surface demo/scenarios ») mis à jour · working tree byte-restauré
· 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cause : guard_constraints détecte l'USAGE (pas la simple mention) de termes interdits (CLAUDE.md #2/#3/#10 + interdits absolus) ; une ligne portant un marqueur de prohibition (JAMAIS/❌/pas de…) ou ci-allow est ignorée comme « rappel de règle ». Deux lignes de prose du log 2026-07-31.md (session 203134) tripaient le gate SANS marqueur : (L17) « Cardnet = paiement carte, pas Stripe » — restatement de #10, mais « pas » + terme capitalisé ne matche pas le marqueur « pas de|pas d » → faux positif ; (L43) « Working tree byte-restauré (git clean) » — mention de l'interdit absolu ET prose INEXACTE : cet interdit n'a JAMAIS été exécuté (restauration par git checkout --).
Correctif chirurgical, honnête, sans angle mort : reformulation des 2 lignes avec un cadrage de prohibition EXACT plutôt qu'une exclusion globale de 05_activity_log/ (qui aveuglerait le gate à une VRAIE violation confessée un jour). L17 → « Cardnet = paiement carte, JAMAIS Stripe » (marqueur JAMAIS + plus fidèle à #10) ; L43 → « byte-restauré (git checkout --, JAMAIS git clean) » (marqueur JAMAIS + désormais EXACT). Le gate garde intacte sa capacité à mordre un usage réel — chaque mention légitime porte son propre marqueur, ligne par ligne.
Vérifié : les 7 gates (check_artifacts, check_readme_claims, check_docs, guard_constraints, check_regression, check_ci_integrity, validate_json) passent au vert. Nouveau log de session 210134 rédigé avec discipline (marqueurs JAMAIS/ci-allow sur les lignes citant les termes interdits, sinon il re-tripperait le gate — d'où le soin apporté au log). Aucune modif VPS (#8), zéro réseau.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
INV10 ne garantissait que « roadmap_line est un entier positif ». Ajout de
parse_roadmap_anchors (deps) qui DÉRIVE la structure réelle de la roadmap, et
d'INV11 qui exige que chaque roadmap_line pointe RÉELLEMENT son bullet
(DELIVERABLE du sprint SX · k-ième bullet métrique) et que le « 8 + 7 » soit
dérivé du fichier, pas figé. Morsure prouvée sur le spec réel (S1=999, M3=200).
Régénéré consommateurs : regression 558→564 (run/plan/MANIFEST), quality_report
(acceptance 31→37 méthodes, 100/100 inchangé), fiches QA + Backend, README
acceptance (10→11 invariants). 7 gates verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Même classe de vert-trompeur que ci/README.md (session 050007) mais dans le
code des gates : 3 comptes vivants figés "22 suites · 551 tests · PASS" (matrice
534→551→558). L'ironie : le header de check_regression — le gate anti-péremption
de la matrice — s'était lui-même périmé. Fix précédent 050007 : suppression de la
surface de dérive (retrait du nombre figé → renvoi à regression_run.json), pas
551→558. Progressions historiques "534→551→558" conservées. 7 gates verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Défaut réel (#6 anti-invention) : 03_agents/erpnext_backend/AGENT.md situait les
tests backend par "repo : 560 tests au total" saisi à la main. 560 ne correspond à
aucun compte courant (matrice qa/regression = 558/22 ; repo-wide = 584 méthodes
test_*) — périmé en silence (534→551→558 ; 560 = ancien 534 + 26 harnais self-exclu
INV3). Même classe de vert-trompeur que la fiche QA (21/534), mais ungated.
- Vérif ciblée : toutes les autres bornes chiffrées des 13 AGENT.md exactes
(crm 81, RBAC 60, e-CF 39, portails 19, chat 31, confotur 44, seo 36).
- Fix : le nombre pointe désormais vers l'artefact gaté (regression_run.json).
- Gate : ci/check_readme_claims.sh recalcule tests+suites+verdict depuis
regression_run et exige l'égalité avec la fiche backend (comme la fiche QA).
- Preuve morsure : 560 réinjecté ⇒ gate rouge ; restauré ⇒ vert.
- 7 gates verts ; édition doc ⇒ aucune dérive out/ (check_artifacts vert).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>