Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m2s
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a10e2d-a5ef-7e92-b03d-b1694e915680
68 lines
3.4 KiB
Python
68 lines
3.4 KiB
Python
"""Versioned journey registry and mandatory collected-test coverage validation."""
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
REGISTRY = ROOT / "docs/usecases/registry.json"
|
|
|
|
|
|
def load_cases():
|
|
data = json.loads(REGISTRY.read_text(encoding="utf-8"))
|
|
if data.get("schema_version") != 1 or not isinstance(data.get("cases"), list):
|
|
raise ValueError("Unsupported use-case registry schema")
|
|
cases = data["cases"]
|
|
if not cases:
|
|
raise ValueError("The use-case registry cannot be empty")
|
|
ids = set()
|
|
for case in cases:
|
|
uid = case["id"]
|
|
if uid in ids:
|
|
raise ValueError(f"Duplicate use-case id: {uid}")
|
|
ids.add(uid)
|
|
if case["confirmation"] not in {"inferred", "observed", "user-confirmed"}:
|
|
raise ValueError(f"Unknown confirmation for {uid}")
|
|
if case["transfer_status"] not in {"pending-user-review", "accepted", "deferred"}:
|
|
raise ValueError(f"Unknown transfer status for {uid}")
|
|
if case["transfer_status"] == "accepted" and not case.get("acceptance_ref"):
|
|
raise ValueError(f"Accepted case {uid} needs a user acceptance reference")
|
|
for field in ("narrative", "fixture"):
|
|
path = (ROOT / case[field]).resolve()
|
|
if not path.is_relative_to(ROOT) or not path.is_file():
|
|
raise ValueError(f"Missing or outside-repo {field} for {uid}")
|
|
fixture = json.loads((ROOT / case["fixture"]).read_text(encoding="utf-8"))
|
|
if fixture.get("synthetic") is not True or fixture.get("usecase_id") != uid:
|
|
raise ValueError(f"Fixture must be synthetic and linked to {uid}")
|
|
if not isinstance(case["established"], bool):
|
|
raise ValueError(f"established must be a boolean for {uid}")
|
|
if set(case["tests"]) != {"fast", "browser"}:
|
|
raise ValueError(f"Expected fast and browser test layers for {uid}")
|
|
if case["established"]:
|
|
if case["confirmation"] != "user-confirmed" or not case["contract"]:
|
|
raise ValueError(f"Established case {uid} needs user confirmation and contract")
|
|
for layer in ("fast", "browser"):
|
|
if not case["tests"].get(layer):
|
|
raise ValueError(f"Established case {uid} missing {layer} coverage")
|
|
return cases
|
|
|
|
|
|
def validate_coverage(cases, collected):
|
|
"""Require exact node IDs, UC marker, and correct fast/browser layer."""
|
|
ids = {case["id"] for case in cases}
|
|
for nodeid, markers in collected.items():
|
|
if markers["usecases"] - ids:
|
|
raise ValueError(f"Use-case test has an unregistered ID: {nodeid}")
|
|
for case in cases:
|
|
if not case["established"]:
|
|
continue
|
|
for layer, nodeids in case["tests"].items():
|
|
for nodeid in nodeids:
|
|
markers = collected.get(nodeid)
|
|
if markers is None:
|
|
raise ValueError(f"{case['id']} missing collected {layer} test: {nodeid}")
|
|
if case["id"] not in markers["usecases"]:
|
|
raise ValueError(f"{nodeid} is not marked for {case['id']}")
|
|
if markers.get("disabled"):
|
|
raise ValueError(f"Protected use-case test cannot skip/xfail: {nodeid}")
|
|
if markers["browser"] != (layer == "browser"):
|
|
raise ValueError(f"Wrong regression layer for {nodeid}")
|