diff --git a/05_activity_log/2026-08-06.md b/05_activity_log/2026-08-06.md index 5ac854d..e7958a7 100644 --- a/05_activity_log/2026-08-06.md +++ b/05_activity_log/2026-08-06.md @@ -538,3 +538,46 @@ byte-identique. **0 artefact reconstruit**, **0 gate ajouté** (#5 — dérive prose isolée, pas une classe récurrente à gater), **0 chiffre inventé** (#6), **0 commande VPS** (#8). Structure du gate inchangée (33 checks). + +## Session `20260806_064502` — Hypothèse « copie-constante à single-sourcer » RÉFUTÉE par le gate · +1 commentaire anti-footgun · 0 édition de production + +**Choix de tâche.** `./run_ci.sh` au démarrage = **33 PASS · 0 FAIL · 0 SKIP**, arbre propre, +roadmap intégralement livrée/gatée. Les ~10 derniers commits sont des sweeps vérif-only à +rendement décroissant. Objectif : traquer une **vraie duplication de constante mandat** à +single-sourcer (classe `fix-vs-gate-transitively-protected-constant` : DELETE la copie, pas +gate N+1), pas re-sweeper du déjà-couvert. + +**Piste investiguée (constantes canoniques #9/#10).** Les 6 marqueurs `3 % / 8.5 % / 52 % / +USD + DOP / Cardnet / Letter US` existent en **≥4 endroits** : (a) `CLAUDE.md` #9/#10 = source · +(b) `genlib/model.py` CANONICAL (émis dans chaque rendu) · (c) `genlib/renderer.py` +`_CANONICAL_MARKERS` (oracle de `check_canonical`) · (d) `tests/test_generator.py` la liste +`for marker in [...]`. J'ai d'abord lu la 1ʳᵉ moitié du gate `check_readme_claims` qui n'ancrait +explicitement que (a→b) + la prose README → **hypothèse** : (c) et (d) sont des copies **non +gatées** → les dériver de `model.CANONICAL` (source unique auto-suivante). + +**RÉFUTATION — le gate a mordu (bien joué la discipline `run_ci`).** Édité (c)+(d) → +`./run_ci.sh` = **32 PASS · 1 FAIL** (`check-readme-claims`). La **2ᵉ moitié** du même gate +(bloc ligne ~5475) `ast.literal_eval` **statiquement** les DEUX listes (regex +`_CANONICAL_MARKERS\s*=\s*(\[.*?\])` et `for marker in (\[...\])`) et les set-diffe vs les 6 +valeurs re-dérivées de CLAUDE.md. Donc (c)/(d) étaient **déjà gatés**. Pire : la dérivation +casse la raison d'être même de l'oracle — `check_canonical()` **prouve** que le rendu (bâti +DEPUIS `model.CANONICAL`) émet bien chaque valeur ; le dériver de `CANONICAL` rend le contrôle +**tautologique** (« md-bâti-depuis-X contient X » = vert vacux). Le commentaire du gate le dit +noir sur blanc : « si cette liste DÉRIVE de CANONICAL … le contrôle NE VÉRIFIE PLUS RIEN ». + +**Conclusion — EXCEPTION à `fix-vs-gate-transitively-protected-constant`.** Cette règle vise +les copies **passives** (prose, config). Un **oracle d'enforcement** est **actif** : sa +duplication EST le test ; l'ancrage correct = garder le littéral + gate statique vs la source +(exactement l'état existant). **Revert** intégral des 2 éditions (test byte-identique restauré). + +**Livrable retenu.** Un seul changement survit : **+5 lignes de commentaire anti-footgun** à +`renderer.py:275`, remontant au **site de code** la raison (indépendance de l'oracle) autrement +enfouie dans le script CI — pour qu'un mainteneur (ou moi, prochaine session) ne refasse pas la +« DRY-ification » qui décapite l'oracle. Sortie **inchangée** (commentaire pur), `check_artifacts` +byte-identique. Mémoire `enforcement-oracle-must-stay-independent` créée. + +**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP**. + +**Portée / anti-churn.** Édité : `renderer.py` (1 commentaire) + ce journal + mémoire. **0 artefact +reconstruit**, **0 gate ajouté** (#5), **0 chiffre inventé** (#6 — les 6 marqueurs déjà présents, +re-dérivés du gate), **0 commande VPS** (#8). Structure du gate inchangée (33 checks). diff --git a/05_deliverables_mvp/faisabilite/generator/genlib/renderer.py b/05_deliverables_mvp/faisabilite/generator/genlib/renderer.py index 71ea7f4..72873b1 100644 --- a/05_deliverables_mvp/faisabilite/generator/genlib/renderer.py +++ b/05_deliverables_mvp/faisabilite/generator/genlib/renderer.py @@ -272,6 +272,11 @@ def render_version_json(brief: dict, bilan: dict, generated_at: str, # --------------------------------------------------------------------------- # # Vérification des paramètres canoniques dans le rendu (axe 4, honnêteté). # --------------------------------------------------------------------------- # +# ORACLE INDÉPENDANT (à dessein) : ces 6 marqueurs sont une copie DÉLIBÉRÉMENT +# distincte de model.CANONICAL — c'est ce qui permet à check_canonical() de +# PROUVER que le rendu (bâti depuis CANONICAL) émet bien chaque valeur. Les +# dériver de CANONICAL rendrait le contrôle tautologique (vert vacux). La liste +# est plutôt ancrée statiquement à CLAUDE.md #9/#10 par ci/check_readme_claims. _CANONICAL_MARKERS = ["3 %", "8.5 %", "52 %", "USD + DOP", "Cardnet", "Letter US"]