[DTP-Worker] Sprint 8 · buffer L75 · Traçabilité non vérifiée : les n° de ligne roadmap_line de la matrice d'acceptation pouvaient pointer à côté en silence (roadmap éditée) → INV11 ancrage roadmap (dérive 8+7 du fichier · #6) + parse_roadmap_anchors + 6 tests ; régénéré 558→564
INV10 ne garantissait que « roadmap_line est un entier positif ». Ajout de parse_roadmap_anchors (deps) qui DÉRIVE la structure réelle de la roadmap, et d'INV11 qui exige que chaque roadmap_line pointe RÉELLEMENT son bullet (DELIVERABLE du sprint SX · k-ième bullet métrique) et que le « 8 + 7 » soit dérivé du fichier, pas figé. Morsure prouvée sur le spec réel (S1=999, M3=200). Régénéré consommateurs : regression 558→564 (run/plan/MANIFEST), quality_report (acceptance 31→37 méthodes, 100/100 inchangé), fiches QA + Backend, README acceptance (10→11 invariants). 7 gates verts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,11 +22,14 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
# qa/acceptance/acclib → 05_deliverables_mvp
|
||||
_DELIVERABLES = os.path.normpath(os.path.join(_HERE, "..", "..", ".."))
|
||||
# 05_deliverables_mvp → racine du dépôt (où vit 04_roadmap/).
|
||||
_REPO_ROOT = os.path.normpath(os.path.join(_DELIVERABLES, ".."))
|
||||
_PUB = os.path.join(_DELIVERABLES, "publiciste")
|
||||
_AUDIT = os.path.join(_DELIVERABLES, "qa", "audit_4big")
|
||||
|
||||
@@ -55,6 +58,54 @@ def audit_sprints() -> dict:
|
||||
return {m["path"]: m["sprint"] for m in spec["modules"]}
|
||||
|
||||
|
||||
# Ancres de traçabilité de la roadmap (structure, jamais des n° saisis à la main).
|
||||
_SPRINT_HEAD = re.compile(r"##\s+SPRINT\s+\d+.*?·\s*(S\d+)\s*\(")
|
||||
_METRIC_HEAD = re.compile(r"##\s+M[ée]triques\s+succ")
|
||||
_DELIVERABLE = re.compile(r"\*\*DELIVERABLE")
|
||||
_METRIC_BULLET = re.compile(r"^-\s*✅")
|
||||
|
||||
|
||||
def parse_roadmap_anchors(roadmap_ref: str) -> dict:
|
||||
"""DÉRIVE les ancres de traçabilité depuis la roadmap réelle (#6 · jamais une
|
||||
liste de n° de ligne saisie à la main).
|
||||
|
||||
Renvoie :
|
||||
- ``deliverables`` : {sprint SX -> n° de ligne du bullet ``**DELIVERABLE**``
|
||||
appartenant au sprint SX} (le SX est LU dans le titre ``## SPRINT n … · SX (…``) ;
|
||||
- ``metrics`` : [n° de ligne] des bullets ``- ✅`` sous la section
|
||||
``## Métriques succès MVP``, en ordre de fichier ;
|
||||
- ``path`` : le chemin résolu (pour messages).
|
||||
|
||||
``roadmap_ref`` absolu est utilisé tel quel ; relatif est résolu depuis la
|
||||
racine du dépôt. Lève ``OSError`` si la roadmap est absente/illisible — une
|
||||
référence de traçabilité vers un fichier fantôme est un mensonge (red honnête)."""
|
||||
path = roadmap_ref if os.path.isabs(roadmap_ref) \
|
||||
else os.path.join(_REPO_ROOT, roadmap_ref)
|
||||
with open(path, encoding="utf-8") as fh:
|
||||
lines = fh.read().splitlines()
|
||||
|
||||
deliverables: dict[str, int] = {}
|
||||
metrics: list[int] = []
|
||||
current_sprint: str | None = None
|
||||
in_metrics = False
|
||||
for i, ln in enumerate(lines, 1):
|
||||
mh = _SPRINT_HEAD.match(ln)
|
||||
if mh:
|
||||
current_sprint, in_metrics = mh.group(1), False
|
||||
continue
|
||||
if _METRIC_HEAD.match(ln):
|
||||
current_sprint, in_metrics = None, True
|
||||
continue
|
||||
if ln.startswith("## "): # toute autre section clôt le contexte
|
||||
current_sprint, in_metrics = None, False
|
||||
continue
|
||||
if current_sprint and _DELIVERABLE.search(ln):
|
||||
deliverables[current_sprint] = i
|
||||
if in_metrics and _METRIC_BULLET.match(ln):
|
||||
metrics.append(i)
|
||||
return {"deliverables": deliverables, "metrics": metrics, "path": path}
|
||||
|
||||
|
||||
def artifact_exists(rel_path: str) -> bool:
|
||||
"""Vrai ssi l'artefact cité (chemin relatif à 05_deliverables_mvp) existe.
|
||||
|
||||
@@ -67,6 +118,7 @@ __all__ = [
|
||||
"validate",
|
||||
"parse_ci",
|
||||
"audit_sprints",
|
||||
"parse_roadmap_anchors",
|
||||
"artifact_exists",
|
||||
"DELIVERABLES_ROOT",
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user