e38dd933c6
Continuation de l'axe des DENTS des suites de MODULE ([[module-suite-teeth-mutation]]) : batches 034144+041149 avaient prouvé 12/25 ; ce batch 3 en couvre 6 de plus → 18/25 · 7 restantes non-couvertes ≠ édentées (pas de plafond silencieux). 6 BITES (chaque suite mord sur une dérive de LOGIQUE de son générateur, jamais un écho d'artefact) : - rbac/fixtures_gen builder:43 if_owner ==→!= (test_if_owner_reflete_scope_own) - rbac/userperm_gen builder:43 by_mechanism += 1→+=2 (sum==50) - rbac/apply_plan aggregator:174 chaîne bijective 2e ==→!= (assertTrue couverture_bijective) - mobile/app_config builder:105 roles=sorted(...)+reverse=True (==sorted(roles_map[portail])) - qa/audit_5d builder:60 count(_FAIL)→count(_PASS) (totals fail:0→13) - frontend/chat_otoia builder:114 sum(nb_roles)→sum(1) (test_44_roles_couverts 44→~5) Axe distinct des DENTS des 8 gates STATIQUES (031134, 8/8) : une suite qui rechargerait out/*.json contre elle-même serait édentée = faux vert Sprint 8 · les suites reconstruisent en mémoire depuis le contrat. LEÇON réappliquée (désambiguïser TOOTHLESS-test vs mutation INERTE) : le 1er pick mobile (:192 roles_couverts sum→len) était édenté pour la suite de MODULE (agrégat jamais ré-asserté en mémoire) ; basculé sur :105 (tri, réellement contraint). Idem fixtures :68 → :43. Harnais /tmp read-only, remplacement d'octets littéral (assert 1 occurrence), run de la seule suite, restore byte-exact cp+cmp, trap EXIT, jamais git clean, arbre pristine · 0 gate ajouté (#5) · 0 chiffre inventé (#6) · 0 édition prod · CI 33 PASS Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>