From cb3de786f860b671ae88abd546e57429f1ee40dd Mon Sep 17 00:00:00 2001 From: Claude Code DTP Worker Date: Wed, 5 Aug 2026 21:23:25 +0000 Subject: [PATCH] =?UTF-8?q?[DTP-Worker=2020260805=5F211340]=20GATE=20?= =?UTF-8?q?=E2=80=94=20compl=C3=A9tude=20de=20l'=C3=A9num=C3=A9ration=20de?= =?UTF-8?q?s=20gates=20dans=20la=20TABLE=20=C2=A71=20de=20ci/README.md=20(?= =?UTF-8?q?jumeau=20ungat=C3=A9=20de=20la=20fiche=20QA)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La table §1 « Ce que fait le pipeline » de ci/README.md est LA doc canonique des jobs statiques (une ligne par gate ci/*.sh). Sa complétude était le jumeau exact de la fiche QA fermée par afa6165, mais NON gaté : check_ci_integrity verrouille le câblage (ci/*.sh ↔ gate.needs), le bloc fiche-QA ne lit que 03_agents/qa/AGENT.md — rien n'exigeait que chaque gate figure dans la table §1. Un 9ᵉ gate y serait omis EN SILENCE. Prouvé ungate par mutation (retrait de la ligne de table check_mobile_workflow → run_ci --static 8 PASS, aucun gate ne mord). Fix = extension du gate existant (PAS un nouveau job · #5) : bloc Python dans check_readme_claims.sh (avant sys.exit) réutilisant _gate_names re-dérivé de git ls-files 'ci/*.sh' (hors lib.sh · #6). Exige chaque basename cité dans une LIGNE DE TABLE (|…) de la section §1 — délibérément PAS la prose §1 (qui ne cite que certains gates pour l'explication mobile-build.yml : un contrôle whole-section serait édenté sur un retrait de ligne de table). 0 nouveau ci/*.sh, 33 jobs inchangés. Teeth 2 axes : MUT1 suppression de la vraie ligne de table (l.24) → RED nommant check_mobile_workflow.sh ; MUT2 9ᵉ ci/*.sh factice tracké → RED sur les DEUX surfaces (fiche QA + table §1 : forward-protection) puis git rm --cached + rm, arbre byte-restauré (JAMAIS git clean). Piège inerte écarté : sed 15d visait l'en-tête de table (grep -n renumérotait relatif au pipe), re-ciblé sur la ligne 24 réelle. Doc sous-section « COMPLÉTUDE de l'énumération dans la TABLE §1 » ajoutée en §2 de ci/README (discipline ci-readme-table-detail-in-section2). Sweep préalable repo-wide 7-gates/32-jobs : 0 dérive réelle (toutes occurrences historiques datées ou pédagogiques, classées KEEP). 0 édition de production, 0 artefact rebuild, 0 chiffre saisi (#6 — 8/9 recomputés), 0 VPS (#8). run_ci 33 PASS · 0 FAIL · 0 SKIP. Co-Authored-By: Claude Opus 4.8 (1M context) --- 05_activity_log/2026-08-05.md | 50 +++++++++++++++++++++++++++++++++++ ci/README.md | 13 +++++++++ ci/check_readme_claims.sh | 40 ++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/05_activity_log/2026-08-05.md b/05_activity_log/2026-08-05.md index 2200f78..afb4fbd 100644 --- a/05_activity_log/2026-08-05.md +++ b/05_activity_log/2026-08-05.md @@ -1857,3 +1857,53 @@ ajouté** (#5 — la journée était déjà entièrement gatée), **0 chiffre sa (#8). Seules éditions : le rapport de currency + ce journal. **Vérif.** `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP** · `git status` propre après commit. + +--- + +## Session 20260805_211340 · GATE — complétude de l'énumération des gates dans la **table §1 de `ci/README.md`** (jumeau ungaté de la fiche QA, fermé `afa6165`) + +**Contexte + choix de tâche.** Arbre propre au démarrage, `./run_ci.sh` → **33 PASS · 0 +FAIL · 0 SKIP** ; roadmap `ROADMAP_8_WEEKS_OR_LESS.md` intégralement livrée/gatée in-repo. +Hypothèse dirigée par la mémoire *prose-facts-vs-numeric-drift* (5ᵉ sous-classe) : le 8ᵉ +gate statique `check_mobile_workflow.sh` livré ce jour a pu laisser des **siblings périmés** +dans les gate-docs ungatés. Sweep repo-wide `\b7 (gates?|statiques?)\b` / `\b32 (jobs?|PASS)\b` : +**0 dérive réelle** — toutes les occurrences « 7 »/« 32 » sont des **snapshots datés +historiques** (daily_reports/activity_log 08-02→08-05) ou **pédagogiques** (le commentaire +`check_mobile_workflow.sh:13` « 7/7 gates statiques restaient verts » désigne les 7 gates +**pré-existants** qui motivaient un 8ᵉ), classe correctement `historical-repro`/`pedagogical` += KEEP. Docs present-tense (ci/README §1, `8ᵉ gate statique`) toutes cohérentes à 8/33. + +**Le finding réel — une surface UNGATÉE.** La **table §1 de `ci/README.md`** (« Ce que fait +le pipeline ») est LA doc canonique des jobs statiques : une ligne par gate `ci/*.sh`. Or sa +**complétude** était le jumeau exact de la fiche QA fermée par `afa6165` — mais **non gaté** : +`check_ci_integrity` verrouille le CÂBLAGE (`ci/*.sh` ↔ `gate.needs`), le bloc fiche-QA (ajouté +`afa6165`) ne lit que `03_agents/qa/AGENT.md`. **Rien** n'exigeait que chaque gate figure dans +la table §1 → un 9ᵉ gate y serait omis EN SILENCE (même mode de défaillance que la fiche QA +avait subi un jour entier). Prouvé ungate **par mutation** (verify-uncovered) : retrait de la +**ligne de table** `check_mobile_workflow` → `run_ci --static` **8 PASS** (aucun gate ne mord). + +**Fix — extension du gate existant (PAS un nouveau job · #5).** Bloc Python ajouté à +`ci/check_readme_claims.sh` (avant `sys.exit`), **réutilisant** `_gate_names` déjà re-dérivé de +`git ls-files 'ci/*.sh'` (hors `lib.sh` · #6 — jamais une liste à la main). Il exige que chaque +basename soit cité dans une **ligne de TABLE** (`|`…) de la **section §1** — délibérément PAS la +prose §1 (qui ne mentionne que certains gates pour l'explication `mobile-build.yml` : un contrôle +whole-section serait **édenté** sur un retrait de ligne de table, comme la mutation l'a révélé — +d'où le scope table-rows). 0 nouveau gate `ci/*.sh`, 33 jobs inchangés. + +**Teeth mutation-prouvés (2 axes).** MUT1 — suppression de la vraie ligne de table +`check_mobile_workflow` (l.24) → **RED** nommant `check_mobile_workflow.sh` (exit 1). MUT2 — +9ᵉ `ci/*.sh` factice tracké (index seul) → **RED** sur **les DEUX** surfaces (fiche QA + table §1 : +forward-protection, le prochain gate ne pourra être omis d'aucune) ; `git rm --cached` + `rm`, +**arbre byte-restauré** (JAMAIS `git clean`). *Piège écarté* : un premier essai `sed 15d` visait +la ligne 15 = **en-tête** de table (le `grep -n` renumérotait relatif au pipe) — mutation inerte, +détectée et re-ciblée sur la vraie ligne 24. + +**Doc.** Sous-section « COMPLÉTUDE de l'énumération dans la TABLE §1 » ajoutée en **§2** de +`ci/README.md` (discipline *ci-readme-table-detail-in-section2* : ne pas grossir la cellule §1). + +**Périmètre.** **0 édition de production** (générateur/out/), **0 artefact rebuild** (aucune doc +scorée `audit_4big`), **0 chiffre saisi à la main** (#6 — `8`/`9` recomputés de `git ls-files`), +**aucune commande VPS** (#8). Seules éditions : `ci/check_readme_claims.sh` (+40 l) et +`ci/README.md` (+13 l). + +**Vérif.** `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP** · `git status` propre après commit. diff --git a/ci/README.md b/ci/README.md index 65c862a..2eccc71 100644 --- a/ci/README.md +++ b/ci/README.md @@ -1649,6 +1649,19 @@ la fiche → mismatch (gate réel non cité) · ajout d'un 9ᵉ `ci/*.sh` track documenté → mismatch (**forward-protection** : le prochain gate ne pourra pas être omis) ; restauré = vert. +**COMPLÉTUDE de l'énumération dans la TABLE §1 de ce README.** La table §1 « Ce que +fait le pipeline » (ci-dessus) est LA doc canonique des jobs statiques — une ligne par +gate `ci/*.sh`. Sa complétude était le **jumeau ungaté** de la fiche QA : `check_ci_integrity` +verrouille le câblage CI, le bloc précédent énumère côté fiche, mais **rien** n'exigeait que +chaque gate figure dans la table §1. Un 9ᵉ gate y serait omis EN SILENCE (prouvé ungate : +retrait de la ligne de table de `check_mobile_workflow` → 8 gates statiques verts). On +réutilise l'ensemble re-dérivé de `git ls-files 'ci/*.sh'` (hors `lib.sh`, #6) et on exige +que chaque basename soit cité dans une **ligne de TABLE** (`|`…) de la section §1 — **pas** la +prose §1 (qui ne cite que certains gates pour l'explication `mobile-build.yml`, ce qui +rendrait un contrôle whole-section édenté sur un retrait de ligne de table). **2 morsures +vérifiées** : retrait de la ligne de table `check_mobile_workflow.sh` → mismatch nommant le +gate · ajout d'un 9ᵉ `ci/*.sh` tracké → mismatch (**forward-protection**) ; 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. diff --git a/ci/check_readme_claims.sh b/ci/check_readme_claims.sh index f9fe0bc..40fc93b 100755 --- a/ci/check_readme_claims.sh +++ b/ci/check_readme_claims.sh @@ -9192,6 +9192,46 @@ if _qa is not None: good(f"Énumération gates statiques · les {len(_gate_names)} gates ci/*.sh " f"(hors lib.sh) sont tous cités dans {_QA_FICHE}") +# ── Complétude de l'énumération des gates dans la TABLE §1 de ci/README ────── +# ci/README.md §1 « Ce que fait le pipeline » porte LA table canonique des jobs +# statiques (une ligne par gate `ci/*.sh`). C'est la doc de référence du pipeline, +# mais sa complétude était ungatée : `check_ci_integrity` verrouille le CÂBLAGE +# CI (ci/*.sh ↔ gate.needs), le bloc ci-dessus énumère côté fiche QA, mais RIEN +# n'exigeait que chaque gate figure dans la table §1. Un 9ᵉ gate y serait omis EN +# SILENCE (prouvé ungate par mutation : retrait de la ligne §1 de +# `check_mobile_workflow` → 8 gates statiques verts). On réutilise `_gate_names` +# (re-dérivé de git · #6) et on exige que chaque basename soit cité dans une LIGNE +# DE TABLE (`|`…) de la section §1 — PAS la prose §1, qui ne cite que certains +# gates pour d'autres raisons (explication `mobile-build.yml`). Un gate absent de +# la table échoue. +_CI_README = "ci/README.md" +try: + _cir_lines = open(_CI_README, encoding="utf-8").read().splitlines() +except OSError as e: + bad(f"Énumération gates statiques · {_CI_README} illisible : {e}") + _cir_lines = None +if _cir_lines is not None: + _in_s1 = False + _s1_rows = [] + for _ln in _cir_lines: + if _ln.startswith("## 1."): + _in_s1 = True + continue + if _in_s1 and _ln.startswith("## "): + break + if _in_s1 and _ln.lstrip().startswith("|"): + _s1_rows.append(_ln) + _s1_tbl = "\n".join(_s1_rows) + _miss_s1 = [n for n in _gate_names if f"ci/{n}" not in _s1_tbl] + if _miss_s1: + bad(f"Énumération gates statiques · la table §1 de {_CI_README} n'énumère " + f"PAS {_miss_s1} — « Ce que fait le pipeline » doit lister les " + f"{len(_gate_names)} gates ci/*.sh (hors lib.sh, re-dérivés de git) → " + f"ajouter la/les ligne(s) de table manquante(s)") + else: + good(f"Énumération gates statiques · les {len(_gate_names)} gates ci/*.sh " + f"sont tous cités dans la table §1 de {_CI_README}") + sys.exit(1 if FAIL else 0) PY rc=$?