#!/usr/bin/env python3 """Validate a recorded Windows x64 late-slope run (lmxopcua#799) with the Linux analyzer's own row/window logic. The row ledger, cold cycle-3 caps, first-rejection check, fixed windows and least-squares slopes come unchanged from ../late-slope/analyze.py (ARCHITECTURE switched to X64). Only the run-envelope checks differ: there is no container, so the launcher's PowerShell receipts (run-receipt.json, target-runtime.txt) take the place of the Docker receipts. """ import argparse import json from pathlib import Path import re import sys sys.dont_write_bytecode = True sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "late-slope")) import analyze as core # noqa: E402 core.ARCHITECTURE = "X64" APP = core.APP def read_text(path): return path.read_text(encoding="utf-8-sig") def analyze(run, bundle_receipt, source_revision): bundle = json.loads(read_text(bundle_receipt)) core.require(bundle["sourceRevision"] == source_revision and bundle["rid"] == "win-x64" and bundle["runtimeVersion"] == core.RUNTIME and bundle["limits"] == core.BUDGETS, "Wrong Windows bundle") rows = [json.loads(line) for line in read_text(run / "resources.jsonl").splitlines() if line.strip()] start, samples, completions, rejection, result = core.validate_rows(iter(rows), source_revision) mapping = dict(line.split("=", 1) for line in read_text(run / "target-runtime.txt").splitlines() if "=" in line) core.require(mapping.get("targetPid") == str(start["processId"]) and mapping.get("actualExecutable", "").lower().endswith(f"\\app\\{APP}.exe".lower()) and mapping.get("mappedCoreClr", "").lower().endswith("\\app\\coreclr.dll") and mapping.get("coreClrSha256") == bundle["coreClrSha256"], "Published Windows apphost or mapped CLR was not verified for the recorded PID") test_exit = int(read_text(run / "test-exit-status.txt").strip()) core.require((test_exit != 0) == bool(rejection), "Original test exit was not preserved") controls = core.check_trx(run / "results/descriptor-controls.trx", core.DESCRIPTOR_TESTS) workload = core.check_trx(run / "results/late-slope.trx", {core.TEST_NAME}, rejection and rejection["assertionMessage"]) receipt = json.loads(read_text(run / "run-receipt.json")) core.require(receipt["targetVerified"] is True and receipt["testExitStatus"] == test_exit and receipt["leftoverTaskProcesses"] == 0, "Launcher did not verify the target or left processes behind") wall = receipt["wallSeconds"] core.require(start["startupSeconds"] + result["cycleSeconds"] + result["shutdownSeconds"] <= wall, "Startup, cycle and shutdown phases exceed measured wall time") return {"protocol": core.PROTOCOL, "platform": "windows-x64", "sourceRevision": source_revision, "bundleCoreClrSha256": bundle["coreClrSha256"], "diagnosticOutcome": result, "firstColdRejection": rejection, "descriptorTests": controls, "experimentTests": workload, "testExitStatus": test_exit, "wallSeconds": wall, **core.describe(samples, completions)} def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--run", type=Path, required=True) parser.add_argument("--bundle-receipt", type=Path, required=True) parser.add_argument("--source-revision", required=True) options = parser.parse_args() core.require(re.fullmatch(r"[0-9a-f]{40}", options.source_revision), "Invalid revision") try: print(json.dumps(analyze(options.run.resolve(strict=True), options.bundle_receipt, options.source_revision), indent=2, allow_nan=False)) except (OSError, ValueError, KeyError, TypeError) as error: print(f"Incomplete Windows late-slope evidence: {error}", file=sys.stderr) return 1 return 0 if __name__ == "__main__": raise SystemExit(main())