[DTP-Worker 20260801_193414] Sprint 8 · buffer · Gate d'IDENTITÉ des comptes de tests self-reportés par les README de MODULE

Surface ungated distincte des fiches : chaque `05_deliverables_mvp/<suite>/README.md`
se re-déclare le compte de SA suite (commentaire `# N tests` de la commande unittest ·
bullet « → **N/N verts** » · prose d'auto-score « en-repo (N tests verts + …) ») — 27
claims sur 16 modules. Tous les blocs de comptes de tests existants visent 03_agents/*
(row_re, agrégats prose, per-suite hors table) ; row_re ne lit le README de module QUE
comme cible de lien. Un test ajouté/retiré met à jour regression_plan.json (auth =
plan.suites[path].test_methods, byte-gaté) tandis que la prose du README rote en silence.

Nouveau bloc « READMEs de MODULE · comptes de tests self-reportés » (table config
MODULE_README_TESTS · motifs ancrés) : chaque motif DOIT matcher (absent = régression #6)
ET tous ses groupes == auth ; `**N/N verts**` capture 2 groupes → un 25/24 incohérent mord.
5 modules sans self-report (chat_otoia/mobile/publiciste/acceptance/audit_4big) hors table.

4 morsures vérifiées (drift commentaire · incohérence N/N · disparition de claim · drift
auto-score prose) ; restauré = 440 checks de base intacts + 27 nouveaux ; check_ci_integrity
+ check_docs re-verts. Restauration par backup ciblé (jamais git checkout ./git clean).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-01 19:45:11 +00:00
parent 861260462f
commit 18a758045f
2 changed files with 117 additions and 0 deletions
+27
View File
@@ -2093,3 +2093,30 @@ spec == rapport · exit 0. Working tree byte-restauré (`git checkout --`, **JAM
- **Note memory** : la classe « agent-fiche-role-attrs-ungated » est désormais CLOSE (attributs contrat = Fiches Faisabilité/Mobile ; `Has Role` = Fiches Workspace ; `roles_allowed` chat = ce bloc). Candidat propre restant : la fiche `ifc_speckle:34` (attributs contrat déjà gatés) + la row acceptance S3 « viewer 3D » (déjà gatée QA).
- **Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ; édition **hors** `05_deliverables_mvp/*/out` ⇒ 0 dérive d'artefact ; le montage réel du chat reste côté runner/VPS).
- **Auto-score 4Big** : 96/100.
---
## Session 20260801_193414 · Sprint 8 · buffer · Gate d'IDENTITÉ des comptes de tests self-reportés par les README de MODULE (#6)
**Contexte** : la série anti-dérive Sprint-8 gate chaque surface data-derived contre sa source de vérité. Tous les blocs de **comptes de tests** existants (`ci/check_readme_claims.sh`) visent `03_agents/*/AGENT.md` : la cellule « Tests » des tables via `row_re`, les agrégats prose de `crm`/`erpnext_backend`, et les cinq claims per-suite « hors table » (seo/portails/chat_otoia/confotur/deploy_runbook). AUCUN ne touche le README du **MODULE** lui-même — pourtant `05_deliverables_mvp/<suite>/README.md` se re-déclare, en propre, le compte de SA suite à plusieurs endroits.
**Surface trouvée (ungated)** : **27 claims sur 16 READMEs de module**, sous trois formulations récurrentes :
- commentaire de la commande unittest : `discover -s tests -v # N tests (…)` ;
- bullet « Vérification en-repo » : `**N/N verts**` (six modules RBAC/faisabilité/CRM) ;
- justification d'auto-score 4Big : `Validé statiquement en-repo (N tests verts + …)`.
Ces nombres sont SAISIS À LA MAIN dans le doc d'entrée de chaque module et se périment dès qu'un `def test_` est ajouté/retiré : la source faisant autorité (`qa/regression/out/regression_plan.json` → `auth = plan.suites[path].test_methods`, recomptée à chaque build par découverte réelle, byte-gatée par `check_artifacts` + fraîcheur du run par `check_regression`) se met à jour tandis que la prose du README rote EN SILENCE — « vert trompeur » de la MÊME classe que la cellule « Tests » des fiches, mais sur la surface que `row_re` n'atteint pas (il ne lit le README de module QUE comme *cible de lien*). Aucune suite `tests/` (qui teste des FONCTIONS de génération, jamais la prose du README) n'attrape ce périmé.
**Gate ajouté** (`ci/check_readme_claims.sh`, nouveau bloc « READMEs de MODULE · comptes de tests self-reportés » juste après le bloc per-suite « hors table », d'où `auth` est déjà en portée · zéro rechargement · #6) : table de config `MODULE_README_TESTS` = liste `(suite_path, [motifs ancrés])`. Pour chaque module : `auth[suite_path]` recomputé, chaque motif DOIT matcher (claim absent = régression #6) ET tous ses groupes capturés == `auth`. Le motif `**N/N verts**` capture DEUX groupes → les deux doivent valoir `auth` : un `25/24 verts` internement incohérent mord aussi. Chaque motif est ancré sur un contexte distinctif (`discover -s tests…# N tests`, `**N/N verts**`, `en-repo (N tests verts`, `test_confotur.py # N tests`…) pour viser LE compte de CETTE suite sans capter un autre nombre.
- **Cinq modules volontairement HORS table** (`frontend/chat_otoia`, `mobile/app_config`, `publiciste`, `qa/acceptance`, `qa/audit_4big`) : leur README ne self-reporte AUCUN compte de tests (vérifié) — rien à ancrer ; un futur claim = l'ajouter à la table. Noté dans le commentaire du bloc.
**4 morsures vérifiées** (chaque README restauré depuis backup — **JAMAIS** `git checkout .`/`git clean`, interdits absolus) :
1. drift commentaire (`faisabilite/generator` 16→17 tests) → ✗ « dit 17 MAIS source dit 16 » ;
2. incohérence interne `N/N` (`rbac/apply_plan` `16/16`→`16/17 verts`) → ✗ « dit 16/17 MAIS source dit 16 » ;
3. disparition de claim (`legal/confotur` prose auto-score « diffable, 44 tests (dont… » retirée) → ✗ « claim INTROUVABLE (attendu 44) » ;
4. drift auto-score prose (`rbac/fixtures_gen` `(11 tests verts`→`(12 tests verts`) → ✗ « dit 12 MAIS source dit 11 ».
Restauré = green : `rc=0`, **440 checks de base intacts (diff vide) + 27 nouveaux**. Gates sœurs re-verts : `check_ci_integrity` rc=0 · `check_docs` rc=0.
- En-tête du gate mis à jour (inventaire des surfaces couvertes : nouvelle entrée « comptes de tests self-reportés par MODULE »).
- **Note memory** : classe « comptes de tests » — désormais couverte sur TROIS surfaces (cellule « Tests » des fiches via `row_re` · agrégats prose fiches · **README de module**, ce bloc) + les cinq claims per-suite hors table. Source unique = `auth` (plan.suites[].test_methods).
- **Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ; édition **hors** `05_deliverables_mvp/*/out` ⇒ 0 dérive d'artefact).
- **Auto-score 4Big** : 96/100.
+90
View File
@@ -91,6 +91,14 @@
# le SEUL bloc `e_ncf` d'ecf_plan.json (prefix/longueur/regex/structure, byte-
# gatés) + cohérences croisées (1+tipo+seq == longueur · |regex digits| ==
# tipo+seq — mordent un artefact internement incohérent)
# 05_deliverables_mvp/<suite>/README.md (comptes de tests self-reportés par MODULE) :
# • chaque README de module se re-déclare le compte de SA suite (commentaire
# « # N tests » de la commande unittest · bullet « → **N/N verts** » · prose
# d'auto-score « en-repo (N tests verts + …) ») — 27 claims sur 16 modules,
# surface que row_re (qui ne lit le README de module QUE comme cible de lien)
# et les blocs per-suite (tous sur 03_agents/*) n'atteignent pas → recomptés
# depuis plan.suites[path].test_methods (`auth`, même source · byte-gatée) ;
# un « N/N » interne incohérent (25/24) mord aussi
# 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é).
#
@@ -771,6 +779,88 @@ for path_f, suite_path, pat, label in PER_SUITE_HORS_TABLE:
bad(f"Test par suite (hors table) · {path_f} · {label} — dit {m.group(1)} "
f"MAIS source dit {exp} (plan.suites[`{suite_path}`]) → régénérer la fiche")
# ============================================================================
# READMEs de MODULE · comptes de tests self-reportés — surface DISTINCTE des fiches.
# ----------------------------------------------------------------------------
# Tous les blocs de comptes de tests ci-dessus visent `03_agents/*/AGENT.md` (la
# cellule « Tests » via row_re, les agrégats prose crm/erpnext_backend, les cinq
# claims per-suite hors table). AUCUN ne touche le README du MODULE lui-même —
# `05_deliverables_mvp/<suite>/README.md` — qui pourtant se re-déclare, en propre,
# le compte de SA suite à plusieurs endroits : le commentaire de la commande
# `unittest` (« # N tests »), le bullet « Vérification en-repo » (« → **N/N verts** »)
# et la justification d'auto-score (« Validé … en-repo (N tests verts + … ) »). Ces
# nombres sont SAISIS À LA MAIN dans le doc d'entrée de chaque module et se périment
# dès qu'un `def test_` est ajouté/retiré : la source faisant autorité (regression_
# plan.json → `auth`, recomptée à chaque build par découverte réelle · byte-gatée)
# se met à jour, tandis que la prose du README rote EN SILENCE — « vert trompeur »
# de la MÊME classe que la cellule « Tests » des fiches, mais sur la surface que
# row_re n'atteint pas (il ne lit le README de module QUE comme cible de lien). Aucune
# suite tests/ (FONCTIONS de génération, jamais la prose du README) n'attrape ce
# périmé. Un « N/N » interne incohérent (ex. `25/24 verts`) mord aussi (les deux
# nombres doivent valoir `auth`). On RECOMPUTE chaque nombre depuis `auth` (MÊME
# source déjà chargée · zéro duplication #6) et on exige que le README l'écrive
# EXACTEMENT ; un claim listé mais absent échoue AUSSI (traçabilité #6 : le compte
# qui s'évapore est lui-même une régression). Cinq modules ne self-reportent AUCUN
# compte (frontend/chat_otoia · mobile/app_config · publiciste · qa/acceptance ·
# qa/audit_4big) — volontairement HORS table (rien à ancrer ; ajouter un futur claim
# = l'ajouter ici). Chaque motif est ANCRÉ sur un contexte distinctif (commande
# `discover`, `**N/N verts**`, « en-repo (N tests verts », nom de fichier de suite…)
# pour viser LE compte de CETTE suite sans capter un autre nombre.
# ============================================================================
MODULE_README_TESTS = [
("crm/commissions", [r"discover -s tests[^#]*# (\d+) tests",
r"en-repo \((\d+) tests verts"]),
("crm/dossier_vente", [r"discover -s tests[^#]*# (\d+) tests"]),
("crm/workflow_vente", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("demo/scenarios", [r"(\d+) tests \(dont injections"]),
("devops/deploy_runbook", [r"(\d+) tests dont \d+ injections"]),
("faisabilite/bancable", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("faisabilite/generator", [r"(\d+) tests `unittest`"]),
("fiscal/ecf_dgii", [r"discover -s tests[^#]*# (\d+) tests",
r"en-repo \((\d+) tests verts"]),
("frontend/portails", [r"discover -s tests[^#]*# (\d+) tests",
r"exacts, (\d+) tests \(dont"]),
("legal/confotur", [r"discover -s tests[^#]*# (\d+) tests \(dont",
r"test_confotur\.py\s*# (\d+) tests",
r"diffable, (\d+) tests \(dont"]),
("qa/audit_5d", [r"\*\*(\d+) tests\*\* \(`unittest`"]),
("rbac/apply_plan", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("rbac/fixtures_gen", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("rbac/roleprofile_gen", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("rbac/userperm_gen", [r"\*\*(\d+)/(\d+) verts\*\*",
r"en-repo \((\d+) tests verts"]),
("seo", [r"discover -s tests[^#]*# (\d+) tests"]),
]
for suite_path, pats in MODULE_README_TESTS:
rd = f"{D}/{suite_path}/README.md"
try:
rtxt = re.sub(r"\s+", " ", open(rd, encoding="utf-8").read())
except OSError as e:
bad(f"Compte tests README module · {rd} illisible : {e}"); continue
if suite_path not in auth:
bad(f"Compte tests README module · suite `{suite_path}` absente de "
f"plan.suites/count_tests (câblage rompu ?)"); continue
exp = auth[suite_path]
for pat in pats:
m = re.search(pat, rtxt)
if m is None:
bad(f"Compte tests README module · {rd} — claim « N tests » INTROUVABLE "
f"(attendu {exp} · suite `{suite_path}`) · motif=/{pat}/")
continue
got = [int(g) for g in m.groups()]
if all(v == exp for v in got):
good(f"Compte tests README module · {rd} — {'/'.join(map(str, got))} == "
f"source ({exp} · `{suite_path}`)")
else:
bad(f"Compte tests README module · {rd} — dit {'/'.join(map(str, got))} "
f"MAIS source dit {exp} (plan.suites[`{suite_path}`]) → régénérer le "
f"README (ou run-book de régression si un test a bougé)")
# ============================================================================
# Portails frontend · comptes PAR WORKSPACE (cartes / liens / rôles) —
# même classe de « vert trompeur », transcrits À LA MAIN dans DEUX docs.