docs: publish Process multiselect verification and native correction evidence

This commit is contained in:
2026-09-23 06:51:41 -07:00
parent b743a10d51
commit 6d99aacab8
48 changed files with 4921 additions and 0 deletions
@@ -0,0 +1,48 @@
# Portable Process native receipts
Adapted from the State native evidence package. Python standard library only;
neither preparation nor verification runs any GUI, checker, archived helper or binary.
From a checkout, validate explicit closed runs:
```text
python -B prepare.py --root C:/ar-multiselect-9e8r6t --runs run-1 --check-only
python -B prepare.py --root C:/ar-multiselect-9e8r6t --runs run-1 run-2 --output FRESH_DIRECTORY
python -B FRESH_DIRECTORY/verify.py
```
The output directory must not exist. Run-2 is an example, usable only after its
finished.json exists. Explicit names prevent accidental capture of a live run.
No run is automatically accepted. Run-1 always retains `reviewStatus: failed`:
Back exposed the outer reference's editable Properties while highlighting the
qualified tile; reorder and history were not performed. Later runs are
`unreviewed` by this tool even if independently accepted in the parent's report.
The archive retains every run file byte, exact prepared helpers (including
common.py and README.md), the actual capture-executed.js separately, complete
fixture/working/snapshot source, screenshots and accessibility JSON, logs,
normal-exit/closure flags, and history-bytes.json when present. The executed
capture function is preserved and package-pinned; the preparation receipt does
not authenticate it as the same bytes as the prepared capture.js template.
Both GUI and checker build raw receipts, process/start metadata, logs, complete
input maps and source ZIPs are archived. Source maps/ZIPs are deduplicated by
exact hash. The historical checker source is also directly available. Helpers
must match recorded pins; use repeated `--helper PATH` for unavailable historical
versions. Never rewrite original capture helpers to make pins pass.
Verification checks safe unique ZIP paths and JSON keys, all member hashes,
reference closure, lifecycle/time relationships, exact prepared helpers,
source-map equality, every source-capsule byte, executable receipt identity,
artifact membership in raw Cargo output, all snapshot reports, and literal
history bytes if present. Nonzero native/checker exits are retained as data;
missing closure or inconsistent receipts refuse packaging. A successful receipt
consistency check is not a claim that native interactions succeeded.
The verifier does not authenticate authorship, independently replay the checker,
interpret screenshot contents, verify pixel dimensions, infer click/drag/focus
actions, prove one-step history, or establish usability/native acceptance. Input
hashes establish recorded consistency, not a reproducible-build proof. Binaries
are identified by build readback pins and native receipts, not included or run.
Independent parent review remains necessary. Failed checker output is preserved
verbatim and not required to be a positive JSON report.
@@ -0,0 +1,22 @@
{
"prepare.py": {
"bytes": 6712,
"sha256": "d6b265b0047e9e0f8d67b71a9208b0467cd12b0470690713bfce6e3ceba6e0d3"
},
"verify.py": {
"bytes": 16518,
"sha256": "035e2e3eacdfb4205e6560fa85befbe65bbc2d20c5c8a42a11e4a965131ed0e4"
},
"README.md": {
"bytes": 2857,
"sha256": "57d447f984fd8dccc1e93fdb7b493bbb9e76a081b2a0a2d28689da86c0d61ce4"
},
"manifest.json": {
"bytes": 80265,
"sha256": "7bd4fa9247941d17939de989501b66c0d5d04f222424fb092c00f52f765b5bca"
},
"evidence.zip": {
"bytes": 12355442,
"sha256": "e94c3e9f2fb644c8e415e09b75eaf973d9c2a93534ad9e41d69793a3c11e8f88"
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,115 @@
"""Package explicitly named closed Process native runs; never execute archived helpers."""
from pathlib import Path
import argparse
import io
import json
import re
import zipfile
from verify import pin, parsed, need, norm, relative, safe, zip_inventory, verify_data, verify_package
HERE = Path(__file__).resolve().parent
FAILED_RUN_ONE = "Observed Back restored qualified highlight with outer-reference editable Properties; reorder and Undo/Redo/reopen history were not performed. Failed native workflow, despite three positive unchanged Project reports."
def collect(root, runs, extra_helpers=()):
native = root / ".local/process-multiselect-native"
candidates = [p for p in native.iterdir() if p.is_file()]
candidates += sorted((root / ".local/process-group-gates").glob("*.py"))
candidates += list(extra_helpers)
helpers = [(p.suffix, p.read_bytes()) for p in candidates]
payload, specs = {}, {}
def add(name, data):
need(safe(name) and (name not in payload or payload[name] == data), "member collision: " + name)
payload[name] = data
return name
def helper(expected):
matches = [(suffix, data) for suffix, data in helpers if pin(data) == expected]
need(matches, "exact historical helper unavailable: " + str(expected))
suffix, data = matches[0]
return add("helpers/" + expected["sha256"] + suffix, data)
def tree(folder, prefix):
need(folder.is_dir(), "missing directory: " + str(folder))
for path in sorted(folder.rglob("*")):
need(not path.is_symlink() and not getattr(path, "is_junction", lambda: False)(), "linked evidence input")
if path.is_file():
add(prefix + path.relative_to(folder).as_posix(), path.read_bytes())
for run in runs:
folder = native / run
need((folder / "finished.json").is_file(), "open/unlaunched run refused: " + run)
prepared = parsed((folder / "prepared.json").read_bytes())
tree(folder, "runs/" + run + "/raw/")
spec = {"originalRun": norm(prepared["cwd"]) + "/.local/process-multiselect-native/" + run,
"reviewStatus": "failed" if run == "run-1" else "unreviewed",
"reviewNote": FAILED_RUN_ONE if run == "run-1" else "Packaging consistency does not decide native acceptance. Consult the independent parent review.",
"helpers": {name: helper(expected) for name, expected in prepared["helpers"].items()},
"executedCapture": pin((folder / "capture-executed.js").read_bytes()), "builds": {}}
for kind in ("gui", "checker"):
recorded = prepared[kind]
rel = relative(recorded["receipt"], prepared["cwd"])
need(rel.startswith(".local/process-group-gates/") and rel.endswith("/result.json"), "unexpected receipt location")
receipt = root / rel
result_data = receipt.read_bytes()
need(pin(result_data) == recorded["receiptPin"], "historical build receipt changed")
result = parsed(result_data)
prefix = "builds/" + pin(result_data)["sha256"] + "/"
build = {"originalRelative": rel, "helper": helper(result["helper"])}
for name in ("started.json", "process.json", "result.json", "stdout.log", "stderr.log", "inputs.json", "inputs.zip"):
data = (receipt.parent / name).read_bytes()
# Deduplicate source capsules independently of differing build receipts.
member = ("inputs/" + pin(data)["sha256"] + Path(name).suffix) if name.startswith("inputs.") else prefix + name
build[name] = add(member, data)
spec["builds"][kind] = build
if kind == "checker":
capsule = payload[build["inputs.zip"]]
need(pin(capsule) == result["archive"], "historical checker capsule pin")
inputs = parsed(payload[build["inputs.json"]])
with zipfile.ZipFile(io.BytesIO(capsule)) as archive:
zip_inventory(archive, inputs)
source = archive.read("crates/oa-core/examples/process_multiselect_native.rs")
spec["checkerSource"] = add("checker-source/" + pin(source)["sha256"] + ".rs", source)
specs[run] = spec
manifest = {"schema": 1, "kind": "process-multiselect-native", "runs": specs,
"members": {name: pin(data) for name, data in sorted(payload.items())}}
return payload, manifest, verify_data(manifest, payload.__getitem__)
def write_json(path, value):
with path.open("xb") as stream:
stream.write((json.dumps(value, indent=2) + "\n").encode())
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, required=True)
parser.add_argument("--runs", nargs="+", required=True)
parser.add_argument("--output", type=Path)
parser.add_argument("--check-only", action="store_true")
parser.add_argument("--helper", type=Path, action="append", default=[], help="Exact historical helper bytes if current helper changed")
args = parser.parse_args()
need(len(args.runs) == len(set(args.runs)) and all(re.fullmatch(r"run-[0-9]+", name) for name in args.runs), "explicit unique run-N names required")
need(args.check_only or args.output is not None, "--output or --check-only required")
if args.output is not None:
need(not args.output.exists(), "fresh nonexistent output directory required")
payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper)
if args.check_only:
print("PASS raw consistency; no archive written:", summary)
return
out = args.output.resolve()
out.mkdir(parents=True, exist_ok=False)
for name in ("prepare.py", "verify.py", "README.md"):
with (out / name).open("xb") as stream:
stream.write((HERE / name).read_bytes())
with zipfile.ZipFile(out / "evidence.zip", "x", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive:
for name, data in sorted(payload.items()):
info = zipfile.ZipInfo(name, date_time=(2026, 9, 23, 0, 0, 0))
info.compress_type = zipfile.ZIP_DEFLATED
info.external_attr = 0o100644 << 16
archive.writestr(info, data)
write_json(out / "manifest.json", manifest)
write_json(out / "files.json", {name: pin((out / name).read_bytes()) for name in ("prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip")})
need(verify_package(out) == summary, "written package differs from raw evidence")
print("PASS package readback:", out, summary)
if __name__ == "__main__":
main()
@@ -0,0 +1,229 @@
"""Verify archived native receipts and bytes; do not rerun the GUI or checker."""
from pathlib import Path, PurePosixPath
from datetime import datetime
import argparse
import hashlib
import json
import io
import re
import stat
import zipfile
BASE = {"prepared.json", "started.json", "finished.json", "generation.json", "generation.stdout.log",
"generation.stderr.log", "app.stdout.log", "app.stderr.log", "capture-executed.js"}
OUTER = {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"}
def need(ok, message):
if not ok:
raise ValueError(message)
def pin(data):
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
def safe(name):
return (isinstance(name, str) and bool(name) and "\\" not in name and ":" not in name
and not PurePosixPath(name).is_absolute() and all(ord(c) >= 32 for c in name)
and all(part not in ("", ".", "..") for part in name.split("/")))
def parsed(data):
def unique(items):
result = {}
for key, value in items:
need(key not in result, "duplicate JSON key: " + key)
result[key] = value
return result
return json.loads(data, object_pairs_hook=unique)
def norm(path):
return path.replace("\\", "/").rstrip("/")
def relative(path, root):
prefix = norm(root) + "/"
need(norm(path).startswith(prefix), "recorded path outside owner: " + path)
value = norm(path)[len(prefix):]
need(safe(value), "unsafe recorded relative path")
return value
def ordered(*values):
times = [datetime.fromisoformat(value) for value in values]
return all(t.utcoffset() is not None for t in times) and times == sorted(times)
def zip_inventory(archive, members):
names = archive.namelist()
need(len(names) == len(set(names)) and set(names) == set(members), "exact archive members")
for info in archive.infolist():
need(safe(info.filename) and not info.is_dir() and not stat.S_ISLNK(info.external_attr >> 16), "unsafe archive member")
need(info.file_size == members[info.filename]["bytes"], "archive member size")
def verify_data(manifest, read):
need(manifest["schema"] == 1 and manifest["kind"] == "process-multiselect-native", "manifest kind")
members, runs = manifest["members"], manifest["runs"]
need(bool(runs) and all(re.fullmatch(r"run-[0-9]+", run) for run in runs), "run names")
need(all(safe(name) for name in members), "safe member names")
for name, expected in members.items():
need(pin(read(name)) == expected, "member pin: " + name)
used, summaries = set(), {}
def raw(name):
need(name in members, "missing member: " + name)
used.add(name)
return read(name)
def obj(name):
return parsed(raw(name))
def tree(prefix):
return {name[len(prefix):]: raw(name) for name in members if name.startswith(prefix)}
def pinned_tree(prefix, expected):
actual = tree(prefix)
need({name: pin(data) for name, data in actual.items()} == expected, "pinned tree: " + prefix)
return actual
for run, spec in runs.items():
prefix = "runs/" + run + "/raw/"
prepared, start, end, generation = [obj(prefix + n + ".json") for n in ("prepared", "started", "finished", "generation")]
need(spec["reviewStatus"] in ("failed", "unreviewed") and isinstance(spec["reviewNote"], str) and spec["reviewNote"], "explicit non-acceptance status")
if run == "run-1":
need(spec["reviewStatus"] == "failed", "run-1 must retain observed native failure")
origin = norm(prepared["cwd"]) + "/.local/process-multiselect-native/" + run
need(spec["originalRun"] == origin and prepared["run"] == run and start["cwd"] == prepared["cwd"], "original run mapping")
need(start["prepared"] == pin(raw(prefix + "prepared.json")), "launch preparation pin")
need(ordered(generation["start"], generation["finish"], prepared["prepared"], start["start"], end["finish"]), "native lifetime")
need(type(start["pid"]) is int and start["pid"] > 0 and type(end["exitCode"]) is int, "closed native process")
for key in ("guiUnchanged", "checkerUnchanged", "fixtureUnchanged"):
need(type(end[key]) is bool, "closure flag")
need(start["gui"] == prepared["gui"] and start["checker"] == prepared["checker"] == generation["checker"], "binary identity")
need(start["command"] == [prepared["gui"]["binary"]], "GUI command")
need(generation["exitCode"] == 0 and generation["command"][:2] == [prepared["checker"]["binary"], "generate"] and len(generation["command"]) == 3 and norm(generation["command"][2]) == origin + "/fixture", "generation command")
for stream in ("stdout", "stderr"):
need(end[stream] == pin(raw(prefix + "app." + stream + ".log")), "GUI log pin")
need(generation[stream] == pin(raw(prefix + "generation." + stream + ".log")), "generation log pin")
need(set(spec["helpers"]) == set(prepared["helpers"]), "exact prepared helper mapping")
for name, expected in prepared["helpers"].items():
need(safe(name) and "/" not in name and pin(raw(spec["helpers"][name])) == expected, "historical helper: " + name)
need(start["helper"] == prepared["helpers"]["native.py"], "launch helper")
need(pin(raw(prefix + "capture-executed.js")) == spec["executedCapture"], "actual capture function pin")
fixture = pinned_tree(prefix + "fixture/", prepared["fixture"])
fm = parsed(fixture["manifest.json"])
need(fm["fixture"] == "process-multiselect-native-20260923" and fm["source_entry"] == prepared["entry"] and safe(prepared["entry"]), "fixture identity/entry")
need(parsed(fixture["baseline.json"])["id"] == fm["ids"]["project"], "complete Project baseline identity")
fixture_source = {name[7:]: data for name, data in fixture.items() if name.startswith("source/")}
need(prepared["entry"] in fixture_source and norm(prepared["workingEntry"]) == origin + "/working/" + prepared["entry"], "working entry mapping")
working = tree(prefix + "working/")
need(bool(working) and all(name.endswith(".arcadia") for name in working), "saved working tree")
build_maps = {}
for kind, target in (("gui", "arcadia-studio"), ("checker", "process_multiselect_native")):
recorded, b = prepared[kind], spec["builds"][kind]
result, began, process = [obj(b[n]) for n in ("result.json", "started.json", "process.json")]
need(pin(raw(b["result.json"])) == recorded["receiptPin"] and relative(recorded["receipt"], prepared["cwd"]) == b["originalRelative"], "build receipt mapping")
need(all(result.get(k) == v for k, v in began.items()) and process["command"] == result["command"] and type(process["pid"]) is int and process["pid"] > 0, "build start/result/process")
need(result["exitCode"] == 0 and result["inputsUnchanged"] is True and ordered(result["start"], process["observed"], result["finish"], generation["start"]), "successful preceding build")
for stream in ("stdout", "stderr"):
need(pin(raw(b[stream + ".log"])) == result[stream], "build log pin")
need(pin(raw(b["helper"])) == result["helper"], "build helper pin")
need(pin(raw(b["inputs.json"])) == recorded["inputs"] == result["inputs"], "build source map pin")
inputs = obj(b["inputs.json"])
need(len(inputs) == result["inputCount"] and all(safe(name) for name in inputs), "source map count/paths")
capsule = raw(b["inputs.zip"])
need(pin(capsule) == result["archive"], "build source capsule pin")
with zipfile.ZipFile(io.BytesIO(capsule)) as archive:
zip_inventory(archive, inputs)
need(all(pin(archive.read(name)) == expected for name, expected in inputs.items()), "all captured source bytes")
if kind == "checker":
path = "crates/oa-core/examples/process_multiselect_native.rs"
need(raw(spec["checkerSource"]) == archive.read(path), "historical checker source")
artifacts = [row for row in result["artifacts"] if row["cargo"]["target"]["name"] == target]
need(len(artifacts) == 1 and artifacts[0]["readback"] == recorded["pin"] and artifacts[0]["cargo"]["executable"] == recorded["binary"] and artifacts[0]["cargo"]["profile"]["test"] is False, "native executable provenance")
stdout_rows = [parsed(line) for line in raw(b["stdout.log"]).splitlines() if line.strip().startswith(b"{")]
need(artifacts[0]["cargo"] in stdout_rows, "artifact appears in raw Cargo output")
build_maps[kind] = inputs
need(prepared["gui"]["inputs"] == prepared["checker"]["inputs"] and build_maps["gui"] == build_maps["checker"], "same GUI/checker source map")
top = {name[len(prefix):] for name in members if name.startswith(prefix) and "/" not in name[len(prefix):]}
base = BASE | (top & {"history-bytes.json", "observations.md"})
if "observations.md" in top:
raw(prefix + "observations.md")
captures = sorted(name for name in top - base if name.endswith(".json"))
need(captures, "native captures required")
expected_top = base | set(captures)
for name in captures:
capture = obj(prefix + name)
need(ordered(start["start"], capture["time"], end["finish"]), "capture lifetime")
window = capture["window"]
need(norm(window["app"]) == "process:" + norm(prepared["gui"]["binary"]) and type(window["id"]) is int and window["id"] > 0, "captured executable/window")
need(isinstance(capture["accessibility"], dict) and isinstance(capture["images"], list), "accessibility/capture payload")
for image in capture["images"]:
filename = image["file"]
need(safe(filename) and "/" not in filename and filename.startswith(name[:-5] + "-") and filename.endswith((".jpg", ".png")) and filename not in expected_top, "unique image mapping")
need(all(type(image[k]) is int and image[k] > 0 for k in ("width", "height")), "image dimensions")
expected_top.add(filename)
data = raw(prefix + filename)
need(data.startswith(b"\xff\xd8") if filename.endswith(".jpg") else data.startswith(b"\x89PNG\r\n\x1a\n"), "image signature")
need(top == expected_top, "exact top-level run files")
labels = {name[len(prefix + "snapshots/"):].split("/")[0] for name in members if name.startswith(prefix + "snapshots/")}
states, results, positive = {}, {}, []
for label in sorted(labels):
need(re.fullmatch(r"[a-z0-9-]+", label), "snapshot label")
folder = prefix + "snapshots/" + label + "/"
began, result = obj(folder + "started.json"), obj(folder + "result.json")
need(all(result.get(k) == v for k, v in began.items()), "snapshot start/result")
need(result["prepared"] == start["prepared"] and result["checker"] == prepared["checker"] and result["helper"] == prepared["helpers"]["snapshot.py"], "snapshot provenance")
need(ordered(start["start"], result["start"], result["finish"], end["finish"]), "snapshot lifetime")
mode, command = result["mode"], result["command"]
need(mode in ("unchanged", "reordered") and len(command) == 5 and command[:3] == [prepared["checker"]["binary"], "check", mode] and norm(command[3]) == origin + "/fixture/baseline.json" and norm(command[4]) == origin + "/snapshots/" + label + "/source/" + prepared["entry"], "snapshot command")
need(result["baseline"] == pin(fixture["baseline.json"]), "snapshot baseline")
for stream in ("stdout", "stderr"):
need(result[stream] == pin(raw(folder + stream + ".log")), "snapshot log pin")
need(type(result["exitCode"]) is int and all(type(result[k]) is bool for k in ("binaryUnchanged", "workingSourceUnchanged", "snapshotUnchanged", "baselineUnchanged")), "snapshot closure")
states[label] = pinned_tree(folder + "source/", result["source"])
need({name for name in members if name.startswith(folder)} == {folder + n for n in ("started.json", "result.json", "stdout.log", "stderr.log")} | {folder + "source/" + n for n in states[label]}, "exact snapshot files")
if result["exitCode"] == 0:
report = obj(folder + "stdout.log")
need(report["result"] == "PASS" and report["comparison"] == "complete Project equality; literal expected order" and report["mode"] == mode and report["baseline"] == command[3] and report["saved"] == command[4], "positive complete Project report")
positive.append(label)
results[label] = result
history_present = "history-bytes.json" in top
if history_present:
history = obj(prefix + "history-bytes.json")
groups = history["equalByteGroups"]
need(len(groups) == 2 and groups[0][:2] == ["baseline", "undo"] and groups[1] == ["reordered", "redo", "reopened"], "literal Process history groups")
history_labels = [label for group in groups for label in group]
need(len(history_labels) == len(set(history_labels)) and set(history_labels) == set(history["snapshots"]) and set(history_labels) <= set(positive), "history labels/positive reports")
need(history["status"] == "PASS" and history["prepared"] == start["prepared"] and history["helper"] == prepared["helpers"]["history-bytes.py"] and ordered(end["finish"], history["verified"]), "history provenance")
need(end["exitCode"] == 0 and all(end[k] is True for k in ("guiUnchanged", "checkerUnchanged", "fixtureUnchanged")), "history clean closure")
for group, mode in zip(groups, ("unchanged", "reordered")):
for label in group:
need(states[label] == states[group[0]] and results[label]["mode"] == mode and history["snapshots"][label] == pin(raw(prefix + "snapshots/" + label + "/result.json")), "literal history bytes/receipt")
need(all(results[label][k] is True for k in ("binaryUnchanged", "workingSourceUnchanged", "snapshotUnchanged", "baselineUnchanged")), "stable history snapshot")
need(len(states[label]) == history["sourceFilesPerSnapshot"], "history source count")
need(states["baseline"] == fixture_source and states["baseline"] != states["reordered"], "baseline exact and reorder changed")
changed = sorted(name for name in set(states["baseline"]) | set(states["reordered"]) if states["baseline"].get(name) != states["reordered"].get(name))
need(changed == history["changedFilesFromBaseline"] == ["oa/behavior/process_oa_process.arcadia"], "only intended OA source changed")
sequence = [results[label] for label in ("baseline", "reordered", "undo", "redo", "reopened")]
need(all(ordered(a["finish"], b["start"]) for a, b in zip(sequence, sequence[1:])), "history chronology")
summaries[run] = {"reviewStatus": spec["reviewStatus"], "exitCode": end["exitCode"], "captures": len(captures), "snapshots": len(labels), "positiveReports": len(positive), "historyBytes": history_present}
need(used == set(members), "unreferenced package members: " + repr(set(members) - used))
return summaries
def verify_package(root):
files = parsed((root / "files.json").read_bytes())
need(set(files) == OUTER, "outer files")
for name, expected in files.items():
need(pin((root / name).read_bytes()) == expected, "outer pin: " + name)
manifest = parsed((root / "manifest.json").read_bytes())
with zipfile.ZipFile(root / "evidence.zip") as archive:
zip_inventory(archive, manifest["members"])
return verify_data(manifest, archive.read)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("package", nargs="?", type=Path, default=Path(__file__).resolve().parent)
args = parser.parse_args()
print("PASS byte/receipt consistency only:", verify_package(args.package))
print("No GUI/checker execution or native acceptance claim; see independent parent review.")