From 986d29362c0f762611fe9e898c7e1fd6ffbb5500 Mon Sep 17 00:00:00 2001 From: Claude Code DTP Worker Date: Wed, 5 Aug 2026 05:19:04 +0000 Subject: [PATCH] =?UTF-8?q?[DTP-Worker=2020260805=5F051154]=20Attestation?= =?UTF-8?q?=20des=20DENTS=20des=20suites=20de=20MODULE=20=E2=80=94=20BATCH?= =?UTF-8?q?=204=20(FINAL)=20:=20mutation-test=20les=207=20derni=C3=A8res?= =?UTF-8?q?=20suites=20=E2=86=92=20CL=C3=94TURE=2025/25=20=C2=B7=207=20BIT?= =?UTF-8?q?ES=20=C2=B7=200=20TOOTHLESS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6 mutations de LOGIQUE de générateur (sortie re-assertée en mémoire) : portails roles_couverts sum +1 · audit-4big totals.fail len(below) +1 · demo duree_min sum +1 · regression test_methods sum -1 · deploy couverture-bijective gated_set-mapped_set → | · acceptance exact want==have → !=. 2 mutations proposées par Explore étaient INERTES (and→or sur 'not [] and not []' reste True) — remplacées par des mutations qui font BASCULER la sortie observée (leçon (b) désambiguïsation test-édenté vs mutation-inerte appliquée en direct). 1 sous-classe DISTINCTE : rbac-aggregate (test_rbac.py) n'a pas de builder/out — il valide le CONTRAT rbac_50_roles.json (schéma, ==50, unicité, 5 portails, set_user_permissions #6), structurellement non-echo ; dent prouvée par dérive du contrat cible 50→49 (test_exactement_50_roles). Axe contrat signalé honnêtement ≠ axe logique-générateur. Clôture 25/25 des suites de MODULE mordantes + 8/8 gates STATIQUES = Sprint 8 'regression tests exhaustifs' attesté sur ses deux axes de DENTS. Harnais /tmp read-only (baseline verte → cp → str.replace unicité → run suite seule → assert exit≠0 → restore cp+cmp), trap EXIT, jamais git clean/checkout, arbre byte-pristine. 0 gate ajouté (#5) · 0 chiffre inventé (#6) · 0 édition prod · aucune commande VPS (#8) · CI 33 PASS Co-Authored-By: Claude Opus 4.8 (1M context) --- 05_activity_log/2026-08-05.md | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) 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