[DTP-Worker 20260801_203424] Sprint 8 · buffer · Audit 5D (4e surface du même README) : gate d'IDENTITÉ des LIVRABLES AUDITÉS — la liste des 5 hand-off out/*.json que l'audit de second niveau LIT (README qa/audit_5d §« Livrables audités »), énumérée à la main hors de tout gate ; recomputée par ENSEMBLE de MANIFEST.audited_artifacts (byte-gaté · = sorted(ARTIFACT_PATHS.values())), ordre README ≠ ordre MANIFEST trié ⇒ set-diff absent/fantôme ; cross-anchors : chaque chemin résout un fichier commité (a) + |audités| == |alias distincts des controls[].artifacts du spec| (b) ; 6 morsures vérifiées (4 README · 2 source), 7 gates re-verts
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2317,6 +2317,99 @@ if a5d_exp is not None:
|
||||
good(f"Audit 5D · IDENTITÉ des 5 dimensions {a5d_order} "
|
||||
f"(id→titre→reference) == audit_report.dimensions")
|
||||
|
||||
# ============================================================================
|
||||
# Audit 5D (4e surface du MÊME README) · IDENTITÉ des LIVRABLES AUDITÉS — la liste
|
||||
# des hand-off `out/*.json` que l'audit de second niveau LIT comme matière première,
|
||||
# énumérée À LA MAIN dans la section « ## Livrables audités » — même classe de
|
||||
# « vert trompeur ».
|
||||
# ----------------------------------------------------------------------------
|
||||
# Les 3 blocs audit_5d ci-dessus gatent la SYNTHÈSE (contrôles/dimensions/verdict),
|
||||
# l'ÉNUMÉRATION des open items et l'IDENTITÉ des 5 dimensions — AUCUN ne touche la
|
||||
# liste des ARTEFACTS SOURCES. Cette liste vit dans MANIFEST.audited_artifacts
|
||||
# (byte-gaté par check_artifacts ⇒ faisant autorité : le générateur la recompute à
|
||||
# chaque build via `sorted(ARTIFACT_PATHS.values())`, le registre des hand-off amont
|
||||
# que `load_artifacts()` charge réellement). Le README (05_deliverables_mvp/qa/
|
||||
# audit_5d/README.md, section « ## Livrables audités (source = leur `out/`) »)
|
||||
# réénumère ces 5 chemins À LA MAIN — dans un ORDRE DIFFÉRENT du MANIFEST (workflow
|
||||
# 2e ici, 3e au MANIFEST, trié) ⇒ comparaison par ENSEMBLE. Piège : brancher un
|
||||
# nouveau livrable amont sur l'audit (nouvelle entrée ARTIFACT_PATHS → nouveau chemin
|
||||
# dans audited_artifacts) ou en retirer un laisse la section README PÉRIMÉE en
|
||||
# silence pendant que l'audit lit un autre jeu de fichiers — le lecteur/banquier
|
||||
# croirait l'audit couvrir un périmètre qu'il ne couvre plus (l'invention #6
|
||||
# interdit), qu'aucune suite tests/ (qui teste des FONCTIONS de contrôle, pas la
|
||||
# prose) n'attrape. On RECOMPUTE l'ensemble depuis MANIFEST.audited_artifacts (zéro
|
||||
# duplication du registre) et on exige que les puces README l'énumèrent EXACTEMENT
|
||||
# (absent ET fantôme mordus). Cohérences croisées bonus (mordent un MANIFEST/spec
|
||||
# INTERNEMENT incohérent) : (a) chaque chemin audité RÉSOUT un fichier commité sur
|
||||
# disque (le `_load` de l'auditeur lève sinon — audit à vide impossible) ; (b) le
|
||||
# NOMBRE de livrables audités == le nombre d'ALIAS distincts d'artefacts référencés
|
||||
# par les contrôles du spec (audit_spec.json · union des `controls[].artifacts`) : un
|
||||
# artefact chargé mais jamais contrôlé, ou un alias contrôlé sans chemin de
|
||||
# chargement (KeyError runtime), désynchronise les deux. Section absente ⇒ ROUGE
|
||||
# (traçabilité #6). Direction README/MANIFEST → registre/spec.
|
||||
# ============================================================================
|
||||
import os
|
||||
try:
|
||||
a5a_exp = load("qa/audit_5d/out/MANIFEST.json")["audited_artifacts"]
|
||||
a5a_ctrls = load("qa/audit_5d/audit_spec.json")["controls"]
|
||||
except (OSError, KeyError, ValueError) as e:
|
||||
bad(f"Audit 5D · livrables audités illisibles/inattendus : {e}"); a5a_exp = None
|
||||
if a5a_exp is not None:
|
||||
a5a_exp_set = set(a5a_exp)
|
||||
# tri/dédup : audited_artifacts = sorted(dict.values()) — mord un MANIFEST malformé
|
||||
if a5a_exp != sorted(a5a_exp_set) or len(a5a_exp) != len(a5a_exp_set):
|
||||
bad(f"Audit 5D · MANIFEST.audited_artifacts non trié/dédupliqué : {a5a_exp}")
|
||||
# (a) chaque chemin audité résout un fichier commité (audit à vide impossible)
|
||||
a5a_missing = [p for p in a5a_exp if not os.path.exists(f"{D}/{p}")]
|
||||
if a5a_missing:
|
||||
bad(f"Audit 5D · livrables audités INTROUVABLES sur disque {a5a_missing} → "
|
||||
f"l'auditeur lèverait FileNotFoundError (aucun audit à vide)")
|
||||
else:
|
||||
good(f"Audit 5D · les {len(a5a_exp)} livrables audités résolvent tous un "
|
||||
f"fichier commité")
|
||||
# (b) |audited| == |alias distincts référencés par les contrôles du spec|
|
||||
a5a_alias = set()
|
||||
for ctl in a5a_ctrls:
|
||||
a5a_alias |= set(ctl.get("artifacts", []))
|
||||
if len(a5a_alias) == len(a5a_exp_set):
|
||||
good(f"Audit 5D · {len(a5a_exp_set)} livrables audités == {len(a5a_alias)} "
|
||||
f"alias d'artefacts distincts contrôlés par le spec (aucun mort/orphelin)")
|
||||
else:
|
||||
bad(f"Audit 5D · désynchro registre/spec : {len(a5a_exp_set)} livrables "
|
||||
f"audités MAIS {len(a5a_alias)} alias distincts contrôlés "
|
||||
f"({sorted(a5a_alias)}) → artefact chargé jamais contrôlé, ou alias sans "
|
||||
f"chemin de chargement")
|
||||
# README — puces de la section « ## Livrables audités »
|
||||
try:
|
||||
a5a_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}"); a5a_lines = None
|
||||
if a5a_lines is not None:
|
||||
a5a_got, a5a_in_sec = set(), False
|
||||
a5a_bullet = re.compile(r"^-\s+`([^`]+)`\s*$")
|
||||
for ln in a5a_lines:
|
||||
if re.match(r"^##\s+Livrables audités\b", ln):
|
||||
a5a_in_sec = True; continue
|
||||
if a5a_in_sec and ln.startswith("## "):
|
||||
break
|
||||
if a5a_in_sec:
|
||||
mb = a5a_bullet.match(ln)
|
||||
if mb:
|
||||
a5a_got.add(mb.group(1))
|
||||
if not a5a_got:
|
||||
bad(f"Audit 5D · section « ## Livrables audités » INTROUVABLE/vide dans "
|
||||
f"{D}/qa/audit_5d/README.md (attendu {sorted(a5a_exp_set)})")
|
||||
elif a5a_got == a5a_exp_set:
|
||||
good(f"Audit 5D · livrables audités — les {len(a5a_got)} puces README == "
|
||||
f"MANIFEST.audited_artifacts (aucun fantôme/manquant)")
|
||||
else:
|
||||
miss = sorted(a5a_exp_set - a5a_got); extra = sorted(a5a_got - a5a_exp_set)
|
||||
detail = (f" · absents={miss}" if miss else "") + \
|
||||
(f" · en trop (fantôme)={extra}" if extra else "")
|
||||
bad(f"Audit 5D · livrables audités — README énumère {sorted(a5a_got)} MAIS "
|
||||
f"MANIFEST dit {sorted(a5a_exp_set)}{detail} → régénérer le README")
|
||||
|
||||
# ============================================================================
|
||||
# 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