diff --git a/05_activity_log/2026-08-05.md b/05_activity_log/2026-08-05.md index ce855b1..bf6cdb6 100644 --- a/05_activity_log/2026-08-05.md +++ b/05_activity_log/2026-08-05.md @@ -1,5 +1,55 @@ # Activity Log · 2026-08-05 · Claude Code DTP Worker +## Session 051154 · Attestation des DENTS des **suites de MODULE** — BATCH 4 (FINAL) : les **7 dernières** suites → **25/25** prouvées · **7 BITES · 0 TOOTHLESS** · arbre byte-pristine · 0 édition de production + +**Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **33 PASS · 0 FAIL · 0 SKIP**, arbre propre, +roadmap `ROADMAP_8_WEEKS_OR_LESS.md` intégralement livrée/gatée — nous sommes au **Sprint 8 · QA : +regression tests exhaustifs**. Continuation et **clôture** de l'axe des DENTS des suites de MODULE +([[module-suite-teeth-mutation]]) : les batches 034144/041149/044153 ont prouvé **18/25**, laissant les +**7 dernières** non-couvertes (rbac-aggregate, portails, audit-4big, demo-scenario, regression, +deploy-runbook, acceptance) — **non-couvertes ≠ édentées, juste non-prouvées**. Ce batch les couvre +toutes → **25/25**. Axe distinct des 8 gates STATIQUES (8/8, 031134) : une suite qui rechargerait +`out/*.json` contre elle-même serait édentée = faux vert Sprint 8 comme un gate édenté. + +**Méthode.** Reconnaissance (Explore, read-only) pour cartographier, par module, **une ligne de LOGIQUE +de générateur** reconstruite en mémoire par une assertion. **Vérification critique avant de croire +l'agent** ([[module-suite-teeth-mutation]] leçon (b)) : deux mutations proposées étaient **INERTES**, +pas mordantes — `and→or` sur `deploylib/builder.py:61` (`not [] and not []` = True → `or` = True aussi, +sortie inchangée) et idem `acclib/builder.py:138`. Remplacées par des mutations qui **font basculer** la +sortie observée : `deploy` → `gated_set - mapped_set` **→ `|`** (union : `missing` non-vide, bijective +False, asserté par `test_coverage_bijective`) ; `acceptance` → `"exact": want == have` **→ `!=`** +(chaque `p["exact"]` bascule False, asserté par `test_partition_exact_all_sprints`). Unicité de chaque +cible re-vérifiée par `grep -Fc == 1` **avant** mutation. Harnais `/tmp` read-only +(`/tmp/suite_teeth_20260805_batch4.sh`) : **baseline verte** sanity → backup `cp` → `str.replace` (assert +1 occurrence) → run de **la seule suite du module** (working-directory dérivé de `ci.yml`) → assert +`exit≠0` → restauration `cp` + `cmp` byte-exact ; `trap EXIT` restaure tout ; jamais `git +clean`/`checkout` ([[ci-gate-verification-method]]). + +**6 BITES — mutations de LOGIQUE de générateur, sortie re-assertée en mémoire :** +- **portails** · `wslib/builder.py:114` `roles_couverts = sum(m["nb_roles"] …)` **`+ 1`** → `test_roles_restriction` recompte le total vs `manifest.counts.roles_couverts`. +- **audit-4big** · `q4lib/builder.py:30` `"fail": len(below)` **`+ 1`** → `test_real_build_passes_gate` exige `totals.fail == 0`. +- **demo-scenario** · `scenlib/builder.py:44` `duree = sum(b["duree_min"] …)` **`+ 1`** → `test_duree_est_somme_des_beats` recompte `sc["duree_min"]` vs somme des beats. +- **regression** · `reglib/builder.py:44` `"test_methods": sum(s["test_methods"] …)` **`- 1`** → `test_totals_match_suites` recompute la somme vs `totals.test_methods`. +- **deploy-runbook** · `deploylib/builder.py:59` `gated_set - mapped_set` **`→ |`** → `test_coverage_bijective` exige `bijective` + `missing==[]`. +- **acceptance** · `acclib/builder.py:136` `"exact": want == have` **`→ !=`** → `test_partition_exact_all_sprints` exige chaque `p["exact"]` + `partition_ok`. + +**1 BITE — sous-classe distincte (validation-de-CONTRAT, pas générateur).** `rbac-aggregate` +(`rbac/tests/test_rbac.py`) n'a **pas** de builder/`out/` : il charge directement le **contrat** +`rbac_50_roles.json` et y asserte des invariants absolus (schéma, ==50, unicité id/nom, couverture des 5 +portails, invariant #6 `set_user_permissions`). Structurellement **non-echo** (il ne compare pas un +artefact à lui-même — il contraint des constantes dures). Dent prouvée par une dérive du **contrat** +`"cible_rbac_roles": 50 → 49`, assertée par `test_exactement_50_roles` → **BITE**. Honnêteté de portée : +axe « contrat » ≠ axe « logique de générateur », signalé comme tel plutôt que forcé dans le même moule. + +**Verdict : 7 BITES · 0 TOOTHLESS → clôture 25/25 des suites de MODULE mordantes.** Combiné aux 8 gates +STATIQUES (8/8) et à la reproductibilité des artefacts, le Sprint 8 « regression tests exhaustifs » est +attesté sur ses **deux axes de DENTS**. + +**Vérifications.** Arbre **byte-pristine** après harnais (`git status --porcelain` vide, `git diff --stat` +vide). `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP** (aucun fichier gaté touché — restauration byte-exact). +**0 chiffre inventé (#6)** · **0 gate ajouté** (prouve les tests existants, n'en crée aucun — #5) · **0 +édition de production** · **aucune commande VPS (#8)** · **aucun `git clean`.** + ## Session 044153 · Attestation des DENTS des **suites de MODULE** — BATCH 3 : mutation-test *generator-logic* sur 6 nouvelles suites (→ **18/25** prouvées) · **6 BITES · 0 TOOTHLESS** · arbre byte-pristine · 0 édition de production **Contexte + choix de tâche.** `./run_ci.sh` au démarrage : **33 PASS · 0 FAIL · 0 SKIP**, arbre