Files
ARCADIA-Studio/harness/experiments/lifecycle-fixture-preflight-20260913/archive.py
T

205 lines
14 KiB
Python

"""Package existing lifecycle preflight evidence. Never run its drivers or binaries."""
import argparse
import hashlib
import json
import re
import subprocess
from datetime import datetime, timezone
from pathlib import Path, PurePosixPath
ARCHIVE = Path("harness/experiments/lifecycle-fixture-preflight-20260913")
SOURCE = Path(".local/nested-lifecycle-native-fixture-20260912")
GATES = Path(".local/allocation-union-20260912")
EXPECTED_FIXTURE = "998a2fd3e2474e72fc013f4da422e49bad61e118de62eccfbd71bf06b863ce7f"
EXPECTED_PROBE = "bf2eb9b908ae36198d15d47ae79d56e4bb181f506598cc4e76a76175041f633e"
LIMITATIONS = [
"Evidence packaging only: no compiler, probe, native app, or original driver was executed.",
"Historical receipts remain verbatim, including preliminary r1 failure and all diagnostics.",
"No executable, DLL, rlib, target artifact, or toolchain is included; identities remain in original receipts.",
"Original receipt commands and PowerShell drivers contain original-local paths and layout assumptions; they are provenance, not portable rerun commands.",
"The original fixture README includes original-local code-path references; its Markdown receipt links resolve within this archive.",
"Full gate manifests and logs document historical source versions, not current palette/native acceptance.",
"110 scoped core/config/lock input bytes are identified by manifests; repository source and full build dependencies are not copied here.",
"No source snapshot was deduplicated or omitted. Small duplicate fixture/probe/driver/receipt files are retained verbatim.",
]
README = """# Lifecycle fixture and preflight evidence
This archive preserves existing evidence; packaging did not rerun a compiler, probe, application, or driver. It does not establish native rendering, interaction, palette, or release acceptance.
Start with the [original fixture README](fixture/README.md), [fixture](fixture/lifecycle-native.arcadia), [identities](fixture/identities.tsv), and [preflight source](fixture/preflight.rs). The original README and every receipt/log/source snapshot are copied byte for byte. Its preparation-stage and later preflight statements retain their original scope.
- [Preliminary r1 receipt](fixture/preliminary-admission-42511f0-r1/run.json): launch failed with -1073741515 (0xC0000135), with empty output. This failure is retained.
- [Preliminary r2 receipt](fixture/preliminary-admission-42511f0-r2/run.json): same identified executable, runtime PATH prefix supplied, exit 0. Self-comparison establishes only the admission checks described in the original README.
- [Strong preflight build](fixture/strong-preflight-d61-r1/build.json), [run](fixture/strong-preflight-d61-r1/run.json), [assertion output](fixture/strong-preflight-d61-r1/run.stdout.log), and [110 scoped inputs](fixture/strong-preflight-d61-r1/verified-core-config-inputs.json): original successful core preflight evidence, not GUI evidence.
- [42511f0 input manifest](provenance/full-42511f0.inputs.json), [result](provenance/full-42511f0.result.json), [log](provenance/full-42511f0.log); [d61 input manifest](provenance/full-d61f1f3.inputs.json), [result](provenance/full-d61f1f3.result.json), [log](provenance/full-d61f1f3.log). These are the historical gates referenced by the preflight driver; they do not verify later desktop changes.
- [Archive manifest](manifest.json) records every included file's original source path, byte count and SHA-256, the excluded executable identity, receipt cross-checks, source identities, limitations, and payload totals. [Packaging/verification helper](archive.py) is the exact helper used to create this archive.
Core oracle source: `42511f0f8ae46f29e11ae18c1030face654c2994`. Closed later core-input comparison gate: `d61f1f38779ab70a77efcde523ae31c432aefcfd`. Strong-preflight recorded current source: `aadc6396d39ff336d05381d58d545093d3f37a73`. The fixture README's target renderer was the reviewed f659 union before later corrections. These are different scopes, not interchangeable tested versions.
All small duplicates are retained, so relative receipt-directory references still resolve. Original absolute command paths, `.local` code references, toolchain paths, and PowerShell `$PSScriptRoot` layout assumptions are **original-local provenance only**. The copied drivers must not be executed directly from this archive: their relative repository-root assumptions no longer hold. No executable/dependency package is included. Native session work/baseline copies and subsequent palette receipts are outside this archive's scope.
From the repository root, use Python 3 with:
```text
python harness/experiments/lifecycle-fixture-preflight-20260913/archive.py verify --root .
python harness/experiments/lifecycle-fixture-preflight-20260913/archive.py verify --root . --check-sources
python harness/experiments/lifecycle-fixture-preflight-20260913/archive.py verify-index --root .
```
`verify` is portable and checks exact file inventory, hashes, sizes, and Markdown links. `--check-sources` additionally compares the original local evidence and therefore needs this original checkout's `.local` files. `verify-index` is optional after staging and compares every archive file, including the manifest, to its exact Git index blob; the helper never stages or commits anything. Creation refuses an existing archive directory.
"""
def identity(data):
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
def git(root, *args):
return subprocess.check_output(["git", "-C", str(root), *args])
def read_json(data):
return json.loads(data.decode("utf-8-sig"))
def safe_path(base, relative):
rel = PurePosixPath(relative)
if rel.is_absolute() or ".." in rel.parts or "\\" in relative:
raise ValueError(f"Unsafe archive path: {relative}")
target = (base / Path(*rel.parts)).resolve()
if not target.is_relative_to(base.resolve()):
raise ValueError(f"Path escapes archive: {relative}")
return target
def verify(root, check_sources=False, index=False):
out = root / ARCHIVE
manifest = read_json((out / "manifest.json").read_bytes())
expected = {item["path"] for item in manifest["files"]} | {"manifest.json"}
actual = {p.relative_to(out).as_posix() for p in out.rglob("*") if p.is_file()}
if actual != expected:
raise ValueError(f"Inventory mismatch: missing={expected-actual}; extra={actual-expected}")
total = 0
for item in manifest["files"]:
path = safe_path(out, item["path"])
if path.is_symlink():
raise ValueError(f"Symlink payload: {path}")
data = path.read_bytes()
if identity(data) != {k: item[k] for k in ("bytes", "sha256")}:
raise ValueError(f"Identity mismatch: {path}")
total += len(data)
if check_sources and item["source_kind"] == "original-local":
if data != safe_path(root, item["source"]).read_bytes():
raise ValueError(f"Original source changed: {item['source']}")
if path.suffix.lower() == ".md":
for link in re.findall(r"\[[^\]]*\]\(([^)]+)\)", data.decode("utf-8-sig")):
if "://" in link or link.startswith("#"):
continue
destination = (path.parent / link.split("#", 1)[0]).resolve()
if not destination.is_relative_to(out.resolve()) or not destination.is_file():
raise ValueError(f"Unresolved Markdown link: {item['path']} -> {link}")
if total != manifest["payload_bytes"] or len(manifest["files"]) != manifest["payload_count"]:
raise ValueError("Manifest totals mismatch")
if check_sources:
for item in manifest["excluded"]:
if identity(safe_path(root, item["source"]).read_bytes()) != {k: item[k] for k in ("bytes", "sha256")}:
raise ValueError(f"Excluded original changed: {item['source']}")
if index:
for path in sorted(expected):
repo_path = (ARCHIVE / path).as_posix()
if git(root, "show", ":" + repo_path) != (out / path).read_bytes():
raise ValueError(f"Index byte mismatch: {repo_path}")
return {"verified": True, "payload_count": len(manifest["files"]), "total_files_including_manifest": len(expected), "payload_bytes": total, "check_sources": check_sources, "check_index": index}
def create(root):
out = root / ARCHIVE
if out.exists():
raise FileExistsError(f"Refuse existing archive: {out}")
sources = sorted((root / SOURCE).rglob("*"))
payload = {}
excluded = []
for path in sources:
if path.is_symlink():
raise ValueError(f"Refuse source symlink: {path}")
if not path.is_file():
continue
data = path.read_bytes()
source = path.relative_to(root).as_posix()
if path.suffix.lower() == ".exe":
excluded.append({"source": source, **identity(data), "reason": "Executable excluded; original build/run identity preserved in receipts."})
else:
relative = (Path("fixture") / path.relative_to(root / SOURCE)).as_posix()
payload[relative] = (data, source, "original-local")
if len(excluded) != 1 or not excluded[0]["source"].endswith("/strong-preflight-d61-r1/lifecycle-preflight.exe"):
raise ValueError("Unexpected binary inventory")
for stem in ("full-42511f0", "full-d61f1f3"):
for suffix in (".inputs.json", ".result.json", ".log"):
path = root / GATES / (stem + suffix)
payload["provenance/" + path.name] = (path.read_bytes(), path.relative_to(root).as_posix(), "original-local")
def data(path):
return payload["fixture/" + path][0]
if identity(data("lifecycle-native.arcadia"))["sha256"] != EXPECTED_FIXTURE:
raise ValueError("Fixture identity differs from reviewed source")
if identity(data("preflight.rs"))["sha256"] != EXPECTED_PROBE:
raise ValueError("Probe identity differs from reviewed source")
r1 = read_json(data("preliminary-admission-42511f0-r1/run.json"))
r2 = read_json(data("preliminary-admission-42511f0-r2/run.json"))
strong = read_json(data("strong-preflight-d61-r1/run.json"))
build = read_json(data("strong-preflight-d61-r1/build.json"))
if (r1["exit"], r2["exit"], strong["exit"], build["exit"]) != (-1073741515, 0, 0, 0):
raise ValueError("Unexpected historical receipt outcomes")
if excluded[0]["sha256"] != strong["binary_sha256"]:
raise ValueError("Excluded executable identity mismatch")
checks = []
for folder, receipt, prefix in (("preliminary-admission-42511f0-r1", r1, ""), ("preliminary-admission-42511f0-r2", r2, ""), ("strong-preflight-d61-r1", strong, "run.")):
for stream in ("stdout", "stderr"):
name = folder + "/" + prefix + stream + ".log"
if identity(data(name))["sha256"] != receipt[stream + "_sha256"]:
raise ValueError(f"Receipt/log mismatch: {name}")
checks.append(name)
for snapshot in ("preliminary-admission-42511f0-r1/fixture-source.arcadia.txt", "strong-preflight-d61-r1/fixture-source.arcadia.txt"):
if data(snapshot) != data("lifecycle-native.arcadia"):
raise ValueError(f"Fixture snapshot differs: {snapshot}")
if data("strong-preflight-d61-r1/preflight-source.rs") != data("preflight.rs"):
raise ValueError("Probe snapshot mismatch")
if data("strong-preflight-d61-r1/run-driver.ps1") != data("run-preflight-d61-r1.ps1"):
raise ValueError("Driver snapshot mismatch")
scoped = read_json(data("strong-preflight-d61-r1/verified-core-config-inputs.json"))
if len(scoped) != 110:
raise ValueError("Scoped input count mismatch")
for stem in ("full-42511f0", "full-d61f1f3"):
inputs = read_json(payload["provenance/" + stem + ".inputs.json"][0])["inputs"]
indexed = {item["path"]: item for item in inputs}
for item in scoped:
if any(indexed[item["path"]][key] != item[key] for key in ("bytes", "sha256")):
raise ValueError(f"Scoped input disagreement: {stem} {item['path']}")
payload["README.md"] = (README.encode("utf-8"), "generated archive navigation and limitations", "generated")
payload["archive.py"] = (Path(__file__).read_bytes(), Path(__file__).resolve().relative_to(root).as_posix(), "original-local")
files = [{"path": path, "source": source, "source_kind": kind, **identity(blob)} for path, (blob, source, kind) in sorted(payload.items())]
manifest = {"schema": 1, "created_utc": datetime.now(timezone.utc).isoformat(), "scope": "Historical lifecycle fixture/core preflight packaging only", "archive": ARCHIVE.as_posix(), "source_root": SOURCE.as_posix(), "packaging_checkout_head": git(root, "rev-parse", "HEAD").decode().strip(), "historical_sources": {"oracle_core": r1["core_source"], "comparison_gate": build["full_gate_source"], "strong_preflight_recorded_head": build["current_head"]}, "receipt_exits": {"preliminary_r1": r1["exit"], "preliminary_r2": r2["exit"], "strong_build": build["exit"], "strong_run": strong["exit"]}, "cross_checks": {"receipt_log_hashes": checks, "scoped_inputs_matching_both_full_manifests": len(scoped), "fixture_probe_driver_duplicate_snapshots": "equal and preserved"}, "limitations": LIMITATIONS, "excluded": excluded, "payload_count": len(files), "payload_bytes": sum(item["bytes"] for item in files), "files": files}
out.mkdir(parents=True, exist_ok=False)
for path, (blob, _, _) in sorted(payload.items()):
target = safe_path(out, path)
target.parent.mkdir(parents=True, exist_ok=True)
with target.open("xb") as stream:
stream.write(blob)
with (out / "manifest.json").open("xb") as stream:
stream.write((json.dumps(manifest, ensure_ascii=False, indent=2) + "\n").encode("utf-8"))
return verify(root, check_sources=True)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("mode", choices=("create", "verify", "verify-index"))
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--check-sources", action="store_true")
args = parser.parse_args()
root = args.root.resolve()
result = create(root) if args.mode == "create" else verify(root, args.check_sources, args.mode == "verify-index")
print(json.dumps(result, indent=2))
if __name__ == "__main__":
main()