[DTP-Worker] Sprint 8 · buffer L75 · Gate intégrité chiffres README (ci/check_readme_claims.sh)
Faux-vert réel : le README (point d'entrée) affichait des chiffres PÉRIMÉS que sa propre source cité contredisait, sans qu'aucun gate ne les enforce. check_docs ne valide que les LIENS, jamais la VALEUR des nombres → dérive silencieuse : « 21/21 modules » (artefact: 22/22), « 21 suites » (22), « 14 in_repo + 1 out_of_scope » (15 in_repo). CLAUDE.md #6 non gardé. Fix : (1) corrige les 3 chiffres du README ; (2) 7e gate statique check_readme_claims.sh qui RECOMPUTE chaque chiffre depuis l'artefact cité (audit_4big/regression/acceptance + count AGENT.md) et exige l'égalité avec l'écrit — un claim absent échoue aussi. Câblé : job check-readme-claims ∈ gate.needs (30 jobs), source lib.sh, verrouillé par check_ci_integrity INV-B. Bite proofs : « 21/21 » réintroduit ⇒ exit 1 (README≠artefact) ; claim suites retiré ⇒ exit 1 (INTROUVABLE) ; restauré ⇒ exit 0. Nettoyage : commentaires CI « 21 suites/534 tests » → 22/551. 7/7 gates verts, YAML valide. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+21
-2
@@ -64,7 +64,7 @@ jobs:
|
||||
# Fraîcheur de la matrice de régression (Sprint 8 · QA « Regression tests
|
||||
# exhaustifs »). Complète check-artifacts : ce dernier ne rejoue que `build`
|
||||
# et exclut les artefacts d'EXÉCUTION ; ce gate rejoue `run` et exige que le
|
||||
# `qa/regression/out/regression_run.json` commité (21 suites · 534 tests ·
|
||||
# `qa/regression/out/regression_run.json` commité (22 suites · 551 tests ·
|
||||
# PASS, cité dans toute la doc) soit byte-identique au run frais. Rend
|
||||
# impossible la re-commission d'une matrice périmée (ex. dérive « demo 18→21 »)
|
||||
# ou rouge commitée verte. stdlib pur, zéro pip, ~5 s.
|
||||
@@ -97,6 +97,25 @@ jobs:
|
||||
- name: Contrôle intégrité du câblage CI
|
||||
run: bash ci/check_ci_integrity.sh
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Intégrité des chiffres du README (Sprint 8 buffer · CLAUDE.md #6). Le README
|
||||
# est le point d'entrée du mandat et déclare que chaque chiffre de sa section
|
||||
# « État courant » est sourcé vers un artefact commité (« n'introduit aucune
|
||||
# donnée nouvelle »). Aucun gate ne l'enforçait : check-docs ne valide que les
|
||||
# LIENS, jamais la VALEUR des nombres. Ce gate RECOMPUTE chaque chiffre depuis
|
||||
# l'artefact cité (modules/verdict 4Big, suites régression, promesses/statuts/
|
||||
# verdict acceptance, nombre d'AGENT.md) et exige l'égalité avec ce qui est
|
||||
# écrit — un README qui se contredit avec sa propre source (ex. 21→22 modules
|
||||
# non répercuté) est un « vert trompeur ». stdlib pur, zéro pip.
|
||||
# --------------------------------------------------------------------------
|
||||
check-readme-claims:
|
||||
name: Intégrité des chiffres du README (valeur == artefact cité · #6)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Contrôle des chiffres du README
|
||||
run: bash ci/check_readme_claims.sh
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Publiciste (Sprint 2) : parser faisabilité → projets_master.json + generator.
|
||||
# Tests unitaires stdlib pur (unittest) → aucune installation pip requise sur
|
||||
@@ -504,7 +523,7 @@ jobs:
|
||||
gate:
|
||||
name: Gate qualité (agrégat)
|
||||
runs-on: ubuntu-latest
|
||||
needs: [constraints-guard, validate-json, check-docs, check-artifacts, check-regression, check-ci-integrity, publiciste-tests, rbac-tests, faisabilite-gen-tests, rbac-fixtures-tests, rbac-userperm-tests, rbac-roleprofile-tests, rbac-applyplan-tests, bancable-tests, crm-workflow-vente-tests, crm-dossier-vente-tests, crm-commissions-tests, fiscal-ecf-tests, frontend-portails-tests, legal-confotur-tests, qa-audit-5d-tests, seo-tests, chat-otoia-tests, qa-audit-4big-tests, demo-scenario-tests, qa-regression-tests, devops-deploy-runbook-tests, qa-acceptance-tests, mobile-app-config-tests]
|
||||
needs: [constraints-guard, validate-json, check-docs, check-artifacts, check-regression, check-ci-integrity, check-readme-claims, publiciste-tests, rbac-tests, faisabilite-gen-tests, rbac-fixtures-tests, rbac-userperm-tests, rbac-roleprofile-tests, rbac-applyplan-tests, bancable-tests, crm-workflow-vente-tests, crm-dossier-vente-tests, crm-commissions-tests, fiscal-ecf-tests, frontend-portails-tests, legal-confotur-tests, qa-audit-5d-tests, seo-tests, chat-otoia-tests, qa-audit-4big-tests, demo-scenario-tests, qa-regression-tests, devops-deploy-runbook-tests, qa-acceptance-tests, mobile-app-config-tests]
|
||||
steps:
|
||||
- name: Résultat
|
||||
run: echo "✅ Gate qualité 4Big franchi — tous les checks verts."
|
||||
|
||||
@@ -1,5 +1,81 @@
|
||||
# Activity Log · 2026-07-31 · Claude Code DTP
|
||||
|
||||
## Session `20260731_030001` · Buffer S8 · « Vert trompeur » : le README (point d'entrée) affichait des chiffres PÉRIMÉS que sa propre source contredisait — aucun gate ne les enforçait
|
||||
|
||||
**Tâche** : **Sprint 8 · buffer L75** (DevOps CI/CD · QA). Roadmap fonctionnellement
|
||||
close (22/22 modules 100/100, 551 tests verts, 6 gates statiques). Poursuite de la
|
||||
série anti-dérive : recherche d'un **faux-vert réel** (une affirmation présentée comme
|
||||
vérifiée mais qu'aucun gate ne vérifie), même classe que les bugs `regression_run.json`
|
||||
/ `out/` RBAC / `cd ""` des sessions précédentes.
|
||||
|
||||
### Défaut trouvé — les chiffres du README dérivaient en SILENCE vs leurs artefacts cités
|
||||
|
||||
- **Mécanisme** : `README.md` est le **point d'entrée** du mandat ; sa section « État
|
||||
courant (sourcé) » déclare mot pour mot *« Chaque chiffre ci-dessous est sourcé vers
|
||||
un artefact commité (anti-invention #6) ; ce README n'introduit aucune donnée
|
||||
nouvelle. »* Cette promesse n'était gardée par **aucun** gate : `check_docs.sh` ne
|
||||
valide que les **liens** (la cible existe), **jamais la VALEUR** des nombres. Quand un
|
||||
module + son job CI ont été ajoutés au fil des sprints, les chiffres du README se sont
|
||||
**périmés en silence** tout en restant « sourcés » vers un artefact qui, lui, dit
|
||||
autre chose — un README qui se **contredit avec sa propre source** est le pire « vert
|
||||
trompeur » (CLAUDE.md #6 : « zéro invention de chiffres »), appliqué à la doc d'entrée.
|
||||
- **Preuve au sol (3 dérives réelles constatées)** :
|
||||
- README : « **21/21** modules gated à 100/100 » — `qa/audit_4big/out/quality_report.json`
|
||||
`totals` dit **22/22** (min_score 100, verdict PASS) ;
|
||||
- README : « **21** suites gated » — `qa/regression/out/regression_plan.json`
|
||||
`totals.suites` dit **22** (551 tests) ;
|
||||
- README : « 15 promesses… **14 `in_repo`** prouvées + **1 `out_of_scope`** » —
|
||||
`qa/acceptance/out/acceptance_matrix.json` a **15 `in_repo`** (M5 est désormais
|
||||
`in_repo` avec son hors-périmètre tracé per-promesse ; 0 promesse hors `in_repo`).
|
||||
Les liens étaient tous verts (`check_docs` OK) : la dérive était **invisible**.
|
||||
|
||||
### Fix (2 solutions · CLAUDE.md #4 — retenu : correction README + gate qui l'enforce)
|
||||
|
||||
- **Correction des 3 chiffres** du README (21→22 modules, 21→22 suites, « 14+1 » → « 15
|
||||
in_repo ») pour refléter les artefacts.
|
||||
- **Correctif de fond** : nouveau gate **`ci/check_readme_claims.sh`** (7ᵉ gate statique)
|
||||
qui **RECOMPUTE** chaque chiffre depuis l'artefact cité (jamais une liste à la main ·
|
||||
#6) et exige l'égalité avec ce qui est **écrit** dans le README : modules/verdict
|
||||
(audit_4big), suites (régression), promesses/statuts/verdict (acceptance), nombre
|
||||
d'`AGENT.md` (×2 : nav + titre). Un claim **absent** du README échoue AUSSI (la dérive
|
||||
de formulation qui ferait disparaître un chiffre est elle-même une régression de
|
||||
traçabilité). *(Alt. écartée : régénérer le README depuis un template — surdimensionné
|
||||
et fragile pour une section en prose ; un gate qui compare valeur↔source est la preuve
|
||||
la plus forte et la moins couplée à la mise en forme.)*
|
||||
- **Câblage CI** : job `check-readme-claims` ajouté à `ci.yml` + inséré dans
|
||||
`gate.needs` (30 jobs bloquants désormais). `check_ci_integrity` (INV-A/INV-B) valide
|
||||
le câblage : `gate.needs` == 32 jobs − 1 (gate) − 1 manuel ; `ci/check_readme_claims.sh`
|
||||
lancé par `check-readme-claims` ∈ gate, et **source `ci/lib.sh`** (pas de code mort,
|
||||
échoue en `exit 3` hors arbre git comme les 6 autres).
|
||||
|
||||
### Preuves de morsure
|
||||
|
||||
- **Bite 1** (valeur périmée) : réintroduit « 21/21 modules » ⇒ gate **exit 1**
|
||||
`✗ README dit 21/21/100 MAIS artefact dit 22/22/100 → régénérer README`.
|
||||
- **Bite 2** (claim disparu) : retire `**22 suites gated**` ⇒ gate **exit 1**
|
||||
`✗ claim INTROUVABLE dans README (attendu suites=22)`.
|
||||
- **Restauré** ⇒ **exit 0** vert. Gate inerte tant que README == artefacts.
|
||||
|
||||
**Anti-invention (#6)** : rien inventé — le gate **recompute** la vérité depuis les
|
||||
artefacts au lieu de figer un compteur ; les 3 chiffres corrigés sont tous **recoupés**
|
||||
sur `quality_report`/`regression_plan`/`acceptance_matrix`.
|
||||
|
||||
**Nettoyage cohérence (#5 · éliminer le vieux)** : 3 commentaires CI mentionnaient
|
||||
encore « 21 suites · 534 tests » (désormais 22 · 551) — corrigés dans
|
||||
`.gitea/workflows/ci.yml` et `ci/check_regression.sh`. `ci/README.md` : table §1 + détail
|
||||
§2 + commande §3 du nouveau gate ajoutés.
|
||||
|
||||
**Vérifs** : **7 gates** locaux verts (`guard_constraints`/`validate_json`/`check_docs`/
|
||||
`check_artifacts`/`check_regression`/`check_ci_integrity`/**`check_readme_claims`**) ;
|
||||
`ci.yml` **YAML valide** ; `check_ci_integrity` : `gate.needs` = **30 jobs** (32 − gate
|
||||
− e2e-baseline manuel), 7 `ci/*.sh` câblés + `lib.sh` sourcée par les 7. Artefacts `out/`
|
||||
inchangés (aucun module `05_deliverables_mvp/` touché ⇒ pas de régénération).
|
||||
|
||||
**Hors périmètre worker (VPS · #8)** : néant (stdlib pur en-repo ; enregistrement du
|
||||
runner Gitea toujours du ressort DevOps).
|
||||
|
||||
**Auto-score 4Big** : 96/100.
|
||||
|
||||
## Session `20260731_015954` · Buffer S8 · « Vert trompeur » : les 6 gates `ci/*.sh` passaient VERT hors d'un arbre git en ne contrôlant RIEN
|
||||
|
||||
**Tâche** : **Sprint 8 · buffer L75 (« Regression tests exhaustifs » · DevOps
|
||||
|
||||
@@ -38,13 +38,13 @@ Transverses : [`devops`](03_agents/devops/AGENT.md) · [`qa`](03_agents/qa/AGENT
|
||||
|
||||
## État courant (sourcé)
|
||||
|
||||
- **Qualité 4Big** : **21/21 modules gated à 100/100** (seuil 95 · `CLAUDE.md` #5), verdict `PASS`
|
||||
- **Qualité 4Big** : **22/22 modules gated à 100/100** (seuil 95 · `CLAUDE.md` #5), verdict `PASS`
|
||||
— source [`qa/audit_4big/out/quality_report.json`](05_deliverables_mvp/qa/audit_4big/out/quality_report.json).
|
||||
- **Régression** : **21 suites gated** couvertes bijectivement vs CI ; le compte de tests
|
||||
- **Régression** : **22 suites gated** couvertes bijectivement vs CI ; le compte de tests
|
||||
agrégé faisant autorité est produit par `qa/regression run` (non commité par design)
|
||||
— plan [`qa/regression/out/regression_plan.json`](05_deliverables_mvp/qa/regression/out/regression_plan.json).
|
||||
- **Recette roadmap** : **15 promesses** (8 livrables sprint + 7 métriques MVP), **14 `in_repo`
|
||||
prouvées + 1 `out_of_scope`** (M5 « app publiée 2 stores », hors périmètre worker · #8),
|
||||
- **Recette roadmap** : **15 promesses** (8 livrables sprint + 7 métriques MVP), **15 `in_repo`
|
||||
prouvées** (chacune traçant ses items hors-périmètre worker · #8 · ex. M5 « app publiée 2 stores »),
|
||||
verdict `true` — source [`qa/acceptance/out/acceptance_matrix.json`](05_deliverables_mvp/qa/acceptance/out/acceptance_matrix.json).
|
||||
- **Guards** : [`ci/guard_constraints.sh`](ci/README.md) + [`ci/check_docs.sh`](ci/README.md) verts.
|
||||
|
||||
|
||||
@@ -20,6 +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 du README : chaque nombre de « État courant » == 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
|
||||
@@ -105,6 +106,28 @@ Ferme le trou laissé par les couvertures existantes (`audit_4big/registry`,
|
||||
working-directory n'étaient gardés par personne. Même classe d'anti-dérive que INV4
|
||||
(disque→CI), appliquée au **câblage** CI. stdlib pur (bash/awk/git), zéro réseau.
|
||||
|
||||
### `check_readme_claims.sh`
|
||||
Le `README.md` est le **point d'entrée** du mandat ; sa section « État courant
|
||||
(sourcé) » affiche des chiffres et déclare *« Chaque chiffre ci-dessous est sourcé
|
||||
vers un artefact commité (anti-invention #6) ; ce README n'introduit aucune donnée
|
||||
nouvelle. »* Cette promesse n'était gardée par **aucun** gate : `check_docs.sh` ne
|
||||
valide que les **liens** (la cible existe), jamais la **valeur** des nombres. Quand un
|
||||
module + son job CI sont ajoutés (21→22 modules, 21→22 suites) ou qu'une promesse
|
||||
change de statut (14 `in_repo` + 1 `out_of_scope` → 15 `in_repo`), les chiffres du
|
||||
README se **périment en silence** tout en restant « sourcés » vers un artefact qui dit
|
||||
autre chose — un README qui se **contredit avec sa propre source** est un « vert
|
||||
trompeur » (même classe que la matrice périmée « demo 18→21 » ou INV4, appliqué à la
|
||||
doc d'entrée). Ce gate **recompute** chaque chiffre depuis l'artefact cité (jamais une
|
||||
liste à la main · #6) et exige l'égalité avec ce qui est **écrit** :
|
||||
- modules gated `N/M` à `K/100` + verdict `PASS` → `qa/audit_4big/out/quality_report.json` (`totals`) ;
|
||||
- `N` suites gated → `qa/regression/out/regression_plan.json` (`totals.suites`) ;
|
||||
- `N` promesses (`X` sprint + `Y` métriques), `Z` `in_repo`, verdict `true` → `qa/acceptance/out/acceptance_matrix.json` ;
|
||||
- « 13 agents » (×2 : nav + titre) → `git ls-files 03_agents/*/AGENT.md`.
|
||||
|
||||
Un claim **absent** du README é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.
|
||||
|
||||
### `lib.sh` — helper partagé (sourcé, jamais exécuté seul)
|
||||
Les 6 gates commençaient tous par `cd "$(git rev-parse --show-toplevel)"`. **Hors**
|
||||
d'un arbre de travail git (tarball, `git archive | tar -x`, `git` absent du PATH),
|
||||
@@ -126,6 +149,7 @@ bash ci/check_docs.sh # liens + score
|
||||
bash ci/check_artifacts.sh # reproductibilité out/ (build)
|
||||
bash ci/check_regression.sh # fraîcheur matrice régression (run)
|
||||
bash ci/check_ci_integrity.sh # intégrité du câblage CI (gate ⊇ tous jobs)
|
||||
bash ci/check_readme_claims.sh # chiffres du README == artefacts cités (#6)
|
||||
```
|
||||
|
||||
Chaque script retourne `0` si conforme, `1` sinon. Reproduit exactement ce que
|
||||
|
||||
Executable
+148
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# check_readme_claims.sh · OTO Enterprise OS DTP
|
||||
# ----------------------------------------------------------------------------
|
||||
# Gate d'INTÉGRITÉ des chiffres du README (Sprint 8 buffer · CLAUDE.md #6 —
|
||||
# « Zéro invention de chiffres · toujours vérifier sources archives »).
|
||||
#
|
||||
# Le README.md est le POINT D'ENTRÉE du mandat. Sa section « État courant
|
||||
# (sourcé) » affiche des chiffres et déclare, mot pour mot :
|
||||
# « Chaque chiffre ci-dessous est sourcé vers un artefact commité
|
||||
# (anti-invention #6) ; ce README n'introduit aucune donnée nouvelle. »
|
||||
# Cette promesse n'était garantie par AUCUN gate. `check_docs.sh` ne valide que
|
||||
# les liens (cible existe) — pas la VALEUR des nombres. Résultat : quand un
|
||||
# module + son job CI sont ajoutés (21→22 modules, 21→22 suites) ou qu'une
|
||||
# promesse change de statut (14 in_repo + 1 out_of_scope → 15 in_repo), les
|
||||
# chiffres du README se PÉRIMENT en silence tout en restant « sourcés » vers un
|
||||
# artefact qui, lui, dit autre chose. Un README qui se contredit avec sa propre
|
||||
# source est un « vert trompeur » de la même classe que la matrice périmée
|
||||
# (« demo 18→21 ») ou l'orphan_tests_dirs (INV4) — appliqué à la doc d'entrée.
|
||||
#
|
||||
# Ce gate RECOMPUTE chaque chiffre depuis l'artefact cité (jamais une liste à la
|
||||
# main · #6) et exige l'égalité avec ce qui est ÉCRIT dans le README :
|
||||
# • Qualité 4Big N/M modules gated à K/100, verdict → qa/audit_4big totals
|
||||
# • Régression N suites gated → qa/regression plan
|
||||
# • Recette N promesses (X sprint + Y métriques), Z in_repo, verdict
|
||||
# → qa/acceptance matrix
|
||||
# • Agents « 13 agents » (×2 : nav + titre) → 03_agents/*/AGENT.md
|
||||
# Un claim absent du README échoue AUSSI (la dérive de formulation qui
|
||||
# ferait disparaître un chiffre est elle-même une régression de traçabilité).
|
||||
#
|
||||
# Dépendances : bash, git, python3 (stdlib pur · CLAUDE.md #2 — runner sans pip).
|
||||
# ============================================================================
|
||||
set -uo pipefail
|
||||
# shellcheck source=ci/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh" || exit 3
|
||||
cd_repo_root # racine du dépôt, ou ROUGE honnête si hors arbre git (cf. lib.sh)
|
||||
|
||||
echo "== Intégrité des chiffres du README (valeur == artefact cité · #6) =="
|
||||
|
||||
python3 - <<'PY'
|
||||
import json, re, subprocess, sys
|
||||
|
||||
D = "05_deliverables_mvp"
|
||||
FAIL = 0
|
||||
def bad(m):
|
||||
global FAIL; FAIL = 1; print(f" \033[31m✗\033[0m {m}")
|
||||
def good(m):
|
||||
print(f" \033[32m✓\033[0m {m}")
|
||||
|
||||
try:
|
||||
readme = open("README.md", encoding="utf-8").read()
|
||||
except OSError as e:
|
||||
print(f" \033[31m✗\033[0m README.md illisible : {e}"); sys.exit(1)
|
||||
# Texte normalisé (espaces/newlines compressés) pour les claims multi-lignes.
|
||||
norm = re.sub(r"\s+", " ", readme)
|
||||
|
||||
def load(p):
|
||||
with open(f"{D}/{p}", encoding="utf-8") as f:
|
||||
return json.load(f)
|
||||
|
||||
# --- Vérités-terrain recalculées depuis les artefacts (jamais saisies) -------
|
||||
q = load("qa/audit_4big/out/quality_report.json")["totals"]
|
||||
qv = load("qa/audit_4big/out/quality_report.json")["verdict"]
|
||||
reg = load("qa/regression/out/regression_plan.json")["totals"]
|
||||
acc = load("qa/acceptance/out/acceptance_matrix.json")
|
||||
rows = acc["matrix"]
|
||||
n_sprint = sum(1 for r in rows if r["kind"] == "sprint_deliverable")
|
||||
n_metric = sum(1 for r in rows if r["kind"] == "mvp_metric")
|
||||
n_inrepo = sum(1 for r in rows if r["status"] == "in_repo")
|
||||
acc_verdict = acc["verdict"]
|
||||
agents = subprocess.run(["git", "ls-files", "03_agents/*/AGENT.md"],
|
||||
capture_output=True, text=True).stdout.split()
|
||||
n_agents = len(agents)
|
||||
|
||||
# --- Chaque claim : (libellé, regex sur `norm`, groupes attendus) ------------
|
||||
# Le n-uplet capturé (str) est comparé à l'attendu (str). Un claim non trouvé
|
||||
# échoue (regex is None) — la disparition d'un chiffre est une régression.
|
||||
checks = [
|
||||
("Qualité 4Big · modules gated",
|
||||
r"\*\*(\d+)/(\d+) modules gated à (\d+)/100\*\*",
|
||||
(str(q["pass"]), str(q["modules"]), str(q["min_score"])),
|
||||
f"pass={q['pass']} total={q['modules']} min_score={q['min_score']}"),
|
||||
|
||||
("Régression · suites gated",
|
||||
r"\*\*(\d+) suites gated\*\*",
|
||||
(str(reg["suites"]),),
|
||||
f"suites={reg['suites']}"),
|
||||
|
||||
("Recette · promesses (sprint + métriques)",
|
||||
r"\*\*(\d+) promesses\*\* \((\d+) livrables sprint \+ (\d+) métriques",
|
||||
(str(len(rows)), str(n_sprint), str(n_metric)),
|
||||
f"total={len(rows)} sprint={n_sprint} metric={n_metric}"),
|
||||
|
||||
("Recette · promesses in_repo",
|
||||
r"\*\*(\d+) `in_repo`",
|
||||
(str(n_inrepo),),
|
||||
f"in_repo={n_inrepo}"),
|
||||
|
||||
("Agents · fiche nav",
|
||||
r"Fiches des \*\*(\d+) agents\*\*",
|
||||
(str(n_agents),),
|
||||
f"AGENT.md={n_agents}"),
|
||||
|
||||
("Agents · titre section",
|
||||
r"## Les (\d+) agents",
|
||||
(str(n_agents),),
|
||||
f"AGENT.md={n_agents}"),
|
||||
]
|
||||
|
||||
for label, pat, expected, src in checks:
|
||||
m = re.search(pat, norm)
|
||||
if m is None:
|
||||
bad(f"{label} — claim INTROUVABLE dans README (attendu {src}) · motif=/{pat}/")
|
||||
continue
|
||||
got = m.groups()
|
||||
if got == expected:
|
||||
good(f"{label} — README {'/'.join(got)} == artefact ({src})")
|
||||
else:
|
||||
bad(f"{label} — README dit {'/'.join(got)} MAIS artefact dit {'/'.join(expected)} ({src}) → régénérer README")
|
||||
|
||||
# --- Verdicts textuels cités dans le README (PASS / true) --------------------
|
||||
if re.search(r"verdict `PASS`", norm):
|
||||
if qv == "PASS":
|
||||
good(f"Qualité 4Big · verdict README `PASS` == artefact ({qv})")
|
||||
else:
|
||||
bad(f"Qualité 4Big · README dit verdict `PASS` MAIS artefact dit {qv}")
|
||||
else:
|
||||
bad("Qualité 4Big · verdict `PASS` non cité dans README (attendu)")
|
||||
|
||||
if re.search(r"verdict `true`", norm):
|
||||
if acc_verdict is True:
|
||||
good("Recette · verdict README `true` == artefact (True)")
|
||||
else:
|
||||
bad(f"Recette · README dit verdict `true` MAIS artefact dit {acc_verdict}")
|
||||
else:
|
||||
bad("Recette · verdict `true` non cité dans README (attendu)")
|
||||
|
||||
sys.exit(1 if FAIL else 0)
|
||||
PY
|
||||
rc=$?
|
||||
|
||||
echo
|
||||
if [[ "$rc" -eq 0 ]]; then
|
||||
echo -e "\033[32m✅ Chiffres du README fidèles aux artefacts cités (aucune donnée inventée · #6).\033[0m"
|
||||
else
|
||||
echo -e "\033[31m❌ Chiffre(s) du README périmé(s) vs artefacts — corriger README avant merge.\033[0m"
|
||||
fi
|
||||
exit "$rc"
|
||||
@@ -5,7 +5,7 @@
|
||||
# Gate de FRAÎCHEUR de la matrice de régression (roadmap Sprint 8 · QA
|
||||
# « Regression tests exhaustifs » · CLAUDE.md #5 — zéro régression silencieuse).
|
||||
# Prouve, en une commande, que l'artefact d'EXÉCUTION commité
|
||||
# `qa/regression/out/regression_run.json` (totaux « 21 suites · 534 tests ·
|
||||
# `qa/regression/out/regression_run.json` (totaux « 22 suites · 551 tests ·
|
||||
# verdict PASS » cité partout dans la doc et les logs) reflète TOUJOURS la
|
||||
# réalité du disque — en le régénérant et en exigeant l'identité byte-for-byte.
|
||||
#
|
||||
@@ -15,7 +15,7 @@
|
||||
# EST un artefact de `run` : il porte les compteurs réellement exécutés
|
||||
# (ran/passed/failures) que `build` ne connaît pas. Résultat : sans ce gate, la
|
||||
# matrice agrégée pouvait se périmer en silence (ex. un module + son job CI
|
||||
# ajoutés sans régénérer la matrice → « 21 suites » devenu faux) sans qu'aucune
|
||||
# ajoutés sans régénérer la matrice → « 22 suites » devenu faux) sans qu'aucune
|
||||
# suite `tests/` — qui teste des FONCTIONS, pas le fichier commité — ne l'attrape.
|
||||
# C'est exactement la dérive « demo 18→21 » déjà corrigée à la main : ce gate la
|
||||
# rend impossible à re-commettre.
|
||||
|
||||
Reference in New Issue
Block a user