Files
FreeCADWasmDev/tools/business_continuation_context.py

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)