[DTP-Worker 20260805_174324] GATE NEUF classe claude-md-constant-anchor : prose #9 des modules bancable + commissions ancrée sur CLAUDE.md. Mutation #9 (8.5%→9%) mordait DÉJÀ les 8 surfaces generator/template mais 4 copies restaient périmées EN SILENCE dans DEUX modules distincts, chacune se réclamant « (#9) »/« CLAUDE.md #9/#10 » (corriger le generator ne les touche pas → invention #6 latente) : (a) bancable/README.md + (b) banclib/finance.py docstring « 3% édition/8.5% marketing (#9) » · (c) banclib/deps.py « CLAUDE.md #9/#10 (3%/8.5%/52%·USD+DOP·Cardnet·Letter US) » 6 marqueurs · (d) crm/commissions/README.md « pourcentages canoniques (3% édition·8.5% marketing·52% équilibre) ». Extension du bloc d'ancrage existant (check_readme_claims.sh, après Template canonique) RÉUTILISANT exp (zéro re-parse). Teeth mutation-vérifiés : 8.5%→9% mord les 4 · 52%→55% mord (c)+(d) SEULS (a/b ne citent qu'édition+marketing = ciblage précis) · #10 Cardnet→Azul mord l'énum (c) ; arbre restauré = vert. Doc ci/README §2. 0 prod, 0 artefact rebuild (aucun out/ ni doc scoré audit_4big), 0 chiffre saisi (#6, recomputés de CLAUDE.md), 0 VPS (#8). run_ci 33 PASS·0 FAIL·0 SKIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-05 17:53:52 +00:00
parent db91a6bb5b
commit 1441693e25
3 changed files with 149 additions and 0 deletions
+93
View File
@@ -5864,6 +5864,99 @@ if exp is not None:
+ (f" · absents={miss}" if miss else "")
+ (f" · en trop={extra}" if extra else "") + " → régénérer le template")
# ============================================================================
# Bancable + Commissions · PROSE #9 (« pourcentages canoniques ») ANCRÉE sur
# CLAUDE.md — même classe d'ANCRAGE que « paramètres canoniques » (generator) et
# « Template canonique » ci-dessus, mais sur des MODULES DISTINCTS
# (faisabilite/bancable, crm/commissions) dont la doc RECOPIE à la main les
# pourcentages #9 en se réclamant EXPLICITEMENT « (#9) » / « CLAUDE.md #9/#10 »,
# sans qu'aucun gate ne les liât à la contrainte.
# ----------------------------------------------------------------------------
# Le bloc « paramètres canoniques » ancre le SEUL module generator (model.py /
# README / renderer / scorer / test) + le TEMPLATE. Restent QUATRE copies
# data-derived dans DEUX autres modules, toutes invisibles à check_artifacts
# (prose/docstrings hors out/) et non attrapées par leurs tests/ (FONCTIONS) :
# (a) faisabilite/bancable/README.md — « 3 % édition » et « 8.5 % marketing » (#9)
# (b) faisabilite/bancable/banclib/finance.py — MÊME phrase, en docstring
# (c) faisabilite/bancable/banclib/deps.py — « CLAUDE.md #9/#10 (3 %/8.5 %/52 %·…) »
# (d) crm/commissions/README.md — « (3 % édition · 8.5 % marketing · 52 % …) »
# La mutation #9 (ex. 8.5 %→9 %) fait DÉJÀ rougir les 8 surfaces generator/template,
# MAIS ces 4 copies-là restent périmées EN SILENCE : corriger le generator ne les
# TOUCHE pas (modules distincts) — invention #6 latente, de la classe déjà fermée
# 10× pour publiciste #10 / fiscal moneda / fiches #10. On RÉUTILISE `exp`
# (recompute #9 depuis CLAUDE.md · zéro duplication). Un claim absent échoue AUSSI.
# ============================================================================
if exp is not None:
_p_edt = _pnorm(exp["frais_edition_pct"]); _p_mkt = _pnorm(exp["marketing_pct"])
_p_eql = _pnorm(exp["point_equilibre_pct"])
_want6b = {_pnorm(exp[k]) for k in _num_keys} | {_ai(exp[k]) for k in _txt_keys}
# (a)+(b) même phrase « « E % édition » et « M % marketing » (#9) »
_duo_re = re.compile(r"«\s*([\d.]+)\s*%\s*[ée]dition\s*»\s*et\s*"
r"«\s*([\d.]+)\s*%\s*marketing\s*»\s*\(#9\)")
for _lbl, _rel in (("bancable/README", "faisabilite/bancable/README.md"),
("bancable/finance.py", "faisabilite/bancable/banclib/finance.py")):
_txt = read_norm(f"{D}/{_rel}")
if _txt is None:
bad(f"Canoniques prose #9 · {_lbl} illisible"); continue
_mm = _duo_re.search(_txt)
if _mm is None:
bad(f"Canoniques prose #9 · {_lbl} — phrase « « N % édition » et "
f"« N % marketing » (#9) » INTROUVABLE (traçabilité #6)")
else:
_got = {_pnorm(float(_mm.group(1))), _pnorm(float(_mm.group(2)))}
_want = {_p_edt, _p_mkt}
if _got == _want:
good(f"Canoniques prose #9 · {_lbl} — {_p_edt} édition · {_p_mkt} "
f"marketing == CLAUDE.md #9")
else:
bad(f"Canoniques prose #9 · {_lbl} — cite {sorted(_got)} MAIS CLAUDE.md "
f"{sorted(_want)} → aligner (ou CLAUDE.md)")
# (c) deps.py « CLAUDE.md #9/#10 (3 % / 8.5 % / 52 % · USD+DOP · Cardnet · Letter US) »
_dep = read_norm(f"{D}/faisabilite/bancable/banclib/deps.py")
if _dep is None:
bad("Canoniques prose #9 · bancable/deps.py illisible")
else:
_md = re.search(r"CLAUDE\.md #9/#10\s*\(([^)]+)\)", _dep)
if _md is None:
bad("Canoniques prose #9 · bancable/deps.py — « CLAUDE.md #9/#10 (…) » "
"INTROUVABLE (traçabilité #6)")
else:
_got = set()
for _tok in re.split(r"[/·]", _md.group(1)):
_p = _pct(_tok)
_got.add(_pnorm(_p) if _p is not None else _ai(_tok))
_got.discard("")
if _got == _want6b:
good("Canoniques prose #9 · bancable/deps.py — 6 marqueurs == "
"CLAUDE.md #9/#10")
else:
_miss = sorted(_want6b - _got); _extra = sorted(_got - _want6b)
bad(f"Canoniques prose #9 · bancable/deps.py — énumère {sorted(_got)} MAIS "
f"CLAUDE.md {sorted(_want6b)}"
+ (f" · absents={_miss}" if _miss else "")
+ (f" · en trop={_extra}" if _extra else "") + " → aligner (ou CLAUDE.md)")
# (d) commissions/README « pourcentages canoniques (E % édition · M % marketing · Q % …) »
_com = read_norm(f"{D}/crm/commissions/README.md")
if _com is None:
bad("Canoniques prose #9 · commissions/README illisible")
else:
_mc = re.search(r"pourcentages canoniques\s*\(([^)]*%[^)]*)\)", _com)
if _mc is None:
bad("Canoniques prose #9 · commissions/README — « pourcentages canoniques "
"(… %) » INTROUVABLE (traçabilité #6)")
else:
_got = {_pnorm(float(_x)) for _x in re.findall(r"([\d.]+)\s*%", _mc.group(1))}
_want = {_p_edt, _p_mkt, _p_eql}
if _got == _want:
good(f"Canoniques prose #9 · commissions/README — {sorted(_want)} == "
f"CLAUDE.md #9")
else:
_miss = sorted(_want - _got); _extra = sorted(_got - _want)
bad(f"Canoniques prose #9 · commissions/README — cite {sorted(_got)} MAIS "
f"CLAUDE.md {sorted(_want)}"
+ (f" · absents={_miss}" if _miss else "")
+ (f" · en trop={_extra}" if _extra else "") + " → aligner (ou CLAUDE.md)")
# ============================================================================
# Fiscal · ecf_dgii — le JEU DE DEVISES `moneda` (`USD`/`DOP`) ANCRÉ sur CLAUDE.md
# #10 — même classe d'ANCRAGE que la CITATION #10 des fiches ci-dessus, mais sur