forked from chiki2bum2/SniperGold_ML
Implements the frozen P3_DATA_ENGINE_V1_SPEC (SHA 84bf0f217ffba51197112a6bbacbcc297058e04b5ca47f0459028fe33e0321e5). Components: engine/ producer (certify, chunkmap, parse, canonical, worker, dispatcher, aggregate, storage, journal, checkpoint, lock, evidence, manifest, run_complete, dataset_builder, cli) + engine/verify independent verifier (vparse, vaggregate, vinvariants, vcompare); headless CLI sniper-data; golden corpus G01-G17; unit/property/adversarial/mutation/legacy-diff/CLI suites. Qualification verdict: QUALIFIED (all 9 mandatory gates pass; independent verifier accepted). Spec, governance record, and legacy checkpoint untouched. G-14 NOT AUTHORIZED honored; no real-data processing, no pilot, no workload 46, no chunk 760 access.
77 lines
No EOL
2.7 KiB
Python
77 lines
No EOL
2.7 KiB
Python
"""Run completion protocol (Layer 16, spec 22, RC_V1).
|
|
|
|
RUN_COMPLETE.json is produced ONLY after all chunks are committed, the
|
|
aggregator is flushed, evidence is computed, and the independent verifier
|
|
returned ACCEPTED. It contains no self-referential hashes; machine
|
|
verification re-checks every hash and file from disk.
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
|
|
from . import versions
|
|
from .util import atomic_write_json
|
|
|
|
|
|
def build_run_complete(out_root, ckpt, evidence, verifier_report_path,
|
|
verifier_verdict, layer_hashes, outputs):
|
|
payload = {
|
|
"schema_version": versions.RUN_COMPLETE_SCHEMA_VERSION,
|
|
"status": "COMPLETED",
|
|
"run_id": ckpt["run_id"],
|
|
"source_identity": ckpt["source_identity"],
|
|
"versions": ckpt["versions"],
|
|
"rows": {
|
|
"parsed": ckpt["cumulative"]["rows_parsed"],
|
|
"canonical": ckpt["cumulative"]["rows_canonical"],
|
|
"bytes_read": ckpt["cumulative"]["bytes_read"],
|
|
"malformed_total": sum(ckpt["cumulative"]["malformed"].values()),
|
|
},
|
|
"malformed": ckpt["cumulative"]["malformed"],
|
|
"outputs": outputs,
|
|
"checkpoint": {
|
|
"last_completed_chunk": ckpt["last_completed_chunk"],
|
|
"next_chunk": ckpt["next_chunk"],
|
|
"status": ckpt["status"],
|
|
},
|
|
"hashes": {
|
|
"evidence_manifest_hash": evidence.get("evidence_manifest_hash"),
|
|
"layer_hashes": layer_hashes,
|
|
},
|
|
"verifier_report": verifier_report_path,
|
|
"verifier_verdict": verifier_verdict,
|
|
"completion_ts_utc": _utc_now_iso(),
|
|
}
|
|
atomic_write_json(_run_complete_of(out_root), payload)
|
|
return payload
|
|
|
|
|
|
def _run_complete_of(out_root):
|
|
return os.path.join(out_root, "RUN_COMPLETE.json")
|
|
|
|
|
|
def load_run_complete(out_root):
|
|
with open(_run_complete_of(out_root), "r", encoding="utf-8") as fh:
|
|
return json.load(fh)
|
|
|
|
|
|
def verify_run_complete(out_root, evidence_payload):
|
|
"""Machine re-check (spec 22): status COMPLETED and the recorded evidence
|
|
manifest hash must equal the on-disk evidence manifest hash. Returns
|
|
(ok, diffs)."""
|
|
try:
|
|
rc = load_run_complete(out_root)
|
|
except Exception as e:
|
|
return False, ["RUN_COMPLETE.json unreadable: %s" % e]
|
|
diffs = []
|
|
if rc.get("status") != "COMPLETED":
|
|
diffs.append("status != COMPLETED")
|
|
if rc.get("hashes", {}).get("evidence_manifest_hash") != \
|
|
evidence_payload.get("evidence_manifest_hash"):
|
|
diffs.append("evidence_manifest_hash mismatch")
|
|
return (not diffs), diffs
|
|
|
|
|
|
def _utc_now_iso():
|
|
import datetime
|
|
return datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00", "Z") |