[DTP-Worker] Sprint 8 · buffer L75 · Comptes de tests PAR SUITE périmés dans la fiche QA (col « Tests ») : audit_4big 35→34 · regression 25→26 · acceptance 31→37 — dérive silencieuse non gatée (seule la somme 564 l'était ; une compensation +1/−1 passerait) → recompute générique des cellules par-suite depuis plan.suites/count_tests dans check_readme_claims (10 lignes vérifiées) + 3 nombres corrigés
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,9 @@
|
||||
# 03_agents/erpnext_backend/AGENT.md (« source unique ») :
|
||||
# • N tests · M suites · verdict (matrice de régression du repo)
|
||||
# → qa/regression run
|
||||
# 03_agents/*/AGENT.md (tables de livrables · colonne « Tests ») :
|
||||
# • chaque cellule « Tests » par suite gatée → plan.suites[path]
|
||||
# (+ count_tests pour le self_module qa/regression, exclu de la matrice)
|
||||
# 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é).
|
||||
#
|
||||
@@ -216,6 +219,68 @@ else:
|
||||
bad(f"Fiche Backend · {BE} dit {'/'.join(mbe.groups())} MAIS regression_run dit "
|
||||
f"{'/'.join(be_exp)} ({be_src}) → régénérer la fiche")
|
||||
|
||||
# ============================================================================
|
||||
# Fiches agents · comptes de tests PAR SUITE (colonne « Tests » des tables) —
|
||||
# même classe de « vert trompeur », au grain le PLUS FIN.
|
||||
# ----------------------------------------------------------------------------
|
||||
# Chaque fiche agent (03_agents/*/AGENT.md) recense ses livrables dans une table
|
||||
# dont la dernière colonne « Tests » affiche le nombre de méthodes `def test_` de
|
||||
# la suite. Ce nombre est SAISI À LA MAIN : il se périme dès qu'un test est
|
||||
# ajouté/retiré. C'est arrivé (fiche QA : `acceptance` disait 31 alors que la
|
||||
# suite en portait 37 · `audit_4big` 35→34 · `regression` 25→26). Les gates
|
||||
# amont ne couvraient QUE la SOMME agrégée (« 564 tests ») : une compensation
|
||||
# entre deux suites (l'une +1, l'autre −1) laisserait la somme juste et les DEUX
|
||||
# lignes fausses. On RECOMPUTE ici chaque cellule depuis la source faisant
|
||||
# autorité — plan.suites[path].test_methods pour les suites gated, et
|
||||
# reglib.discovery.count_tests (même fonction que le plan · zéro duplication)
|
||||
# pour le self_module (qa/regression, exclu de la matrice par SoD mais bien
|
||||
# documenté avec son propre compte).
|
||||
# ============================================================================
|
||||
sys.path.insert(0, f"{D}/qa/regression")
|
||||
try:
|
||||
from reglib.discovery import count_tests
|
||||
except Exception as e: # import cassé = red honnête (source de vérité absente)
|
||||
bad(f"Comptes par suite · import reglib.discovery impossible : {e}")
|
||||
count_tests = None
|
||||
|
||||
plan = load("qa/regression/out/regression_plan.json")
|
||||
auth = {s["path"]: s["test_methods"] for s in plan["suites"]}
|
||||
self_mod = plan["coverage"].get("self_module_excluded")
|
||||
if count_tests is not None and self_mod:
|
||||
auth[self_mod] = count_tests(f"{D}/{self_mod}/tests")[1]
|
||||
|
||||
# Ligne de table Tests : lien vers 05_deliverables_mvp/<path>/README.md + dernier
|
||||
# champ numérique. On ne vérifie QUE les lignes pointant une suite gatée connue
|
||||
# (auth) — toute autre ligne de table est ignorée (pas notre périmètre).
|
||||
row_re = re.compile(
|
||||
r"^\|\s*\[`\w+/`\]\([^)]*?05_deliverables_mvp/([\w/]+?)/README\.md\)"
|
||||
r".*\|\s*(\d+)\s*\|\s*$")
|
||||
fiches = subprocess.run(["git", "ls-files", "03_agents/*/AGENT.md"],
|
||||
capture_output=True, text=True).stdout.split()
|
||||
seen_rows = 0
|
||||
for af in fiches:
|
||||
try:
|
||||
lines = open(af, encoding="utf-8").read().splitlines()
|
||||
except OSError as e:
|
||||
bad(f"Fiche {af} illisible : {e}"); continue
|
||||
for ln, line in enumerate(lines, 1):
|
||||
m = row_re.match(line)
|
||||
if not m:
|
||||
continue
|
||||
path = m.group(1)
|
||||
if path not in auth: # ligne pointant un non-suite → hors périmètre
|
||||
continue
|
||||
claimed, exp = int(m.group(2)), auth[path]
|
||||
seen_rows += 1
|
||||
if claimed == exp:
|
||||
good(f"Fiche {af}:{ln} · {path} — Tests {claimed} == source ({exp})")
|
||||
else:
|
||||
bad(f"Fiche {af}:{ln} · {path} — Tests {claimed} MAIS source dit {exp} "
|
||||
f"(plan.suites/count_tests) → régénérer la fiche")
|
||||
if seen_rows == 0:
|
||||
bad("Comptes par suite · AUCUNE ligne de table « Tests » trouvée dans les "
|
||||
"fiches — la disparition du recensement est elle-même une régression.")
|
||||
|
||||
sys.exit(1 if FAIL else 0)
|
||||
PY
|
||||
rc=$?
|
||||
|
||||
Reference in New Issue
Block a user