[DTP-Worker 20260806_064502] DOC code-site — commentaire anti-footgun sur renderer._CANONICAL_MARKERS (oracle d'enforcement à garder indépendant)

Investigation: les 6 marqueurs canoniques #9/#10 existent en ≥4 endroits. Hypothèse
« (c) renderer._CANONICAL_MARKERS + (d) l'oracle du test sont des copies non gatées
→ dériver de model.CANONICAL (source unique) ». RÉFUTÉE par ./run_ci.sh (check-readme-claims
RED): la 2e moitié du gate ast.literal_eval STATIQUEMENT ces 2 listes et les set-diffe vs
CLAUDE.md → déjà gatées. Et surtout: check_canonical() PROUVE que le rendu (bâti DEPUIS
model.CANONICAL) émet chaque valeur; le dériver de CANONICAL rend le contrôle tautologique
(vert vacux). EXCEPTION à fix-vs-gate-transitively-protected-constant (qui vise les copies
PASSIVES; un oracle d'enforcement est ACTIF, sa duplication EST le test). Revert intégral
des 2 éditions (test byte-identique). Seul survivant: +5 lignes de commentaire remontant la
raison (indépendance de l'oracle) au site de code, autrement enfouie dans le script CI.
Sortie inchangée (commentaire pur), check_artifacts byte-identique.
run_ci 33 PASS 0 FAIL 0 SKIP · 0 artefact reconstruit · 0 gate ajouté (#5) · 0 chiffre inventé (#6)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-06 06:53:04 +00:00
parent e4b3488c7e
commit ddcafc58c0
2 changed files with 48 additions and 0 deletions
+43
View File
@@ -538,3 +538,46 @@ byte-identique.
**0 artefact reconstruit**, **0 gate ajouté** (#5 — dérive prose isolée, pas une classe **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 récurrente à gater), **0 chiffre inventé** (#6), **0 commande VPS** (#8). Structure du gate
inchangée (33 checks). 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).
@@ -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é). # 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"] _CANONICAL_MARKERS = ["3 %", "8.5 %", "52 %", "USD + DOP", "Cardnet", "Letter US"]