[DTP-Worker 20260802_070524] Sprint 8 · buffer · Mobile app_config : gate d'IDENTITÉ du COMPTE D'INVARIANTS de _validate_bundle (8ᵉ instance de la classe ledger)

Recompute le compte « 12 invariants » depuis le SEUL registre-source
(`# Invariant N ·` de `_validate_bundle`) — 4 surfaces prose hand-transcrites
(CLI .py, 2× README, docstring test) ancrées, aucune n'était gatée. Style de
marqueur `# Invariant N ·` + fonction `_validate_bundle` = deux différences
structurelles vs les 7 blocs `# N ·`/`_validate` précédents ; ajoute la surface
fichier-de-tests (b'). 4 verts arbre propre · 8 morsures adversariales · 6 gates
CI exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-02 07:11:34 +00:00
parent 335d449346
commit 655eeeb4a1
2 changed files with 181 additions and 0 deletions
+58
View File
@@ -718,3 +718,61 @@ CODE, pas la prose) · M5 suppression `# 7 ·` ⇒ gap non-contigu (a) · M6 dou
7 (e) · M8 suppression `validate(bundle, schema)` ⇒ invariant 1 introuvable. Gates
re-verts : `check_artifacts` · `check_docs` · `guard_constraints` ·
`check_ci_integrity` · `check_readme_claims` · `check_regression` tous exit 0.
---
## Sprint 8 · buffer · Mobile app_config : gate d'IDENTITÉ du COMPTE D'INVARIANTS de `_validate_bundle` (8ᵉ instance)
**Contexte** — Série anti-dérive Sprint 8 (CLAUDE.md #6 « zéro invention de
chiffres »). La classe « ledger d'invariants » (recompute le nombre d'invariants CI
depuis le registre-source numéroté de la fonction de validation, jamais une liste à
la main) était déjà appliquée à **7 générateurs** : Chat OTOIA · SEO · Fiscal e-CF ·
Legal CONFOTUR · CRM Dossier Vente · QA Audit 5D · CRM Commissions. Le **8ᵉ**
générateur portant le même nombre magique restait NON couvert :
`mobile/app_config/app_config_gen.py`.
Le compte **« 12 invariants »** y est transcrit **à la main à QUATRE endroits**,
aucun gaté, tous invisibles à `check_artifacts` (le `.py`/`.md`/test n'est pas un
`out/*.json`) :
1. `app_config_gen.py` message de succès CLI « … schéma + 12 invariants verts. »
(l.228) ;
2. `README.md` bloc de commande « schéma + 12 invariants » (l.48) ;
3. `README.md` prose de récap « Schéma + 12\ninvariants verts » (l.67-68 — le « 12 »
et le mot séparés par un saut de ligne) ;
4. `tests/test_mobile_app_config.py` docstring « … + les 12 invariants du CLI »
(l.4).
Ajouter un contrôle `# Invariant 13 ·` à `_validate_bundle` sans toucher les 4
chaînes ⇒ le README, le self-report CLI ET la docstring de test mentent en silence
pendant que la CI applique 13 contrôles. Aucune suite `tests/` (qui EXÉCUTE la
validation mais ne compte jamais la prose) ne l'attrape.
**Particularités vs les 7 blocs précédents** (documentées dans l'en-tête du gate) :
- le registre-source utilise le style **`# Invariant N ·`** (le mot « Invariant »
précède le numéro) — les blocs ancrés sur le style nu `# N ·` NE le voient PAS ;
ancrage sur `#\s*Invariant\s+(\d+)…` ;
- la fonction s'appelle **`_validate_bundle`** (pas `_validate`) — l'ancre `def
_validate\b` des autres blocs échoue (`\b` échoue avant `_bundle`) ;
- ce README n'a NI titre « ## Les N invariants » NI énumération numérotée → on gate
**(a)(b)(b')(d)**, en AJOUTANT la surface **fichier-de-tests (b')**, absente des 7
blocs précédents (leurs tests ne portaient pas le chiffre).
**Gate ajouté** (`ci/check_readme_claims.sh`, bloc « Mobile · app_config · IDENTITÉ
du COMPTE D'INVARIANTS ») — RECOMPUTE le ledger depuis le SEUL registre-source
(`# Invariant N ·` de `_validate_bundle`) et exige :
- **(a)** ledger CONTIGU 1..N (schéma compté à part ; lacune OU doublon nu = défaut
mordu) ;
- **(b)** toute mention « N invariants » du `.py` == |ledger| ;
- **(b')** toute mention « N invariants » du fichier de tests == |ledger| ;
- **(d)** toute mention « N invariants » du README == |ledger|.
**Vérif** — 4 checks verts sur l'arbre propre (ledger 1..12 = 12 marqueurs). **8
morsures** adversariales : M1 self-report CLI 12→13 (b) · M2 README bloc-commande
12→13 (d) · M3 README récap (newline-split) 12→13 (d, preuve que `\s+` traverse le
saut de ligne) · M4 docstring test 12→13 (b', la surface neuve) · M5 ajout marqueur
`# Invariant 13 ·` ⇒ ledger→13 pendant que les 3 surfaces prose restent 12 (b+b'+d,
preuve que l'autorité est le CODE, pas la prose) · M6 suppression `# Invariant 7 ·`
⇒ gap non-contigu (a) + désync prose · M7 doublon nu `# Invariant 5 ·` ⇒ détection
de vrai doublon · M8 renommage `_validate_bundle` ⇒ registre introuvable. Gates
re-verts : `check_artifacts` · `check_docs` · `guard_constraints` ·
`check_ci_integrity` · `check_readme_claims` · `check_regression` tous exit 0.