a5de76b7c1
4ᵉ application du pattern « ledger d'invariants » (après Chat OTOIA · SEO · Fiscal e-CF) à legal/confotur/confotur_application_gen.py. Le compte « 14 invariants » y est transcrit à la main à SIX endroits non gatés, tous invisibles à check_artifacts (le .py n'est pas un out/*.json) : 4 chaînes du .py (docstrings module + _validate, succès CLI, aide du sous-parseur) + 2 du README (bloc de commande, commentaire d'arborescence). Ajouter un contrôle # 15 · à _validate sans toucher les 6 chaînes ⇒ README + self-reports mentent en silence pendant que la CI applique 15 contrôles — « vert trompeur » que ni tests/ (FONCTIONS, pas la prose) ni le byte-gate d'artefact n'attrapent. Particularité CONFOTUR (≠ Fiscal) : ledger PROPRE 1..14 (pas de schéma-#1 non marqué, pas de split a/b) MAIS le README porte AUSSI un compte de SOUS-ENSEMBLE éditorial (« 2 invariants refusent tout champ monétaire ») à ne pas confondre avec le total — un \d+ invariants naïf mordrait l'arbre propre. Le gate exclut le sous-ensemble par lookahead négatif (\d+)\s+invariants(?!\s+refusent), appliqué au .py comme au README. Nouveau bloc (ci/check_readme_claims.sh) : RECOMPUTE le ledger depuis le SEUL registre-source (# N · de _validate) et exige (a) ledger CONTIGU 1..N (lacune OU doublon nu = vrai défaut) ; (b) toute mention-total du .py == |ledger| ; (c) toute mention-total du README (hors « refusent ») == |ledger|. 3 checks verts sur l'arbre propre. 6 morsures vérifiées (M1 self-report .py 14→15 · M2 README commande 14→15 · M3 README arborescence 14→13 · M4 ajout # 15 · ⇒ ledger→15 vs prose 14, mord .py ET README · M5 gap # 7 · · M6 doublon nu # 5 ·) + M7 no-false-positive (sous-ensemble 2→3 reste vert). 6 gates re-verts exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>