[DTP-Worker] Sprint 8 · buffer L75 · Domaine Démo : le run-sheet de pitch (demo/scenarios) affichait « 10 modules cités » dans le diagramme d'architecture de son README — un compte data-derived transcrit À LA MAIN sans AUCUN gate, alors que demo/scenarios/out/MANIFEST.json (byte-gaté par check_artifacts, counts.modules_cites_uniques = |union des modules_cites des deux scénarios, résolus par pointeur RFC 6901|, recompté à chaque build) fait autorité. Ajouter un beat qui cite un module encore non tissé (11) OU retirer la dernière citation d'un module d'un scénario (9) ferait dériver le diagramme en silence pendant que l'artefact dit autre chose — « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS, pas la prose du README) n'attrape → nouveau bloc dans check_readme_claims recomputant le nombre depuis counts.modules_cites_uniques et exigeant l'égalité avec le README. Cohérence croisée en bonus : counts.modules_cites_uniques == |modules_cites| (liste dédupliquée du manifeste, elle-même sans doublon) — mord un compteur désynchronisé de sa propre liste. Un claim absent échoue AUSSI (2 morsures vérifiées : dérive README 10→11 · claim disparu = red ; restauré = green). ci/README.md (table + détail) mis à jour · 7 gates re-verts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-07-31 12:05:22 +00:00
parent 09ab940321
commit 97a7b25e38
3 changed files with 116 additions and 1 deletions
+53
View File
@@ -1,5 +1,58 @@
# Activity Log · 2026-07-31 · Claude Code DTP
## Session `20260731_120054` · Buffer S8 · Domaine Démo : le run-sheet de pitch (`demo/scenarios`) affichait « **10 modules cités** » dans le diagramme d'architecture de son README — un compte data-derived transcrit À LA MAIN sans AUCUN gate
**Tâche** : **Sprint 8 · buffer L75** (DevOps CI/CD · QA régression). Roadmap
fonctionnellement close ; poursuite de la série anti-dérive (CLAUDE.md #6). Les
sessions précédentes ont gaté les domaines tests, portails, RBAC (3 volets), SEO, CRM
(pipeline vente), mobile, Legal (CONFOTUR), QA (audit 5D) et DevOps (run-book). Cette
session cible le **domaine Démo** — le **run-sheet de pitch**, dont un compte
data-derived cité dans le README pointait l'artefact généré sans être recomputé par
aucun gate.
### Défaut trouvé — compte ungated, transcrit dans le diagramme du README
- **`05_deliverables_mvp/demo/scenarios/README.md:23`** : diagramme d'architecture →
« `scenario_spec.json … out/ des modules livrés (`**`10 modules cités`**`)` ».
- L'artefact source est byte-gaté par `check_artifacts` :
`demo/scenarios/out/MANIFEST.json` recompte `counts.modules_cites_uniques`
(= |union des `modules_cites` des deux scénarios, résolus par pointeur RFC 6901|) à
chaque build. Le module ne saisit **aucune** valeur métier ; il résout depuis le
disque les hand-off amont que les beats citent.
- Aucun gate ne comparait la VALEUR écrite à l'artefact : ajouter un beat qui cite un
module encore non tissé (**11**) ou retirer la dernière citation d'un module d'un
scénario (**9**) ferait dériver le diagramme en silence — « vert trompeur » qu'aucune
suite `tests/` (qui teste des FONCTIONS, pas la prose du README) n'attrape.
- **État courant** : **aucun nombre périmé** — 10 recoupe MANIFEST exactement
(anti-invention #6 : rien à réécrire). Le défaut est la **surface ungated**.
**Nouveau bloc dans `ci/check_readme_claims.sh`** : recompute le nombre depuis
`counts.modules_cites_uniques` (jamais figé ici · zéro duplication du compteur du
générateur #5) et exige l'égalité avec le README. Cohérence croisée en bonus :
`counts.modules_cites_uniques == |modules_cites|` (liste dédupliquée du manifeste,
elle-même sans doublon) — mord un compteur désynchronisé de sa propre liste. Un claim
absent échoue AUSSI (traçabilité).
### Preuve (2 morsures vérifiées + restauration verte)
| Injection | Résultat |
|---|---|
| README drift `10→11` | ✗ dit 11 modules cités MAIS artefact 10 · exit 1 |
| README claim supprimé (reformulé) | ✗ claim « (N modules cités) » INTROUVABLE · exit 1 |
| restauré | ✓ 10 modules cités == artefact · exit 0 |
- **`ci/README.md`** — surface ajoutée à la table récap du pipeline + paragraphe
descriptif (classe « run-sheet de démo »).
Suite CI complète re-verte : `guard_constraints` · `validate_json` · `check_docs` ·
`check_artifacts` · `check_regression` · `check_ci_integrity` · `check_readme_claims`.
**Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo).
**Auto-score 4Big** : 96/100.
---
## Session `20260731_113048` · Buffer S8 · Domaine DevOps : le run-book de déploiement VPS (`devops/deploy_runbook`) affichait « **7 phases** » (fiche agent devops, ×2) et « **7 confirmations** préalables » (README du module) — deux nombres data-derived transcrits À LA MAIN dans DEUX docs sans AUCUN gate
**Tâche** : **Sprint 8 · buffer L75** (DevOps CI/CD · QA régression). Roadmap
+12 -1
View File
@@ -20,7 +20,7 @@ et manuellement (`workflow_dispatch`). Jobs statiques (+ une suite `unittest` pa
| `check-artifacts` | `ci/check_artifacts.sh` | Reproductibilité : chaque `out/*.json` versionné == build frais | ✅ oui |
| `check-regression` | `ci/check_regression.sh` | Fraîcheur : `qa/regression/out/regression_run.json` (`run`) == run frais + verdict PASS | ✅ oui |
| `check-ci-integrity` | `ci/check_ci_integrity.sh` | Intégrité du câblage : `gate.needs` == tous les jobs non-manuels · chaque `ci/*.sh` câblé au gate | ✅ oui |
| `check-readme-claims` | `ci/check_readme_claims.sh` | Intégrité des chiffres des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) == artefact cité (#6) | ✅ oui |
| `check-readme-claims` | `ci/check_readme_claims.sh` | Intégrité des chiffres des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) **et** du run-sheet de démo (nombre de modules cités dans le diagramme du README) == artefact cité (#6) | ✅ oui |
| `gate` | — | Agrégat vert = gate qualité 4Big franchi | ✅ oui |
Aucune dépendance réseau/marketplace hors `actions/checkout`. Tout tourne avec
@@ -247,6 +247,17 @@ confirmations du README (les tokens `snake_case`) doit être l'ensemble **exact*
`confirmations_ouvertes` — mord l'**échange** d'un nom de confirmation là où le seul
compte (reste 7) resterait aveugle.
Même classe enfin sur le **run-sheet de démo** (livrable `demo/scenarios`) : le
nombre de **modules cités**, transcrit **à la main** dans le diagramme d'architecture
du README du module (« out/ des modules livrés (**10 modules cités**) »), pointait
l'artefact généré sans qu'aucun gate ne le recompute. Il est recomputé depuis
`demo/scenarios/out/MANIFEST.json` (`counts.modules_cites_uniques` = |union des
`modules_cites` des deux scénarios|, byte-gaté par `check_artifacts`) et comparé au
README ; ajouter un beat qui cite un module non encore tissé (11), ou retirer la
dernière citation d'un module (9), ferait dériver le diagramme en silence. Cohérence
croisée en bonus : `counts.modules_cites_uniques` == |`modules_cites`| (liste
dédupliquée du manifeste) — mord un compteur désynchronisé de sa propre liste.
Un claim **absent** échoue aussi (la dérive de formulation qui ferait
disparaître un chiffre est elle-même une régression de traçabilité). stdlib pur
(bash/git/python3), zéro réseau.
+51
View File
@@ -977,6 +977,57 @@ if dr_ph is not None:
bad(f"DevOps · {DR_RD} — énumération {listed} ≠ confirmations_ouvertes "
f"{sorted(dr_open)} → régénérer le README")
# ============================================================================
# Démo · run-sheet de pitch (nombre de modules cités) — même classe de « vert
# trompeur », transcrit À LA MAIN dans le diagramme d'architecture du README du
# module, sans AUCUN gate.
# ----------------------------------------------------------------------------
# Le générateur demo_scenario_gen émet out/MANIFEST.json (byte-gaté par
# check_artifacts ⇒ faisant autorité) dont `counts.modules_cites_uniques` est
# RECOMPTÉ à chaque build = |union des `modules_cites` des deux scénarios| — les
# hand-off amont que les beats citent par pointeur RFC 6901 (le module ne saisit
# AUCUNE valeur métier ; il résout depuis le disque). Ce nombre est recopié À LA
# MAIN dans le diagramme du README du module (05_deliverables_mvp/demo/scenarios/
# README.md — « out/ des modules livrés (10 modules cités) »). Aucun gate ne le
# couvrait : ajouter un beat qui cite un module encore non tissé (11) ou retirer
# la dernière citation d'un module d'un scénario (9) ferait dériver le diagramme
# en silence pendant que le MANIFEST byte-gaté dit autre chose — dérive qu'aucune
# suite tests/ (qui teste des FONCTIONS, pas la prose du README) n'attrape. Même
# piège que les mots-clés SEO, les triplets par workspace des portails, le
# quintuplet CONFOTUR ou la synthèse audit_5d. On RECOMPUTE depuis
# counts.modules_cites_uniques (jamais figé ici · zéro duplication du compteur du
# générateur #5) et on exige l'égalité. Cohérence croisée en bonus :
# counts.modules_cites_uniques == |modules_cites| (liste dédupliquée du manifeste,
# elle-même sans doublon) — mord un compteur désynchronisé de sa propre liste. Un
# claim absent échoue AUSSI (la disparition d'un chiffre est une régression).
# ============================================================================
DEMO_RD = f"{D}/demo/scenarios/README.md"
try:
demo_man = load("demo/scenarios/out/MANIFEST.json")
demo_n = str(demo_man["counts"]["modules_cites_uniques"])
demo_list = demo_man["modules_cites"]
if len(demo_list) != len(set(demo_list)):
bad(f"Démo · incohérence artefact : modules_cites contient des doublons "
f"({len(demo_list)} entrées, {len(set(demo_list))} uniques)")
if demo_n != str(len(demo_list)):
bad(f"Démo · incohérence artefact : counts.modules_cites_uniques={demo_n} "
f"MAIS |modules_cites|={len(demo_list)}")
except (OSError, KeyError, ValueError) as e:
bad(f"Démo · artefact scenarios illisible/inattendu : {e}"); demo_n = None
if demo_n is not None:
demo_rd = read_norm(DEMO_RD)
if demo_rd is not None:
m = re.search(r"out/ des modules livrés \((\d+) modules cités\)", demo_rd)
if m is None:
bad(f"Démo · {DEMO_RD} — claim « (N modules cités) » INTROUVABLE "
f"(attendu modules_cites_uniques={demo_n})")
elif m.group(1) == demo_n:
good(f"Démo · {DEMO_RD} — {m.group(1)} modules cités == artefact "
f"(modules_cites_uniques={demo_n})")
else:
bad(f"Démo · {DEMO_RD} — dit {m.group(1)} modules cités MAIS artefact dit "
f"{demo_n} → régénérer le README")
sys.exit(1 if FAIL else 0)
PY
rc=$?