[DTP-Worker 20260805_194334] GATE NEUF classe fiche-enumeration-completeness : le tableau des gates statiques de la fiche QA se déclare « l'état courant » de git ls-files 'ci/*.sh' mais OMETTAIT le 8ᵉ gate check_mobile_workflow.sh (livré le jour même, cité NULLE PART dans la fiche · grep=0) — check_ci_integrity verrouille le CÂBLAGE CI (ci/*.sh↔gate.needs) mais ignore la fiche, check_readme_claims ne recomputait aucune énumération de gates → surface ungatée. Fix 2 volets : (1) ajout de la ligne manquante (rôle fidèle à l'en-tête du gate, placée après check_ci_integrity) ; (2) extension de check_readme_claims.sh (bloc Python avant sys.exit, réutilise subprocess/bad/good, 0 nouveau gate #5) re-dérivant l'ensemble de git ls-files 'ci/*.sh' (hors lib.sh, #6) et exigeant que chaque basename soit cité (backtické) dans la fiche ; un gate absent échoue. Teeth mutation-prouvés 2 axes : MUT1 retrait de la ligne → RED nommant check_mobile_workflow ; MUT2 ajout d'un 9ᵉ ci/*.sh factice (index seul) → RED (forward-protection : le prochain gate ne pourra être omis) puis --cached retiré, arbre byte-restauré (JAMAIS git clean). Doc ci/README §2 sous check_readme_claims. 0 prod, 0 artefact rebuild (aucun out/ ni doc scoré audit_4big), 0 chiffre saisi (#6, le « 8 » recompté de git ls-files), 0 VPS (#8). run_ci 33 PASS·0 FAIL·0 SKIP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Code DTP Worker
2026-08-05 19:51:00 +00:00
parent c14305c170
commit afa61657cb
4 changed files with 100 additions and 0 deletions
+1
View File
@@ -51,6 +51,7 @@ inversement) — la liste ci-dessous est donc *l'état courant*, pas une constan
| Gate | Rôle (une commande, déterministe, zéro chiffre fabriqué) |
|---|---|
| `check_ci_integrity.sh` | Intégrité du câblage CI : chaque `ci/*.sh` est câblé à un job **dans** `gate.needs` (aucun gate décâblé ni orphelin) — c'est le gardien des gardiens (il **s'exclut** lui-même · SoD). |
| `check_mobile_workflow.sh` | Intégrité du **second** workflow `mobile-build.yml` (EAS build iOS/Android) — **hors** `gate.needs` (il s'active quand Michel fournit `EAS_TOKEN`), donc *non* couvert par `check_ci_integrity` qui ne verrouille que `ci.yml` : bien-formé, gating d'activation `if:` job-level porté par `needs.preflight.outputs.*` (jamais le contexte `secrets.`, non exposé hors GitHub → SKIP silencieux), contrat d'outputs sans dangling (MOB-1..4). |
| `check_readme_claims.sh` | Intégrité des **chiffres** des README / fiches agent (CLAUDE.md #6) : chaque compte cité est **recalculé** depuis l'artefact `out/` ou la source (jamais une donnée inventée). |
| `check_artifacts.sh` | **Reproductibilité** : chaque `out/*.json` se régénère **byte-identique** (aucune dérive entre source et hand-off commité). |
| `check_regression.sh` | **Fraîcheur** de la matrice de régression : le run rejoué == le run commité (aucune régression silencieuse · #5). |
+55
View File
@@ -1706,3 +1706,58 @@ valeurs sont recomputées de `CLAUDE.md`, jamais retapées), **aucune commande V
citée est une surface à ancrer) : nouvelle sous-surface (bancable + commissions) close.
**Vérif.** `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP**.
---
## Session 20260805_194334 · GATE NEUF — complétude de l'énumération des gates statiques dans la fiche QA
**Contexte.** Repo vert au démarrage (33 PASS · 0 FAIL · 0 SKIP), tous modules
livrés, roadmap 8-sem sans tâche-feature ouverte. Sonde ciblée sur la classe
**fiche-completeness** (cf. [[fiche-accuracy-audit-closed]] — « completeness≠accuracy,
diff deliverables vs fiche tables »), cette fois sur une fiche qui **énumère** un
ensemble censé être exhaustif.
**Constat (drift présent-temps réel).** La fiche `03_agents/qa/AGENT.md`
(§« Deuxième étage QA · batterie de gates statiques `ci/*.sh` ») liste les gates dans
un tableau, en se **déclarant explicitement** (l.49) « la liste ci-dessous est donc
*l'état courant*, pas une constante ». Or le tableau ne comptait que **7 lignes** alors
que `git ls-files 'ci/*.sh'` (hors `lib.sh`) en rend **8** : le 8ᵉ gate
`check_mobile_workflow.sh` — livré **le jour même** (session `001109`, cf. rapport
matinal 33-jobs) — n'y figurait **NULLE PART** (`grep -c check_mobile_workflow` fiche
= **0**, les 7 autres ≥ 1). La fiche promettait la complétude sans la tenir : omission
silencieuse d'un jour entier. **Surface ungatée confirmée** : `check_ci_integrity`
verrouille le **câblage CI** (`ci/*.sh` ↔ job `gate.needs`) mais **ne lit pas la fiche** ;
`check_readme_claims` ne recomputait aucune énumération de gates → aucun gardien.
**Fix (2 volets).**
1. **Correction du fond** : ajout de la ligne manquante `check_mobile_workflow.sh` au
tableau, placée juste après `check_ci_integrity.sh` (les deux gardent l'intégrité
d'un fichier-workflow) — rôle décrit fidèlement d'après l'en-tête du gate (second
workflow `mobile-build.yml`, hors `gate.needs`, gating `if:` job-level sur
`needs.preflight.outputs.*` jamais `secrets.`, contrat d'outputs, MOB-1..4).
2. **Ancrage anti-récurrence** : extension du gate existant `ci/check_readme_claims.sh`
(bloc Python ajouté avant `sys.exit`, réutilise `subprocess`/`bad`/`good` déjà en
scope · zéro nouveau gate #5 · zéro nouveau fichier) — re-dérive l'ensemble depuis
`git ls-files 'ci/*.sh'` (hors `lib.sh`, #6) et exige que chaque basename soit cité
(backtické) dans la fiche ; un gate **absent** échoue. Rend la promesse « l'état
courant » **opposable**.
**Teeth (mutation-vérifié, arbre restauré à chaque fois).**
- **MUT1** — retrait de la ligne `check_mobile_workflow.sh` → **RED** nommant le gate
réel non cité (`n'énumère PAS ['check_mobile_workflow.sh'] … 8 gates réels`).
- **MUT2 (forward-protection)** — `git add` d'un 9ᵉ `ci/check_dummy9.sh` factice (index
seul) → **RED** (`… ['check_dummy9.sh'] … 9 gates réels`) : le **prochain** gate
livré ne pourra pas être omis en silence. Fichier `--cached` retiré + `rm` (arbre
byte-restauré, **JAMAIS** `git clean` · CLAUDE.md).
- Arbre restauré → gate exit 0, les 8 gates re-verts.
**Portée / anti-churn.** **0 fichier de production édité** (seuls la fiche QA,
`ci/check_readme_claims.sh`, `ci/README.md`), **0 artefact reconstruit** (aucun
`out/*.json` ni doc scoré par audit_4big → pas de rebuild `quality_report`, cf.
[[audit4big-rebuild-after-doc-edits]]), **0 chiffre saisi à la main** (#6 — le « 8 » est
recompté de `git ls-files`, jamais tapé), **aucune commande VPS** (#8 — 100 % local).
Documenté en `ci/README.md` §2 sous `check_readme_claims.sh` (nouveau paragraphe
« COMPLÉTUDE de l'énumération des gates statiques »), pas de nouvelle ligne au tableau §1
(cf. [[ci-readme-table-detail-in-section2]]).
**Vérif.** `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP**.
+15
View File
@@ -1634,6 +1634,21 @@ contrat » (réservation retiré) · motif du défaut ne cite plus « Cardnet »
vert (exit 0) · working tree **byte-restauré** (`git checkout --`, **JAMAIS** `git clean`) ·
**7 gates re-verts**.
**COMPLÉTUDE de l'énumération des gates statiques dans la fiche QA.** La fiche
`03_agents/qa/AGENT.md` (§« Deuxième étage QA ») énumère les gates `ci/*.sh` en se
**déclarant explicitement** « l'état courant » de `git ls-files 'ci/*.sh'` (« pas une
constante »). Or **rien** ne vérifiait que CHAQUE gate statique y figure vraiment : le 8ᵉ
gate `check_mobile_workflow.sh` (livré le 2026-08-05) a pu rester **omis un jour entier EN
SILENCE** — la fiche promettait la complétude sans la tenir. On **re-dérive** l'ensemble
depuis `git ls-files 'ci/*.sh'` (hors `lib.sh`, #6 — jamais une liste à la main) et on
exige que chaque basename apparaisse (backtické) dans la fiche ; un gate **absent** échoue.
Distinct de `check_ci_integrity` qui verrouille le **câblage CI** (chaque `ci/*.sh` ↔ un
job `gate.needs`) mais **ignore la fiche** ; cette surface ferme le miroir *documentaire* du
même ensemble. **2 morsures vérifiées** : retrait de la ligne `check_mobile_workflow.sh` de
la fiche → mismatch (gate réel non cité) · ajout d'un 9ᵉ `ci/*.sh` tracké non encore
documenté → mismatch (**forward-protection** : le prochain gate ne pourra pas être omis) ;
restauré = vert.
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.
+29
View File
@@ -9163,6 +9163,35 @@ if _rm_lines is not None:
good(f"Traçabilité roadmap · {len(_rm_seen)} citation(s) ancrée(s), "
f"4 modules attendus présents")
# ── Complétude de l'énumération des gates statiques dans la fiche QA ─────────
# La fiche 03_agents/qa/AGENT.md §« Deuxième étage QA » énumère les gates
# `ci/*.sh` en se DÉCLARANT « l'état courant » de `git ls-files 'ci/*.sh'` (pas
# une constante). Or rien ne vérifiait que CHAQUE gate statique y figure : le 8ᵉ
# gate `check_mobile_workflow.sh` a pu être omis un jour entier EN SILENCE. On
# re-dérive l'ensemble depuis git (#6 — jamais une liste à la main) et on exige
# que chaque basename apparaisse dans la fiche ; un gate absent échoue.
_QA_FICHE = "03_agents/qa/AGENT.md"
_gate_names = sorted(
f.rsplit("/", 1)[-1]
for f in subprocess.run(["git", "ls-files", "ci/*.sh"],
capture_output=True, text=True).stdout.split()
if f.rsplit("/", 1)[-1] != "lib.sh")
try:
_qa = open(_QA_FICHE, encoding="utf-8").read()
except OSError as e:
bad(f"Énumération gates statiques · {_QA_FICHE} illisible : {e}")
_qa = None
if _qa is not None:
_missing = [n for n in _gate_names if f"`{n}`" not in _qa]
if _missing:
bad(f"Énumération gates statiques · {_QA_FICHE} n'énumère PAS {_missing} "
f"— la fiche se déclare « l'état courant » de git ls-files 'ci/*.sh' "
f"({len(_gate_names)} gates réels hors lib.sh) → ajouter la/les "
f"ligne(s) manquante(s)")
else:
good(f"Énumération gates statiques · les {len(_gate_names)} gates ci/*.sh "
f"(hors lib.sh) sont tous cités dans {_QA_FICHE}")
sys.exit(1 if FAIL else 0)
PY
rc=$?