[DTP-Worker] Sprint 8 · buffer L75 · Domaine QA/Audit 5D (2e surface) : la TABLE « Verdict courant » de l'audit de conformité énumérait À LA MAIN ses 4 open items (control → dimension → propriétaire) sans AUCUN gate d'IDENTITÉ. Le bloc audit_5d existant gate « 17 contrôles / 5 dimensions » (×2 docs) ET la ventilation du verdict « 13 PASS · 0 FAIL · 4 à confirmer » (recomputée d'audit_report.totals) mais PAS l'identité des 4 contrôles ouverts ni leur (dimension, propriétaire) — surface data-derived distincte du MÊME README. Cette table dérive d'audit_report.json.open_items[] (byte-gaté par check_artifacts : chaque item = {control, dimension, owner, detail} recalculé en rejouant les contrôles sur les hand-off amont). Le bloc de VENTILATION ne recompute que le COMPTE (« 4 à confirmer ») : un ÉCHANGE d'open item (ex. D2.3 → D3.1) laisse le compte à 4 — le compteur reste AVEUGLE — pendant que l'artefact dit autre chose ; idem une dimension mal étiquetée (D1.3 rangé sous D2) ou un propriétaire réattribué — « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS, pas la prose) n'attrape → nouveau bloc dans check_readme_claims recomputant l'ensemble {control:(dimension, propriétaire)} depuis audit_report.open_items (zéro duplication du modèle de l'auditeur #6) et exigeant que la table README l'énumère EXACTEMENT. Contrôle par ENSEMBLE (absent ET en trop mordus, pas seulement présence), puis (dimension, propriétaire) PAR LIGNE. Même patron que l'énumération des confirmations DevOps ou la carte de renormalisation par archétype 4Big. Cohérence croisée en bonus : l'ensemble des control == MANIFEST.open_items (le manifeste qui résume le rapport) — mord un manifeste désynchronisé de son rapport. Un claim absent échoue AUSSI (4 morsures vérifiées : échange D2.3→D3.1 capté là où le compte reste 4 · dimension D1.3→D2 captée · propriétaire D1.1 Direction→Compta capté · ligne D1.2 supprimée = sous-ensemble capté ; restauré = green : [D1.1,D1.2,D1.3,D2.3] control→dimension→propriétaire == audit_report.open_items). État courant : aucun open item périmé (anti-invention #6, rien à réécrire) — le défaut est la surface ungated. ci/README.md (table + détail) mis à jour · 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,63 @@
|
||||
# Activity Log · 2026-07-31 · Claude Code DTP
|
||||
|
||||
## Session `20260731_143104` · Buffer S8 · Domaine QA/Audit 5D (2e surface) : la **table « Verdict courant »** de l'audit de conformité énumérait À LA MAIN ses **4 open items** (`control → dimension → propriétaire`) sans gate d'IDENTITÉ — le bloc existant ne recompute que le COMPTE (« 4 à confirmer »), aveugle à un **échange** d'open item.
|
||||
|
||||
**Tâche** : **Sprint 8 · buffer L75** (DevOps CI/CD · QA). Roadmap fonctionnellement
|
||||
close ; poursuite de la série anti-dérive (CLAUDE.md #6). Le bloc `audit_5d` gaté
|
||||
précédemment couvre « 17 contrôles / 5 dimensions » (×2 docs) **et** la ventilation
|
||||
du verdict « **13 PASS · 0 FAIL · 4 à confirmer** » (recomputée d'`audit_report.totals`).
|
||||
Restait, dans le **même README**, une surface data-derived distincte : la **table
|
||||
« Verdict courant »** qui énumère les 4 contrôles ouverts avec leur dimension et leur
|
||||
propriétaire.
|
||||
|
||||
**Dérive silencieuse fermée** :
|
||||
- `05_deliverables_mvp/qa/audit_5d/README.md:51-56` énumère 4 lignes
|
||||
`| D1.1 · … | D1 | Direction |` … — chacune porte trois faits data-derived :
|
||||
l'`id` du contrôle, sa **dimension**, son **propriétaire**.
|
||||
- Source faisant autorité : `qa/audit_5d/out/audit_report.json.open_items[]`
|
||||
(byte-gaté par `check_artifacts`, chaque item = `{control, dimension, owner, detail}`
|
||||
recalculé en rejouant les contrôles sur les hand-off amont).
|
||||
- Le bloc de **ventilation** ne gate QUE le **compte** (« 4 à confirmer »). Un
|
||||
**échange** d'open item (ex. `D2.3 → D3.1`) laisse le compte à 4 — le compteur
|
||||
reste AVEUGLE — pendant que l'artefact dit autre chose ; idem une **dimension**
|
||||
mal étiquetée (`D1.3` rangé sous `D2`) ou un **propriétaire** réattribué. « Vert
|
||||
trompeur » qu'aucune suite `tests/` (qui teste des FONCTIONS, pas la prose) n'attrape.
|
||||
- **État courant** : **aucun open item périmé** — les 4 lignes recoupent l'artefact
|
||||
exactement (anti-invention #6, rien à réécrire). Le défaut est la **surface ungated**.
|
||||
|
||||
**Nouveau bloc dans `ci/check_readme_claims.sh`** : recompute l'ensemble
|
||||
`{control:(dimension, propriétaire)}` depuis `audit_report.open_items` (zéro
|
||||
duplication du modèle de l'auditeur · #6) et exige que la table README l'énumère
|
||||
**exactement** : contrôle par **ENSEMBLE** (absent ET en trop mordus, pas seulement
|
||||
présence), puis `(dimension, propriétaire)` **par LIGNE**. Même patron que
|
||||
l'énumération des confirmations DevOps ou la carte de renormalisation par archétype
|
||||
4Big. Cohérence croisée en bonus : l'ensemble des `control` == `MANIFEST.open_items`
|
||||
(le manifeste qui résume le rapport) — mord un manifeste désynchronisé de son rapport.
|
||||
|
||||
### Preuve (4 morsures vérifiées + restauration verte)
|
||||
|
||||
| Injection | Résultat |
|
||||
|---|---|
|
||||
| échange `D2.3 → D3.1` (compte reste 4 · gate-compte aveugle) | ✗ énumère `[…,D3.1]` MAIS référentiel `[…,D2.3]` · exit 1 |
|
||||
| dimension `D1.3` étiquetée `D2` (compte + ids intacts) | ✗ open item D1.3 dit dimension=D2 MAIS artefact D1 · exit 1 |
|
||||
| propriétaire `D1.1` `Direction → Compta` (compte + ids + dims intacts) | ✗ D1.1 dit propriétaire=Compta MAIS artefact Direction · exit 1 |
|
||||
| ligne `D1.2` supprimée (sous-ensemble) | ✗ énumère `[D1.1,D1.3,D2.3]` MAIS référentiel `[D1.1,D1.2,D1.3,D2.3]` · exit 1 |
|
||||
| restauré | ✓ `[D1.1,D1.2,D1.3,D2.3]` (control→dimension→propriétaire) == `audit_report.open_items` · exit 0 |
|
||||
|
||||
- **`ci/README.md`** — surface ajoutée à la table récap du pipeline + paragraphe
|
||||
descriptif (2e surface du même README audit 5D).
|
||||
|
||||
Suite CI complète re-verte (7 gates) : `guard_constraints` · `validate_json` ·
|
||||
`check_docs` · `check_artifacts` · `check_regression` · `check_ci_integrity` ·
|
||||
`check_readme_claims`.
|
||||
|
||||
**Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ;
|
||||
édition **hors** `05_deliverables_mvp` ⇒ 0 dérive d'artefact).
|
||||
|
||||
**Auto-score 4Big** : 96/100.
|
||||
|
||||
---
|
||||
|
||||
## Session `20260731_140101` · Buffer S8 · Domaine QA/Audit 4Big (2e surface) : la **carte de renormalisation PAR ARCHÉTYPE** de l'auditeur (« `data_room` (sans HANDOFF) · `parser` (sans CONTRAT … ni HANDOFF) · `contract` (sans CLI ni HANDOFF) ») était transcrite À LA MAIN dans le README du module — la session précédente a gaté le barème (critères + poids + `generator (N critères)`) mais PAS les exclusions des trois autres archétypes.
|
||||
|
||||
**Tâche** : **Sprint 8 · buffer L75** (DevOps CI/CD · QA). Roadmap fonctionnellement
|
||||
|
||||
+16
-1
@@ -20,7 +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 des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) **et** du run-sheet de démo (nombre de modules cités dans le diagramme du README) **et** du montage Chat OTOIA par portail (`Custom Block`/configs runtime/portails, tous = 5 aujourd'hui, ×2 docs) **et** du module de recette `qa/acceptance` (couple livrables de sprint + métriques succès MVP, ×2 docs de module au-delà du README d'entrée) **et** du barème de l'auditeur 4Big (nombre de critères en prose + poids par critère de la table + « generator (N critères) », recomputés de `quality_report.criteria`) **et** de la carte de renormalisation par archétype de l'auditeur 4Big (critères EXCLUS de `data_room`/`parser`/`contract`, recomputés des `checks` par archétype de `quality_report.modules`) == artefact cité (#6) | ✅ oui |
|
||||
| `check-readme-claims` | `ci/check_readme_claims.sh` | Intégrité des chiffres des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer + énumération des open items `control→dimension→propriétaire` recomputée de `audit_report.open_items`) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) **et** du run-sheet de démo (nombre de modules cités dans le diagramme du README) **et** du montage Chat OTOIA par portail (`Custom Block`/configs runtime/portails, tous = 5 aujourd'hui, ×2 docs) **et** du module de recette `qa/acceptance` (couple livrables de sprint + métriques succès MVP, ×2 docs de module au-delà du README d'entrée) **et** du barème de l'auditeur 4Big (nombre de critères en prose + poids par critère de la table + « generator (N critères) », recomputés de `quality_report.criteria`) **et** de la carte de renormalisation par archétype de l'auditeur 4Big (critères EXCLUS de `data_room`/`parser`/`contract`, recomputés des `checks` par archétype de `quality_report.modules`) == 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
|
||||
@@ -233,6 +233,21 @@ contrôle en A_CONFIRMER (pass 13→12, à confirmer 4→5) là où le total de
|
||||
reste 17 et resterait aveugle. Cohérence croisée en bonus : `controls_total` du
|
||||
MANIFEST doit égaler `totals.controls` du rapport.
|
||||
|
||||
Deuxième surface du **même README** de l'audit 5D : la **table « Verdict courant »**
|
||||
énumère **à la main** les 4 open items (`| D1.1 · … | D1 | Direction |` …), chacun
|
||||
portant trois faits data-derived — l'`id` du contrôle, sa **dimension** et son
|
||||
**propriétaire**. Le bloc de ventilation ci-dessus ne gate que le **compte** (« 4 à
|
||||
confirmer ») : un **échange** d'open item (ex. `D2.3 → D3.1`), une **dimension** mal
|
||||
étiquetée (`D1.3` rangé sous `D2`) ou un **propriétaire** réattribué laisserait le
|
||||
compte à 4 et **passerait en silence**. On RECOMPUTE l'ensemble
|
||||
`{control:(dimension, propriétaire)}` depuis `qa/audit_5d/out/audit_report.json`
|
||||
(`open_items[]`, byte-gaté) et on exige que la table README l'énumère **exactement** :
|
||||
contrôle par **ensemble** (absent **et** en trop mordus, pas seulement présence),
|
||||
puis `(dimension, propriétaire)` **par ligne** — même patron que l'énumération des
|
||||
confirmations DevOps ou la carte de renormalisation par archétype 4Big. Cohérence
|
||||
croisée en bonus : l'ensemble des `control` == `MANIFEST.open_items` (le manifeste qui
|
||||
résume le rapport) — mord un manifeste désynchronisé de son propre rapport.
|
||||
|
||||
Même classe enfin sur le **run-book de déploiement VPS** (livrable
|
||||
`devops/deploy_runbook`) : le compte de **phases** (fiche agent `devops` — « graphe
|
||||
de **7 phases ordonnées** » **et** « exécute les 7 phases sur le VPS ») **et** le
|
||||
|
||||
@@ -1024,6 +1024,70 @@ if a5_ctl is not None:
|
||||
bad(f"Audit 5D · {A5D_FI} — dit {'/'.join(m.groups())} MAIS artefact dit "
|
||||
f"{a5_ctl}/{a5_dim} ({a5_src}) → régénérer la fiche")
|
||||
|
||||
# ============================================================================
|
||||
# Audit 5D (2e surface du MÊME README) · ÉNUMÉRATION des open items du « Verdict
|
||||
# courant » (control → dimension → propriétaire) — même classe de « vert trompeur ».
|
||||
# ----------------------------------------------------------------------------
|
||||
# Le bloc précédent gate le COMPTE de la ventilation (« 13 PASS · 0 FAIL · 4 à
|
||||
# confirmer », pass/fail/à confirmer recomputés d'audit_report.totals) mais PAS
|
||||
# l'IDENTITÉ des 4 contrôles ouverts ni leur (dimension, propriétaire). La table
|
||||
# « Verdict courant » du README (05_deliverables_mvp/qa/audit_5d/README.md) énumère
|
||||
# ces 4 lignes À LA MAIN, alors que audit_report.open_items[] (byte-gaté par
|
||||
# check_artifacts ⇒ faisant autorité, chaque item = {control, dimension, owner,
|
||||
# detail} recalculé en rejouant les contrôles) fait foi. Un ÉCHANGE d'open item
|
||||
# (ex. D2.3 → D3.1) laisse le compte à 4 — le bloc de ventilation reste AVEUGLE —
|
||||
# pendant que l'artefact dit autre chose ; idem une dimension mal étiquetée
|
||||
# (D1.3 rangé sous D2) ou un propriétaire réattribué. « Vert trompeur » qu'aucune
|
||||
# suite tests/ (qui teste des FONCTIONS, pas la prose) n'attrape. On RECOMPUTE
|
||||
# l'ensemble {control:(dimension, owner)} depuis open_items (zéro duplication du
|
||||
# modèle de l'auditeur · #6) et on exige que la table README l'énumère EXACTEMENT :
|
||||
# contrôle par ENSEMBLE (absent ET en trop mordus, pas seulement présence), puis
|
||||
# (dimension, propriétaire) par LIGNE. Même patron que l'énumération des
|
||||
# confirmations DevOps ou la carte de renormalisation par archétype 4Big. Cohérence
|
||||
# croisée en bonus : l'ensemble des `control` == MANIFEST.open_items (le manifeste
|
||||
# qui résume le rapport) — mord un manifeste désynchronisé de son propre rapport.
|
||||
# ============================================================================
|
||||
try:
|
||||
a5_oi = load("qa/audit_5d/out/audit_report.json")["open_items"]
|
||||
a5_oi_exp = {o["control"]: (o["dimension"], o["owner"]) for o in a5_oi}
|
||||
a5_oi_man = set(load("qa/audit_5d/out/MANIFEST.json")["open_items"])
|
||||
if a5_oi_man != set(a5_oi_exp):
|
||||
bad(f"Audit 5D · incohérence artefacts : MANIFEST open_items {sorted(a5_oi_man)} "
|
||||
f"MAIS audit_report open_items {sorted(a5_oi_exp)}")
|
||||
except (OSError, KeyError, ValueError) as e:
|
||||
bad(f"Audit 5D · open_items illisible/inattendu : {e}"); a5_oi_exp = None
|
||||
if a5_oi_exp is not None:
|
||||
try:
|
||||
a5_lines = open(f"{D}/qa/audit_5d/README.md",
|
||||
encoding="utf-8").read().splitlines()
|
||||
except OSError as e:
|
||||
bad(f"Audit 5D · README illisible : {e}"); a5_lines = None
|
||||
if a5_lines is not None:
|
||||
# ligne de table = « | <control> · <libellé> | <dimension> | <propriétaire> | »
|
||||
a5_row_re = re.compile(
|
||||
r"^\|\s*(D\d+\.\d+)\b[^|]*\|\s*([^|]+?)\s*\|\s*([^|]+?)\s*\|\s*$")
|
||||
a5_seen = {}
|
||||
for ln in a5_lines:
|
||||
m = a5_row_re.match(ln)
|
||||
if m:
|
||||
a5_seen[m.group(1)] = (m.group(2).strip(), m.group(3).strip())
|
||||
a5_exp_set, a5_got_set = set(a5_oi_exp), set(a5_seen)
|
||||
if a5_got_set != a5_exp_set:
|
||||
bad(f"Audit 5D · énumération open items — table README énumère "
|
||||
f"{sorted(a5_got_set)} MAIS audit_report dit {sorted(a5_exp_set)} "
|
||||
f"→ régénérer le README")
|
||||
else:
|
||||
a5_mism = [c for c in sorted(a5_exp_set) if a5_seen[c] != a5_oi_exp[c]]
|
||||
if a5_mism:
|
||||
for c in a5_mism:
|
||||
bad(f"Audit 5D · open item {c} — README dit "
|
||||
f"(dimension={a5_seen[c][0]}, propriétaire={a5_seen[c][1]}) MAIS "
|
||||
f"audit_report dit (dimension={a5_oi_exp[c][0]}, "
|
||||
f"propriétaire={a5_oi_exp[c][1]})")
|
||||
else:
|
||||
good(f"Audit 5D · énumération open items {sorted(a5_exp_set)} "
|
||||
f"(control→dimension→propriétaire) == audit_report.open_items")
|
||||
|
||||
# ============================================================================
|
||||
# DevOps · run-book de déploiement VPS (phases ordonnées / confirmations
|
||||
# préalables) — même classe de « vert trompeur », transcrite À LA MAIN dans
|
||||
|
||||
Reference in New Issue
Block a user