91 lines
4.6 KiB
Python
91 lines
4.6 KiB
Python
"""Read only the selected IDs' indexed evidence; never scan historical cases."""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def read(path):
|
|
try:
|
|
value = json.loads(path.read_text())
|
|
return value if isinstance(value, dict) else {}
|
|
except (OSError, ValueError):
|
|
return {}
|
|
|
|
|
|
def retained_results(ids, *, root=ROOT):
|
|
root = Path(root).resolve()
|
|
ledger = read(root / "docs/current/business-acceptance.json").get("records", {})
|
|
progress = read(root / "docs/current/scheduler-progress.json").get("records", {})
|
|
cache = {}
|
|
rows, paths = [], set()
|
|
for record_id in sorted(set(ids)):
|
|
entry = ledger.get(record_id, {})
|
|
row = {"id": record_id, "instruction": "Continue remaining behavior; do not replay completed assertions just for a new timestamp."}
|
|
attempted = progress.get(record_id, {})
|
|
if attempted:
|
|
row.update(lastCycle=attempted.get("lastCycle"), lastReason=str(attempted.get("lastReason", ""))[:900])
|
|
# A later failure can coexist with a historical pass; retain both facts.
|
|
names = [("lastFailureEvidencePath", "lastFailureEvidenceSha256"), ("evidencePath", "evidenceSha256")]
|
|
proofs = []
|
|
seen = set()
|
|
for path_key, hash_key in names:
|
|
name, expected = entry.get(path_key), entry.get(hash_key)
|
|
if not isinstance(name, str) or name in seen or not isinstance(expected, str):
|
|
continue
|
|
seen.add(name)
|
|
path = (root / name).resolve()
|
|
if not path.is_relative_to(root / "docs/current/business-evidence"):
|
|
continue
|
|
if path not in cache:
|
|
try:
|
|
data = path.read_bytes()
|
|
cache[path] = (hashlib.sha256(data).hexdigest(), json.loads(data))
|
|
except (OSError, ValueError):
|
|
cache[path] = (None, {})
|
|
actual_hash, report = cache[path]
|
|
if actual_hash != expected or not isinstance(report, dict):
|
|
continue
|
|
result = next((item for item in report.get("results", []) if isinstance(item, dict)
|
|
and item.get("capabilityId") == record_id), None)
|
|
if result is None:
|
|
continue
|
|
paths.add(path)
|
|
completed = [str(assertion.get("name", ""))[:200] for case in result.get("cases", [])
|
|
if isinstance(case, dict) for assertion in case.get("assertions", [])
|
|
if isinstance(assertion, dict) and assertion.get("passed") is True]
|
|
remaining = result.get("remaining", [])
|
|
first_error = result.get("error")
|
|
if not first_error:
|
|
for case in result.get("cases", []):
|
|
if isinstance(case, dict) and any(isinstance(a, dict) and a.get("passed") is False for a in case.get("assertions", [])):
|
|
actual = case.get("actual", {})
|
|
first_error = actual.get("error") if isinstance(actual, dict) else actual
|
|
if not first_error:
|
|
first_error = next((a.get("name") for a in case.get("assertions", []) if a.get("passed") is False), None)
|
|
break
|
|
proofs.append({"path": name, "statusAtExecution": result.get("status"),
|
|
"recordedAt": report.get("executedAt"), "integrityVerified": True,
|
|
"currentInputsRevalidated": False, "completedAssertions": completed[:8],
|
|
"completedAssertionCount": len(completed),
|
|
"remaining": remaining[:8] if isinstance(remaining, list) else str(remaining)[:1200],
|
|
"firstError": str(first_error or "")[:1000],
|
|
"deferredCases": result.get("deferredCases", [])[:8]})
|
|
# Exact evidence-owned implementation files are valid patch anchors.
|
|
# Their fingerprints are not treated as current acceptance here.
|
|
for source in result.get("evidenceFiles", {}):
|
|
if not isinstance(source, str):
|
|
continue
|
|
source_path = (root / source).resolve()
|
|
if source_path.is_relative_to(root) and source_path.is_file() and source_path.suffix in {
|
|
".cpp", ".cxx", ".h", ".hpp", ".ts", ".tsx", ".mjs", ".py"}:
|
|
paths.add(source_path)
|
|
if proofs:
|
|
row["evidence"] = proofs
|
|
if proofs or attempted:
|
|
rows.append(row)
|
|
return rows, sorted(paths)
|