129 lines
8.4 KiB
Python
129 lines
8.4 KiB
Python
"""Read-only verification of the two frozen production follow-up captures."""
|
|
from pathlib import Path, PurePosixPath
|
|
from datetime import datetime
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import math
|
|
import re
|
|
import zipfile
|
|
|
|
ROOT = Path(__file__).resolve().parent
|
|
HEAD = "7bb366f66a8c6f8b6f66fc9b04c9e3b39f84b78e"
|
|
INPUTS = {"bytes": 102567, "sha256": "b9a161be8aca264a6dcf4e7df5cbb7a4f9d999411f1da97430ec0eb3a9929566"}
|
|
SOURCE_ZIP = {"bytes": 2482727, "sha256": "79dfd5167779094f30f0ee7bdcd678935f7471b294fa2193cfcfd4a5a843459c"}
|
|
HELPER = {"bytes": 3097, "sha256": "f14928bb472fc160e0a100a98139cf537380ec232626b0a7bb66f72bfc06128b"}
|
|
GATES = {"production-followup-1": (180, 0, 0, 9), "production-core-2": (511, 0, 1, 49)}
|
|
GATE_FILES = {"inputs.json", "inputs.zip", "started.json", "result.json", "stdout.log", "stderr.log"}
|
|
FOCUSED = ["language", "port_anchors", "source_project", "default_omission_fidelity", "default_omission_output", "default_omission_updates", "default_omission_preservation", "default_omission_admission"]
|
|
|
|
|
|
def require(condition, message):
|
|
if not condition:
|
|
raise SystemExit(message)
|
|
|
|
|
|
def digest(data):
|
|
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
|
|
|
|
|
|
def membership(archive, expected, label):
|
|
names = archive.namelist()
|
|
require(len(names) == len(set(names)), f"{label}: duplicate ZIP members")
|
|
require(set(names) == set(expected), f"{label}: ZIP membership mismatch")
|
|
require(all(not PurePosixPath(name).is_absolute() and ".." not in PurePosixPath(name).parts and "\\" not in name for name in names), f"{label}: unsafe member name")
|
|
|
|
|
|
manifest = json.loads((ROOT / "files.json").read_text(encoding="utf-8"))
|
|
actual = {path.relative_to(ROOT).as_posix() for path in ROOT.rglob("*") if path.is_file() and path.name != "files.json" and "__pycache__" not in path.parts}
|
|
require(actual == set(manifest) == {"README.md", "verify.py", "evidence.zip"}, "Outer membership mismatch")
|
|
for name, expected in manifest.items():
|
|
require(digest((ROOT / name).read_bytes()) == expected, f"Outer hash mismatch: {name}")
|
|
|
|
with zipfile.ZipFile(ROOT / "evidence.zip") as evidence:
|
|
def read_json(name):
|
|
return json.loads(evidence.read(name))
|
|
|
|
payloads = read_json("capture-files.json")
|
|
expected_members = {f"{gate}/{name}" for gate in GATES for name in GATE_FILES} | {"gate-policy.py"}
|
|
require(set(payloads) == expected_members, "Captured file inventory mismatch")
|
|
membership(evidence, expected_members | {"capture-files.json"}, "Evidence")
|
|
for name, expected in payloads.items():
|
|
require(digest(evidence.read(name)) == expected, f"Capture hash mismatch: {name}")
|
|
require(digest(evidence.read("gate-policy.py")) == HELPER, "Frozen helper pin mismatch")
|
|
|
|
snapshots = []
|
|
times = []
|
|
for gate, (passed, failed, ignored, artifact_count) in GATES.items():
|
|
result = read_json(f"{gate}/result.json")
|
|
started = read_json(f"{gate}/started.json")
|
|
require(all(key in result and result[key] == value for key, value in started.items()), f"{gate}: start/result mismatch")
|
|
require(result["head"] == HEAD and result["cwd"] == "C:\\ar-default-9e8r6t", f"{gate}: source identity mismatch")
|
|
require(result["exitCode"] == 0 and result["inputsUnchanged"] is True, f"{gate}: failed or changed input receipt")
|
|
require(result["inputs"] == INPUTS and result["archive"] == SOURCE_ZIP and result["helper"] == HELPER, f"{gate}: frozen pins mismatch")
|
|
for key, name in [("inputs", "inputs.json"), ("archive", "inputs.zip"), ("stdout", "stdout.log"), ("stderr", "stderr.log")]:
|
|
require(digest(evidence.read(f"{gate}/{name}")) == result[key], f"{gate}: {key} receipt mismatch")
|
|
|
|
start, finish = (datetime.fromisoformat(result[key]) for key in ["start", "finish"])
|
|
duration = result["seconds"]
|
|
require(start.tzinfo is not None and finish.tzinfo is not None, f"{gate}: unzoned timestamps")
|
|
require(math.isfinite(duration) and duration >= 0 and 0 <= (finish - start).total_seconds() - duration < 30, f"{gate}: time consistency")
|
|
times.append((start, finish))
|
|
environment = result["environment"]
|
|
require(environment["RUSTUP_TOOLCHAIN"] == "stable-x86_64-pc-windows-gnullvm" and environment["CARGO_INCREMENTAL"] == "0", f"{gate}: native Windows environment mismatch")
|
|
require(result["cargo"] == "cargo 1.98.1 (797e8a9bc 2026-08-05)" and result["rustc"] == "rustc 1.98.1 (48a229cea 2026-09-01)", f"{gate}: tool versions mismatch")
|
|
command = ["cargo", "test", "--locked", "--offline", "-p", "oa-core"]
|
|
if gate == "production-followup-1":
|
|
command += ["--lib"] + [part for target in FOCUSED for part in ["--test", target]]
|
|
require(environment["CARGO_BUILD_JOBS"] is None, f"{gate}: jobs receipt mismatch")
|
|
else:
|
|
command += ["--no-fail-fast"]
|
|
require(environment["CARGO_BUILD_JOBS"] == "1", f"{gate}: jobs receipt mismatch")
|
|
command += ["--message-format=json", "--", "--nocapture"]
|
|
require(result["command"] == command, f"{gate}: command mismatch")
|
|
|
|
inputs = read_json(f"{gate}/inputs.json")
|
|
require(len(inputs) == result["inputCount"] == 613, f"{gate}: input count mismatch")
|
|
require({"crates/oa-core/src/source_defaults.rs", "crates/oa-core/src/source_defaults_tests.rs", "crates/oa-core/tests/default_omission_updates.rs"} <= set(inputs), f"{gate}: production inputs missing")
|
|
with zipfile.ZipFile(io.BytesIO(evidence.read(f"{gate}/inputs.zip"))) as sources:
|
|
membership(sources, inputs, f"{gate} source")
|
|
for name, expected in inputs.items():
|
|
require(digest(sources.read(name)) == expected, f"{gate}: source hash mismatch: {name}")
|
|
snapshots.append(inputs)
|
|
|
|
stdout = evidence.read(f"{gate}/stdout.log").decode("utf-8")
|
|
rows = [tuple(map(int, row)) for row in re.findall(r"^test result: ok\. (\d+) passed; (\d+) failed; (\d+) ignored; (\d+) measured; (\d+) filtered out;", stdout, re.M)]
|
|
totals = tuple(sum(row[index] for row in rows) for index in range(5))
|
|
require(totals == (passed, failed, ignored, 0, 0), f"{gate}: raw summary totals mismatch: {totals}")
|
|
runs = [int(count) for count in re.findall(r"^running (\d+) tests?$", stdout, re.M)]
|
|
require(runs == [sum(row[:4]) for row in rows], f"{gate}: suite sizes mismatch")
|
|
named = re.findall(r"^test (.+?) \.\.\. (ok|FAILED|ignored(?:, [^\r\n]*)?)\r?$", stdout, re.M)
|
|
named_totals = (sum(status == "ok" for _, status in named), sum(status == "FAILED" for _, status in named), sum(status.startswith("ignored") for _, status in named))
|
|
require(named_totals == (passed, failed, ignored), f"{gate}: raw named totals mismatch: {named_totals}")
|
|
if ignored:
|
|
require([(name, status) for name, status in named if status.startswith("ignored")] == [("inheritance_chain_validation_scaling_probe", "ignored, explicit inheritance scaling probe; run with --ignored --nocapture")], f"{gate}: ignored test mismatch")
|
|
artifacts, finished = [], []
|
|
for line in stdout.splitlines():
|
|
try:
|
|
item = json.loads(line)
|
|
except json.JSONDecodeError:
|
|
continue
|
|
if not isinstance(item, dict):
|
|
continue
|
|
if item.get("reason") == "compiler-artifact" and item.get("executable"):
|
|
artifacts.append(item)
|
|
if item.get("reason") == "build-finished":
|
|
finished.append(item.get("success"))
|
|
require(finished == [True], f"{gate}: successful build record mismatch")
|
|
require(len(artifacts) == len(result["artifacts"]) == artifact_count and artifacts == [entry["cargo"] for entry in result["artifacts"]], f"{gate}: compiler receipt mismatch")
|
|
for entry in result["artifacts"]:
|
|
receipt = entry["readback"]
|
|
require(isinstance(receipt, dict) and receipt.get("bytes", 0) > 0 and re.fullmatch(r"[0-9a-f]{64}", receipt.get("sha256", "")) is not None, f"{gate}: invalid historical binary receipt")
|
|
|
|
require(snapshots[0] == snapshots[1], "Gate inputs differ")
|
|
require(times[0][1] <= times[1][0], "Gate chronology mismatch")
|
|
|
|
print("Verified 13 captured files, two identical 613-input source captures at " + HEAD + ".")
|
|
print("Native Windows: focused 180 passed; full oa-core 511 passed, 0 failed, 1 explicitly ignored scaling probe.")
|
|
print("Recorded source/test evidence only; no binary distribution, Linux, GUI/public-consumer, Clippy or release claim.")
|