[DTP-Worker 20260802_093532] Sprint 8 · buffer · Ledger d'invariants 9ᵉ instance : gate d'IDENTITÉ du COMPTE de _validate_bundle de crm/workflow_vente (dialecte # Invariant N ·, 3ᵉ oubli de la classe « close »)

Le générateur workflow_vente_gen.py (Livrable Sprint 4 l.50) porte un ledger de
9 invariants métier de graphe dans `_validate_bundle` (marqueurs `# Invariant N ·`,
phrasé « schéma + 9 invariants »), avec le nombre « 9 » recopié à la main à 4
surfaces vives (gen l.223 + README l.78/114/125), aucune gatée. Prouvé ungate
avant ajout (README 9→10 laissait check_readme_claims exit 0). Gate ajouté
(a)(b)(d) sur le modèle Mobile : recompute le ledger depuis le SEUL registre-source
`# Invariant N ·`, exige contiguïté 1..N + toute mention « N invariants » du .py et
du README == |ledger|. Pas de gate (e) enum : la liste « ## Invariants vérifiés par
le CLI » compte le schéma en item 1 et fusionne les invariants 8&9 → n'est pas le
ledger (faux positif fragile évité). « 25 tests » exclu nativement par l'ancre
« invariants » (aucun faux positif). 3 checks verts arbre propre · 7 morsures
adversariales (dont M3 SILENT-GREEN `# Invariant 10 ·` ⇒ autorité=CODE, M7
no-false-positive) · unittest 25 OK · suite CI complète re-verte.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-02 09:42:13 +00:00
parent ca15e7e12b
commit 3cb1bf06e1
2 changed files with 177 additions and 0 deletions
+64
View File
@@ -1,5 +1,69 @@
# Activity log · 2026-08-02 · Claude Code DTP Worker
## Sprint 8 · buffer · CRM/workflow_vente — gate d'IDENTITÉ du COMPTE D'INVARIANTS de `_validate_bundle` (9ᵉ instance du ledger · dialecte `# Invariant N ·`)
**Contexte** — Série anti-dérive Sprint 8 (CLAUDE.md #6 « zéro invention de
chiffres »). La classe « ledger d'invariants » (recompute le nombre de contrôles
CI depuis le registre-source des marqueurs numérotés de la fonction de validation,
jamais une liste à la main) était consignée « close à 8 générateurs » (Chat OTOIA ·
SEO · Fiscal e-CF · Legal CONFOTUR · CRM Dossier Vente · QA Audit 5D · CRM
Commissions · Mobile) + 2 (deploy_runbook/acceptance, dialecte `# INVn`). La mémoire
`invariant-ledger-count-gate` avertit précisément : « CLOSED a été prouvé FAUX DEUX
FOIS ; re-scanner TOUS les dialectes de marqueur AVANT de croire la clôture ». Un
**3ᵉ oubli** a été exhumé : `crm/workflow_vente/workflow_vente_gen.py` (Livrable
Sprint 4 l.50 · workflow de vente Frappe lead→…→CONFOTUR) porte un ledger de **9
invariants métier de graphe** dans `_validate_bundle`, marqueurs `# Invariant N ·`
(style Mobile), phrasé « schéma + 9 invariants ». Le nombre « 9 » est recopié À LA
MAIN à **4 surfaces vives**, aucune gatée : générateur l.223 (message CLI de succès)
· README l.78 (bloc de commande) · README l.114 (prose de vérification) · README
l.125 (prose d'auto-score).
**Le « vert trompeur » — PROUVÉ ungate avant ajout** (mémoire
`verify-uncovered-before-gating`) : muter « 9 invariants »→« 10 » dans le README
laissait `check_readme_claims` **exit 0**. Ni `check_artifacts` (le `.py` source
n'est pas un `out/*.json`) ni les suites `tests/` (FONCTIONS de validation, jamais
la prose) n'attrapent la dérive. Ajouter un contrôle `# Invariant 10 ·` à
`_validate_bundle` sans toucher les 4 chaînes ⇒ README + self-report CLI mentent en
silence pendant que la CI applique 10 contrôles.
**Particularités du registre** (vs les 8 blocs `# N ·`) — style `# Invariant N ·` +
fonction `_validate_bundle` (comme Mobile ; les blocs ancrés `# N ·`/`def _validate\b`
ne le voient pas). Ledger PROPRE 1..9 compté À PART du schéma (« schéma + N
invariants » · pas de schéma-#1, pas de split a/b ; filet doublon nu conservé). Un
SECOND nombre distinct — « **25 tests** » (suite unittest, déjà gatée) — présent au
README : l'ancre sur le mot « invariants » l'exclut nativement ⇒ **aucun faux
positif**. Le README N'A NI titre « ## Les N invariants » (son titre « ## Invariants
vérifiés par le CLI » ne porte aucun chiffre) NI énumération 1:1 avec le ledger — sa
liste compte le SCHÉMA en item 1 puis **FUSIONNE les invariants 8 & 9** dans son item
9 (« Maîtres … ; comptes du manifeste cohérents ») : elle N'EST PAS le ledger, la
gater comme contiguë==ledger serait un faux positif fragile (présentation éditoriale).
On gate donc UNIQUEMENT (a)(b)(d), comme Audit 5D.
**Gate ajouté** (`ci/check_readme_claims.sh`, bloc « CRM · workflow_vente · IDENTITÉ
du COMPTE D'INVARIANTS », juste après le bloc Mobile) — RECOMPUTE le ledger depuis
le SEUL registre-source (les `# Invariant N ·` de `_validate_bundle`, corps extrait
jusqu'au `def` suivant) et exige : **(a)** ledger CONTIGU 1..N (lacune OU doublon nu
= vrai défaut de registre) ; **(b)** toute mention « N invariants » du `.py` ==
|ledger| ; **(d)** toute mention « N invariants » du README == |ledger|. Mention ou
registre absent = échec (anti-évaporation #6).
**Vérif** — 3 checks verts sur l'arbre propre (ledger 1..9 = 9 marqueurs `# Invariant
N ·`, schéma compté à part). **7 morsures** adversariales, gate lancé SEUL, reverts
par `cp` ciblé (jamais `git checkout` large — cf. incident consigné) : **M1** `.py`
9→10 (b) · **M2** README 9→10 métier (d) · **M3 SILENT-GREEN** `# Invariant 10 ·`
injecté ⇒ ledger→10 pendant que la prose reste 9 (mord `.py` ET README, preuve que
l'autorité est le CODE) · **M4** `# Invariant 5 ·` supprimé ⇒ ledger non contigu (a) +
self-reports désync · **M5** doublon nu `# Invariant 3 ·` ⇒ vrai doublon (a) · **M6**
toutes les mentions « 9 invariants » retirées du README ⇒ self-report ÉVAPORÉ · **M7
no-false-positive** : muter « 25 tests »→« 26 » ⇒ le gate ledger reste SILENCIEUX
(l'ancre « invariants » l'exclut ; le rouge vient du gate test-count préexistant, pas
du mien). Arbre restauré (`git status` propre, seule l'addition +113 subsiste). Suite
unittest re-verte : **25 tests OK** (générateur inchangé). Suite CI complète re-verte :
`check_artifacts` · `check_docs` · `guard_constraints` · `check_ci_integrity` ·
`check_regression` · `check_readme_claims` tous exit 0. **La classe ledger passe à 9
générateurs (+2 dialecte `# INVn`) ; re-scanner tout NOUVEAU dialecte AVANT de
re-déclarer close — ce 3ᵉ oubli confirme l'avertissement de la mémoire.**
## Sprint 8 · buffer · Faisabilité/bancable — ÉLIMINATION du taux `0.52` codé en dur dans l'oracle anti-invention (source unique CANONICAL · #6/#5)
**Contexte** — Série anti-dérive Sprint 8 (CLAUDE.md #6 « zéro invention de