From 85939616837e29a1f55ee3d7ded4d50c9c392b49 Mon Sep 17 00:00:00 2001 From: Claude Code DTP Worker Date: Sat, 1 Aug 2026 04:37:25 +0000 Subject: [PATCH] =?UTF-8?q?[DTP-Worker]=20Sprint=208=20=C2=B7=20buffer=20?= =?UTF-8?q?=C2=B7=20Fiches=20agents/citation=20CLAUDE.md=20#10=20:=20la=20?= =?UTF-8?q?prose=20=C2=AB=20Anti-invention=20=C2=BB=20de=20DEUX=20fiches?= =?UTF-8?q?=20=E2=80=94=20`03=5Fagents/erpnext=5Fbackend/AGENT.md:57`=20(d?= =?UTF-8?q?evises=20**USD=20+=20DOP**=20=C2=B7=20format=20**Letter=20US**?= =?UTF-8?q?=20=C2=B7=20paiements=20**Cardnet**,=20pas=20Stripe)=20et=20`03?= =?UTF-8?q?=5Fagents/crm/AGENT.md:37`=20(devises=20**USD=20+=20DOP**=20?= =?UTF-8?q?=C2=B7=20format=20**Letter=20US**)=20=E2=80=94=20RECOPIE=20?= =?UTF-8?q?=C3=80=20LA=20MAIN=20les=20valeurs=20canoniques=20de=20la=20con?= =?UTF-8?q?trainte=20NON-N=C3=89GOCIABLE=20CLAUDE.md=20#10=20en=20AFFIRMAN?= =?UTF-8?q?T=20=C2=AB=20cit=C3=A9s=20depuis=20CLAUDE.md=20#10,=20jamais=20?= =?UTF-8?q?r=C3=A9invent=C3=A9s=20=C2=BB,=20mais=20AUCUN=20gate=20ne=20lia?= =?UTF-8?q?it=20cette=20citation=20=C3=A0=20#10.=20Le=20bloc=20=C2=AB=20pa?= =?UTF-8?q?ram=C3=A8tres=20canoniques=20=C2=BB=20faisabilite/generator=20n?= =?UTF-8?q?'ancre=20QUE=20genlib/model.py=20CANONICAL=20+=20son=20README?= =?UTF-8?q?=20(classe=20claude-md-constant-anchor),=20AVEUGLE=20=C3=A0=20c?= =?UTF-8?q?es=20fiches=20;=20aucune=20suite=20tests/=20(FONCTIONS,=20jamai?= =?UTF-8?q?s=20l'ancre=20=C3=A0=20CLAUDE.md)=20n'attrape=20la=20prose.=20P?= =?UTF-8?q?i=C3=A8ge=20#6=20:=20RENOMMER=20le=20prestataire=20(`Cardnet`?= =?UTF-8?q?=E2=86=92`Azul`)=20ou=20changer=20une=20devise/format=20dans=20?= =?UTF-8?q?CLAUDE.md=20#10=20laisse=20ces=20citations=20P=C3=89RIM=C3=89ES?= =?UTF-8?q?=20en=20silence,=20contredisant=20le=20mandat=20pendant=20que?= =?UTF-8?q?=20la=20prose=20se=20r=C3=A9clame=20de=20=C2=AB=20CLAUDE.md=20#?= =?UTF-8?q?10=20=C2=BB=20=E2=80=94=20=C2=AB=20vert=20trompeur=20=C2=BB.=20?= =?UTF-8?q?Gate=20ajout=C3=A9=20(bloc=20=C2=AB=20Fiches=20agents=20=C2=B7?= =?UTF-8?q?=20CITATION=20des=20constantes=20CLAUDE.md=20#10=20=C2=BB)=20:?= =?UTF-8?q?=20r=C3=A9utilise=20les=20valeurs=20`exp`=20d=C3=A9j=C3=A0=20re?= =?UTF-8?q?comput=C3=A9es=20de=20#9/#10=20(z=C3=A9ro=20duplication)=20+=20?= =?UTF-8?q?le=20prestataire=20EXCLU=20(`(pas=20X)`)=20recomput=C3=A9=20de?= =?UTF-8?q?=20#10=20;=20config=20table=20par-fiche=20du=20SOUS-ENSEMBLE=20?= =?UTF-8?q?de=20tokens=20qu'elle=20cite=20(crm=20omet=20le=20paiement)=20;?= =?UTF-8?q?=20exige=20l'ancre=20=C2=AB=20CLAUDE.md=20#10=20=C2=BB=20+=20ch?= =?UTF-8?q?aque=20token=20en=20gras=20`****`=20=3D=3D=20#10=20(cas?= =?UTF-8?q?se=20tol=C3=A9r=C3=A9e)=20+=20l'exclusion=20pour=20erpnext.=205?= =?UTF-8?q?=20morsures=20v=C3=A9rifi=C3=A9es=20(Cardnet=E2=86=92Azul=20mor?= =?UTF-8?q?d=20erpnext=20SEUL=20=C2=B7=20devises=20mord=20les=20DEUX=20?= =?UTF-8?q?=C2=B7=20exclusion=20Stripe=E2=86=92PayPal=20=C2=B7=20fiche=20c?= =?UTF-8?q?rm=20Letter=20US=20p=C3=A9rim=C3=A9=20=C2=B7=20ancre=20#10=20su?= =?UTF-8?q?pprim=C3=A9e=20=E2=86=92=20INTROUVABLE),=20restaur=C3=A9=20vert?= =?UTF-8?q?,=207=20gates=20re-verts.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- 05_activity_log/2026-08-01.md | 33 +++++++++++++++++++ ci/check_readme_claims.sh | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/05_activity_log/2026-08-01.md b/05_activity_log/2026-08-01.md index 92770b3..ca3e7e7 100644 --- a/05_activity_log/2026-08-01.md +++ b/05_activity_log/2026-08-01.md @@ -513,3 +513,36 @@ absolu) · **7 gates re-verts** (`check_readme_claims`/`check_ci_integrity`/ édition **hors** `05_deliverables_mvp/*/out` ⇒ 0 dérive d'artefact ; l'import réel du DocType puis du Workflow reste côté agent ERPNext Backend / VPS). - **Auto-score 4Big** : 96/100. + +## Session `20260801_043224` · Buffer S8 · Fiches agents/citation CLAUDE.md #10 : la prose « Anti-invention » de DEUX fiches — `03_agents/erpnext_backend/AGENT.md:57` (devises **USD + DOP** · format **Letter US** · paiements **Cardnet**, pas Stripe) et `03_agents/crm/AGENT.md:37` (devises **USD + DOP** · format **Letter US**) — RECOPIE À LA MAIN les valeurs canoniques de la contrainte NON-NÉGOCIABLE CLAUDE.md #10 en AFFIRMANT « cités depuis CLAUDE.md #10, jamais réinventés », mais AUCUN gate ne liait cette citation à #10. + +**Tâche** : **Sprint 8 · buffer** (DevOps CI/CD · QA). Roadmap fonctionnellement close ; +poursuite de la série anti-dérive d'ANCRAGE à CLAUDE.md (classe [[claude-md-constant-anchor-gate]]). +Même patron EXACT que le bloc « paramètres canoniques » faisabilite/generator (model.py +CANONICAL ↔ #9/#10) et publiciste/branding (4 tokens ↔ #4) — appliqué à une SURFACE +distincte : la prose des fiches agents qui se réclame de #10. + +**Dérive silencieuse fermée** : +- `03_agents/erpnext_backend/AGENT.md:57` + `03_agents/crm/AGENT.md:37` — prose + « Anti-invention (#6) » citant en gras les tokens #10 (devises/format/paiement). +- Source faisant autorité : la contrainte NON-NÉGOCIABLE **CLAUDE.md #10** + (`**USD + DOP**` devises · `**Letter US**` format · `**Cardnet**` paiements (pas Stripe)). +- Le seul contrôle amont (bloc « paramètres canoniques ») n'ancre QUE + `faisabilite/generator/genlib/model.py` CANONICAL + son README — AVEUGLE à ces fiches. + Aucune suite `tests/` (FONCTIONS, jamais l'ancre à CLAUDE.md) n'attrape la prose. +- Piège #6 : RENOMMER le prestataire (`Cardnet`→`Azul`) ou changer une devise/format dans + CLAUDE.md #10 laisse ces citations PÉRIMÉES en silence, contredisant le mandat pendant + que la prose se réclame de « CLAUDE.md #10 » — « vert trompeur ». + +**Gate ajouté** (bloc « Fiches agents · CITATION des constantes CLAUDE.md #10 ») : +réutilise les valeurs `exp` déjà recomputées de #9/#10 (zéro duplication) + le prestataire +EXCLU (`(pas X)`) recomputé de #10 ; config table par-fiche du SOUS-ENSEMBLE de tokens +qu'elle cite (crm omet le paiement) ; exige de chaque fiche l'ancre « CLAUDE.md #10 » + +chaque token en gras `****` == #10 (casse tolérée) + l'exclusion pour erpnext. + +**5 morsures vérifiées** (restauré vert après chacune, 7 gates re-verts) : +1. CLAUDE.md #10 `Cardnet`→`Azul` → mord erpnext SEUL (crm ne cite pas le paiement) ✓ +2. CLAUDE.md #10 devises `USD + DOP`→`USD + EUR` → mord les DEUX fiches ✓ +3. CLAUDE.md #10 `(pas Stripe)`→`(pas PayPal)` → mord l'exclusion erpnext ✓ +4. fiche crm `Letter US`→`Letter USA` → mord CRM (format) ✓ +5. fiche erpnext supprime l'ancre `CLAUDE.md #10` → mord INTROUVABLE ✓ diff --git a/ci/check_readme_claims.sh b/ci/check_readme_claims.sh index 22dcc67..0f0c064 100755 --- a/ci/check_readme_claims.sh +++ b/ci/check_readme_claims.sh @@ -2870,6 +2870,67 @@ if exp is not None: bad(f"Faisabilité canoniques · {FG_RD} — prose énumère {sorted(got)} MAIS " f"CLAUDE.md {sorted(want)}{detail} → régénérer le README") +# ============================================================================ +# Fiches agents · CITATION des constantes CLAUDE.md #10 (devises/format/paiement) +# — même classe d'ANCRAGE que le bloc « paramètres canoniques » ci-dessus, mais +# sur une SURFACE distincte : la prose « Anti-invention » des fiches agents. +# ---------------------------------------------------------------------------- +# Deux fiches RECOPIENT à la main les valeurs canoniques de CLAUDE.md #10 +# (**USD + DOP** devises · **Letter US** format · **Cardnet** paiements, pas +# Stripe) en AFFIRMANT « cités depuis CLAUDE.md #10, jamais réinventés » : +# • 03_agents/erpnext_backend/AGENT.md:57 — devises **USD + DOP**, format +# **Letter US**, paiements **Cardnet** (pas Stripe) +# • 03_agents/crm/AGENT.md:37 — devises **USD + DOP** et format **Letter US** +# La prose PRÉTEND être une CITATION de #10, mais AUCUN gate ne la liait à #10 : +# le bloc « paramètres canoniques » ci-dessus n'ancre QUE genlib/model.py +# CANONICAL + le README generator — AVEUGLE à ces deux fiches. Piège #6 : RENOMMER +# le prestataire de paiement dans CLAUDE.md #10 (`Cardnet` → `Azul`) ou changer une +# devise/format laisse ces citations PÉRIMÉES en silence, contredisant le mandat +# pendant que la prose se réclame de « CLAUDE.md #10 » — « vert trompeur » qu'aucune +# suite tests/ (FONCTIONS, jamais l'ancre à CLAUDE.md) n'attrape. On RÉUTILISE les +# valeurs `exp` déjà recomputées depuis #10 (zéro duplication) + le prestataire +# EXCLU (`(pas X)`), et on exige de CHAQUE fiche les tokens en gras qu'elle cite +# EXACTEMENT + l'ancre « CLAUDE.md #10 ». Chaque fiche cite un SOUS-ENSEMBLE +# distinct (crm omet le paiement) → gate par-fiche ce que la fiche énonce. +# ============================================================================ +if exp is not None: + _m_excl = re.search(r"\(pas\s+(.+?)\)", l10.group(1)) + exp_excl = _m_excl.group(1).strip() if _m_excl else None + _lab10 = {"devises": "devises", "format_doc": "format", "paiement": "paiement"} + # (fiche, [clés #10 citées], cite l'exclusion « (pas X) » ?, libellé) + FICHE10 = [ + ("03_agents/erpnext_backend/AGENT.md", + ["devises", "format_doc", "paiement"], True, "fiche ERPNext Backend:57"), + ("03_agents/crm/AGENT.md", + ["devises", "format_doc"], False, "fiche CRM:37"), + ] + for path, keys, cites_excl, label in FICHE10: + txt = read_norm(path) + if txt is None: + continue + # ancrage : la citation DOIT se réclamer de CLAUDE.md #10 + if not re.search(r"CLAUDE\.md #10", txt): + bad(f"Fiches #10 · {label} ({path}) — ancre « CLAUDE.md #10 » " + f"INTROUVABLE → la citation ne se réclame plus de la contrainte") + continue + drift = [] + for k in keys: + # token en gras **** == valeur recomputée de #10 (casse tolérée) + if not re.search(r"\*\*\s*" + re.escape(exp[k]) + r"\s*\*\*", + txt, re.IGNORECASE): + drift.append(f"{_lab10[k]} attendu **{exp[k]}**") + if cites_excl and exp_excl is not None: + if not re.search(r"\(pas\s+" + re.escape(exp_excl) + r"\)", + txt, re.IGNORECASE): + drift.append(f"exclusion attendue « (pas {exp_excl}) »") + if drift: + bad(f"Fiches #10 · {label} ({path}) — citation DÉRIVE de CLAUDE.md #10 : " + f"{' · '.join(drift)} → aligner la fiche (ou CLAUDE.md)") + else: + _cited = " · ".join(f"**{exp[k]}**" for k in keys) + \ + (f" · (pas {exp_excl})" if cites_excl and exp_excl else "") + good(f"Fiches #10 · {label} — cite {_cited} == CLAUDE.md #10") + # ============================================================================ # Démo · run-sheet de pitch (2e surface du MÊME README) · la TABLE des SCÉNARIOS # — l'IDENTITÉ de chaque ligne (id · projet+libellé · audience), jamais gatée.