[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:
@@ -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