Files
ARCADIA-Studio/harness/experiments/default-consumers-20260913/verify.py
T

160 lines
10 KiB
Python

"""Read-only verification of the four frozen consumer/lint/desktop/build 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 = "df2e1cd65ca5e56f47669e04a9d4bcb426900fcd"
INPUTS = {"bytes": 102567, "sha256": "6bf74c1f68431a034681b754617c39d387783f71354c9106649aec9480e4f29f"}
SOURCE_ZIP = {"bytes": 2483742, "sha256": "e20f33dc363850a9289103a7be28ad613c3fffb2039061957a0186cac72d541b"}
HELPER = {"bytes": 3097, "sha256": "f14928bb472fc160e0a100a98139cf537380ec232626b0a7bb66f72bfc06128b"}
GATES = {
"production-consumers-1": (63, 0, 0, 4),
"production-clippy-1": (0, 0, 0, 0),
"production-desktop-1": (894, 0, 6, 1),
"production-windows-build-1": (0, 0, 0, 3),
}
GATE_FILES = {"started.json", "result.json", "stdout.log", "stderr.log"}
SHARED_FILES = {"inputs.json", "inputs.zip"}
COMMANDS = {
"production-consumers-1": ["cargo", "test", "--locked", "--offline", "-p", "oa-server", "--test", "http", "-p", "oa-cli", "--test", "source_cli", "--no-fail-fast", "--message-format=json", "--", "--nocapture"],
"production-clippy-1": ["cargo", "clippy", "--locked", "--offline", "--workspace", "--all-targets", "--message-format=json", "--", "-D", "warnings"],
"production-desktop-1": ["cargo", "test", "--locked", "--offline", "-p", "oa-desktop", "--bin", "arcadia-studio", "--no-fail-fast", "--message-format=json", "--", "--nocapture"],
"production-windows-build-1": ["cargo", "build", "--locked", "--offline", "--workspace", "--bins", "--message-format=json"],
}
ROWS = {
"production-consumers-1": [(12, 0, 0, 0, 0), (51, 0, 0, 0, 0)],
"production-clippy-1": [],
"production-desktop-1": [(894, 0, 6, 0, 0)],
"production-windows-build-1": [],
}
TARGETS = {
"production-consumers-1": {"http", "source_cli", "arcadia", "arcadia-server"},
"production-clippy-1": set(),
"production-desktop-1": {"arcadia-studio"},
"production-windows-build-1": {"arcadia", "arcadia-server", "arcadia-studio"},
}
IGNORED = {
"app::source_rename::timing_tests::accepted_release1_prepare_commit_sync_and_confirm_timing",
"app::source_rename::timing_tests::layout_timing_tests::accepted_release1_constructor_vs_reuse_through_next_highlight",
"app::source_symbols::tests::source_symbols_100_modules_1000_definitions_10000_uses",
"source_annotations::anchor_tests::final_multi_glyph_cluster_anchor_uses_logical_trailing_advance_edge",
"source_annotations::anchor_tests::mixed_direction_omitted_separator_has_one_logical_predecessor_anchor",
"source_annotations::performance_tests::annotation_projection_cost_distributions",
}
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))
def read_gate(gate, name):
# Original source payloads have identical byte pins in all four receipts.
# Store them once; independently check each gate against those bytes.
return evidence.read(f"shared/{name}" if name in SHARED_FILES else f"{gate}/{name}")
payloads = read_json("capture-files.json")
expected_members = {f"{gate}/{name}" for gate in GATES for name in GATE_FILES} | {"gate-policy.py"} | {f"shared/{name}" for name in SHARED_FILES}
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(read_gate(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")
require(environment["CARGO_BUILD_JOBS"] == "1", f"{gate}: jobs receipt mismatch")
require(result["command"] == COMMANDS[gate], f"{gate}: command mismatch")
inputs = json.loads(read_gate(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-server/tests/http.rs", "crates/oa-cli/tests/source_cli.rs"} <= set(inputs), f"{gate}: production inputs missing")
with zipfile.ZipFile(io.BytesIO(read_gate(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)]
require(rows == ROWS[gate], f"{gate}: per-suite outcomes mismatch")
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 for name, status in named if status.startswith("ignored")} == IGNORED, f"{gate}: ignored test inventory 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")
require({item["target"]["name"] for item in artifacts} == TARGETS[gate], f"{gate}: executable targets 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(all(snapshot == snapshots[0] for snapshot in snapshots), "Gate inputs differ")
require(all(before[1] <= after[0] for before, after in zip(times, times[1:])), "Gate chronology mismatch")
print("Verified 19 captured payloads; four independently pinned, identical 613-input snapshots captured with HEAD " + HEAD + ".")
print("Windows: consumers 63 passed (12 CLI + 51 HTTP); desktop 894 passed / 6 ignored; strict workspace Clippy and 3-binary build succeeded.")
print("Recorded automated evidence only; no binaries distributed and no interactive native, Linux, packaging or release acceptance claim.")