[DTP-Worker 20260802_090530] Sprint 8 · buffer · Angle mort gate « comptes tests par suite » : la cellule rbac (fiche pointe une SPEC, pas un README) était non vérifiée
row_re du gate check_readme_claims §comptes-par-suite exigeait un lien …/README.md ; la fiche erpnext_backend pointe rbac/ via RBAC_50_ROLES_SPEC.md (son point d'entrée contrat), donc sa cellule « Tests | 10 | » échappait au recompute depuis regression_plan.json. Mutation-test 10→99 : gate restait VERT (vrai angle mort, classe « vert trompeur »). Extension : accepte tout *.md d'entrée du dossier module (/[\w.-]+.md) ; le garde path-not-in-auth protège l'élargissement. rbac désormais vue+mordue ; 7 gates verts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -941,3 +941,41 @@ marqueur (`proscrites`/`interdits`/`bannie`) donc `guard_constraints` les laisse
|
||||
passer. **Vérif** : 7 gates re-verts (guard_constraints · check_docs ·
|
||||
check_readme_claims · check_ci_integrity · check_artifacts · check_regression ·
|
||||
validate_json tous exit 0).
|
||||
|
||||
---
|
||||
|
||||
## Sprint 8 · buffer · Angle mort du gate « comptes de tests par suite » : la cellule `rbac` (fiche pointant une SPEC, pas un README)
|
||||
|
||||
**Démarche — vérifier AVANT de conclure « couvert » (mémoire `verify-uncovered-before-gating`).**
|
||||
La série récente ayant épuisé les surfaces driftables évidentes, j'ai audité la
|
||||
**complétude d'un gate existant** plutôt que d'en empiler un neuf (CLAUDE.md #5).
|
||||
|
||||
**Constat.** Le gate `check_readme_claims.sh` §« Fiches agents · comptes de tests
|
||||
PAR SUITE (colonne « Tests ») » recompute chaque cellule `| N |` des tables de
|
||||
livrables des `03_agents/*/AGENT.md` depuis l'autorité `regression_plan.json`
|
||||
(`plan.suites[path].test_methods`). Son `row_re` exigeait pourtant que le lien de
|
||||
la ligne pointe `…/README.md`. **Or une ligne y échappe** : la fiche
|
||||
`erpnext_backend` (l.28) pointe le module `rbac/` via son **point d'entrée
|
||||
`RBAC_50_ROLES_SPEC.md`** (le contrat 50-rôles, pas un README) — donc son
|
||||
`row_re` ne mordait pas, et sa cellule « Tests | 10 | » restait **non vérifiée**.
|
||||
|
||||
**Mutation-test (preuve du trou).** Cellule `rbac` `10 → 99` sur la fiche →
|
||||
`check_readme_claims` restait **VERT** (exit 0), aucune ligne `rbac` évaluée. C'est
|
||||
exactement la classe « vert trompeur » que cette section du gate existe pour tuer
|
||||
(un régénérateur de fiche pourrait y écrire un faux compte sans que la CI bronche).
|
||||
La somme prose « RBAC 60 tests (10+11+12+11+16) » est **order-indépendante** → ne
|
||||
contraint pas la cellule-table `rbac` individuelle. Vrai angle mort.
|
||||
|
||||
**Correctif (extension du gate, pas gate N+1).** `row_re` accepte désormais tout
|
||||
`*.md` d'entrée du dossier module (`/[\w.-]+\.md` au lieu de `/README\.md`), pas
|
||||
seulement README — le garde `path not in auth` (déjà présent) protège de tout
|
||||
élargissement fortuit : seules les lignes pointant une **suite gatée connue** sont
|
||||
évaluées, les autres restent ignorées. Une seule ligne entre ainsi dans le
|
||||
périmètre : `rbac`. Commentaire mis à jour pour documenter le cas SPEC.
|
||||
|
||||
**Vérif.** (1) Arbre propre VERT + la ligne `rbac` est désormais **VUE**
|
||||
(`AGENT.md:28 · rbac — Tests 10 == source (10)`). (2) Mutation `10→99` désormais
|
||||
**MORDUE** (`Tests 99 MAIS source dit 10 → régénérer la fiche`, exit 1). (3)
|
||||
Restauration → exit 0. **7 gates re-verts** : check_ci_integrity · check_artifacts ·
|
||||
check_docs · check_readme_claims · check_regression · guard_constraints ·
|
||||
validate_json tous exit 0.
|
||||
|
||||
@@ -631,11 +631,15 @@ 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).
|
||||
# Ligne de table Tests : lien vers 05_deliverables_mvp/<path>/<doc>.md + dernier
|
||||
# champ numérique. Le <doc>.md est l'ENTRÉE du module — le plus souvent README.md,
|
||||
# mais parfois une SPEC (la fiche `rbac` pointe RBAC_50_ROLES_SPEC.md, son point
|
||||
# d'entrée) : on accepte donc tout `*.md` du dossier module, sinon cette cellule-là
|
||||
# reste un angle mort (mutation 10→99 non mordue). On ne vérifie QUE les lignes
|
||||
# pointant une suite gatée connue (auth) — toute autre ligne est ignorée (hors
|
||||
# périmètre), le garde `path not in auth` protège de tout élargissement fortuit.
|
||||
row_re = re.compile(
|
||||
r"^\|\s*\[`\w+/`\]\([^)]*?05_deliverables_mvp/([\w/]+?)/README\.md\)"
|
||||
r"^\|\s*\[`\w+/`\]\([^)]*?05_deliverables_mvp/([\w/]+?)/[\w.-]+\.md\)"
|
||||
r".*\|\s*(\d+)\s*\|\s*$")
|
||||
fiches = subprocess.run(["git", "ls-files", "03_agents/*/AGENT.md"],
|
||||
capture_output=True, text=True).stdout.split()
|
||||
|
||||
Reference in New Issue
Block a user