diff --git a/harness/experiments/transition-lifecycle-20260913/README.md b/harness/experiments/transition-lifecycle-20260913/README.md new file mode 100644 index 00000000..2d7525ec --- /dev/null +++ b/harness/experiments/transition-lifecycle-20260913/README.md @@ -0,0 +1,51 @@ +# Transition lifecycle: closed-gate evidence + +Closed Cargo-gate checkpoint with eight runs. Native work remains separate. +Run `python verify.py` using +Python 3.10 or newer. The five package files are sufficient; no archived code, +binary, Git command or network operation is executed by verification. + +Raw logs/receipts preserve the initial lifecycle-1 fixture admission failure as +a distinct input state. Successful core-transition-2, desktop-workflow-1 and +core-workflows-1 inputs are bound to +acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8 by an independent local comparison of +all 710 captured input hashes with exact committed bytes using Git cat-file. +The readback summary records Git blob identities; its raw Git stream is not +archived. Offline verification checks those blob hashes and input relationships, +not authenticated membership of a remote commit. Receipt HEADs may precede dirty +changes, so per-run input manifests are authoritative for tested source bytes. + +Strict all-target workspace Clippy passed on those tested inputs. The first +format check failed only on an inherited tuple layout in diagram/focus.rs; +the raw failure is retained. Commit d46854c2dc719bb8b44a0978102de44ecc3a6b39 +reformats that tuple and the second format check passes. Its separate 710-input +inventory is independently compared with that commit; per-run inputCommit +bindings and formattingInputChanges distinguish these source states. Earlier +execution and lint results are not represented as reruns on the formatted +commit. No application behavior change is claimed from formatting evidence. +The Windows workspace build completed on d46854c with the same 710 unchanged +inputs as format-2 and three executable artifact receipts. Those recorded +artifacts identify CLI, server and desktop binaries; binaries are not packaged. + +| Gate | Recorded outcome | +| --- | --- | +| lifecycle-1 | Initial fixture admission failed: 6 failures | +| core-transition-2 | 10 passed | +| desktop-workflow-1 | 25 passed, 1,164 filtered out | +| core-workflows-1 | 28 passed | +| clippy-1 | Strict workspace/all-target lint passed | +| format-1 | Initial tuple-format check failed | +| format-2 | Format check passed with empty streams | +| windows-build-1 | Build passed; three executable artifact records | + +The manifest maps each run to exact manifests and archives; only byte-identical +input objects are deduplicated. Verification checks safe exact ZIP membership, +hashes/lengths, source inventory and contents, 71 vendored iced_widget files, +helper/start/process/result relationships, time order, commands, exit outcomes, +unchanged input assertions, exact test summary rows and artifact receipt records. +Outer text uses UTF-8 LF before pinning; inner bytes remain raw. + +This is process evidence and internal consistency, not a test rerun, proof of +complete coverage, native acceptance or release readiness. Binaries, dependency +caches and credentials are excluded; artifact readback hashes are historical +observations, not independently verified binaries. diff --git a/harness/experiments/transition-lifecycle-20260913/evidence.zip b/harness/experiments/transition-lifecycle-20260913/evidence.zip new file mode 100644 index 00000000..0a8c2194 Binary files /dev/null and b/harness/experiments/transition-lifecycle-20260913/evidence.zip differ diff --git a/harness/experiments/transition-lifecycle-20260913/files.json b/harness/experiments/transition-lifecycle-20260913/files.json new file mode 100644 index 00000000..11c3d37b --- /dev/null +++ b/harness/experiments/transition-lifecycle-20260913/files.json @@ -0,0 +1,18 @@ +{ + "evidence.zip": { + "bytes": 8496343, + "sha256": "5f44ad5d83024a04a873142e77c5b8961c278a19d76492618c3ef2db63801070" + }, + "manifest.json": { + "bytes": 14323, + "sha256": "7d48cb7e0788fb409b196f8be94c5947b30c698219bd016141fec136dbce3148" + }, + "README.md": { + "bytes": 3017, + "sha256": "7946dd1317e326a6319c8e6399a6177ce251c6c8bc6c6c9cc7eac1517130d2db" + }, + "verify.py": { + "bytes": 8239, + "sha256": "13cd285e8c5331bc9b1b7ada1ee7d3ebce4135570e45c047fb56c2f66b558700" + } +} diff --git a/harness/experiments/transition-lifecycle-20260913/manifest.json b/harness/experiments/transition-lifecycle-20260913/manifest.json new file mode 100644 index 00000000..93bc37db --- /dev/null +++ b/harness/experiments/transition-lifecycle-20260913/manifest.json @@ -0,0 +1,477 @@ +{ + "schema": 1, + "testedSourceCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "formattedSourceCommit": "d46854c2dc719bb8b44a0978102de44ecc3a6b39", + "runs": { + "lifecycle-1": { + "command": [ + "cargo", + "test", + "--locked", + "--offline", + "-p", + "oa-core", + "--test", + "transition_lifecycle", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "3f9e6a18af96b5cd10940da4093be8da28b9c835", + "exitCode": 101, + "inputCount": 708, + "kind": "cargo", + "inputs": "inputs/c637fea08bdfad17a86c335b58f79666a22b677174a84e817300451a11260a7a.json", + "archive": "inputs/6f54f538a71dfcd81cfe1309e6fa338f27f6e844f2f315983ef3556134e3eaf6.zip", + "testRows": [ + [ + 0, + 6, + 0, + 0, + 0 + ] + ], + "testTotals": [ + 0, + 6, + 0, + 0, + 0 + ] + }, + "core-transition-2": { + "command": [ + "cargo", + "test", + "--locked", + "--offline", + "-p", + "oa-core", + "--test", + "transition_lifecycle", + "--test", + "transition_counterpart_compatibility", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "3f9e6a18af96b5cd10940da4093be8da28b9c835", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json", + "archive": "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip", + "inputCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "testRows": [ + [ + 4, + 0, + 0, + 0, + 0 + ], + [ + 6, + 0, + 0, + 0, + 0 + ] + ], + "testTotals": [ + 10, + 0, + 0, + 0, + 0 + ] + }, + "desktop-workflow-1": { + "command": [ + "cargo", + "test", + "--locked", + "--offline", + "-p", + "oa-desktop", + "--bin", + "arcadia-studio", + "--message-format=json", + "workflow::", + "--", + "--nocapture" + ], + "head": "3f9e6a18af96b5cd10940da4093be8da28b9c835", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json", + "archive": "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip", + "inputCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "testRows": [ + [ + 25, + 0, + 0, + 0, + 1164 + ] + ], + "testTotals": [ + 25, + 0, + 0, + 0, + 1164 + ] + }, + "core-workflows-1": { + "command": [ + "cargo", + "test", + "--locked", + "--offline", + "-p", + "oa-core", + "--test", + "workflows", + "--message-format=json", + "--", + "--nocapture" + ], + "head": "3f9e6a18af96b5cd10940da4093be8da28b9c835", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json", + "archive": "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip", + "inputCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "testRows": [ + [ + 28, + 0, + 0, + 0, + 0 + ] + ], + "testTotals": [ + 28, + 0, + 0, + 0, + 0 + ] + }, + "clippy-1": { + "command": [ + "cargo", + "clippy", + "--locked", + "--offline", + "--workspace", + "--all-targets", + "--message-format=json", + "--", + "-D", + "warnings" + ], + "head": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json", + "archive": "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip", + "inputCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "testRows": [], + "testTotals": [ + 0, + 0, + 0, + 0, + 0 + ] + }, + "format-1": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "exitCode": 1, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json", + "archive": "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip", + "inputCommit": "acbfb6cc929cb08b599b2e8ccf4d6752e63b84a8", + "testRows": [], + "testTotals": [ + 0, + 0, + 0, + 0, + 0 + ] + }, + "format-2": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "d46854c2dc719bb8b44a0978102de44ecc3a6b39", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/feb3e7ff11a74571fcfe290016131165d7be82e83b8e4a4daae1667e8a9feb3c.json", + "archive": "inputs/00a630ff5d3aa838a3d6ba582f3e54ce12fe45ab52569f4da2cc583be1b1f802.zip", + "inputCommit": "d46854c2dc719bb8b44a0978102de44ecc3a6b39", + "testRows": [], + "testTotals": [ + 0, + 0, + 0, + 0, + 0 + ] + }, + "windows-build-1": { + "command": [ + "cargo", + "build", + "--locked", + "--offline", + "--workspace", + "--bins", + "--message-format=json" + ], + "head": "d46854c2dc719bb8b44a0978102de44ecc3a6b39", + "exitCode": 0, + "inputCount": 710, + "kind": "cargo", + "inputs": "inputs/feb3e7ff11a74571fcfe290016131165d7be82e83b8e4a4daae1667e8a9feb3c.json", + "archive": "inputs/00a630ff5d3aa838a3d6ba582f3e54ce12fe45ab52569f4da2cc583be1b1f802.zip", + "inputCommit": "d46854c2dc719bb8b44a0978102de44ecc3a6b39", + "testRows": [], + "testTotals": [ + 0, + 0, + 0, + 0, + 0 + ] + } + }, + "members": { + "helpers/commit-readbacks.json": { + "bytes": 149015, + "sha256": "d78b2c4182f2b1db7413cc3eaa36614ade32686e520d6e565bab959b36067838" + }, + "helpers/gate-transition.py": { + "bytes": 3500, + "sha256": "065a752452e297ba8a000ee69cfae3996b4e6df9b4edbe002f233a66c32e1c04" + }, + "inputs/00a630ff5d3aa838a3d6ba582f3e54ce12fe45ab52569f4da2cc583be1b1f802.zip": { + "bytes": 2843714, + "sha256": "00a630ff5d3aa838a3d6ba582f3e54ce12fe45ab52569f4da2cc583be1b1f802" + }, + "inputs/65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26.json": { + "bytes": 118907, + "sha256": "65138ba4ac5843e411a068a8309dfe62c0c4186579aec9e755f6decbed8ecc26" + }, + "inputs/6f54f538a71dfcd81cfe1309e6fa338f27f6e844f2f315983ef3556134e3eaf6.zip": { + "bytes": 2836501, + "sha256": "6f54f538a71dfcd81cfe1309e6fa338f27f6e844f2f315983ef3556134e3eaf6" + }, + "inputs/c637fea08bdfad17a86c335b58f79666a22b677174a84e817300451a11260a7a.json": { + "bytes": 118565, + "sha256": "c637fea08bdfad17a86c335b58f79666a22b677174a84e817300451a11260a7a" + }, + "inputs/e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b.zip": { + "bytes": 2843705, + "sha256": "e68321a18e2c1951263744ac9a4e505b18d4bdd520992360f652937fd0abf88b" + }, + "inputs/feb3e7ff11a74571fcfe290016131165d7be82e83b8e4a4daae1667e8a9feb3c.json": { + "bytes": 118907, + "sha256": "feb3e7ff11a74571fcfe290016131165d7be82e83b8e4a4daae1667e8a9feb3c" + }, + "runs/clippy-1/process.json": { + "bytes": 199, + "sha256": "e8aa78d9ea3dd2b623d990a9481e70354707e6aa5a591cb7b93dba5180a90aa9" + }, + "runs/clippy-1/result.json": { + "bytes": 1801, + "sha256": "b6b63d0069a0194d4a1fa91f17d2f6a69555087ec6a9224c322891a3b3047db2" + }, + "runs/clippy-1/started.json": { + "bytes": 1405, + "sha256": "165e5bb3b433703336dff190ad594ff3438da491d3396398e616dc5bc700e376" + }, + "runs/clippy-1/stderr.log": { + "bytes": 456, + "sha256": "e3de1e791b11f30e85b682df843625d4ca6556f7eb298d6a1bf310aa5b38aa30" + }, + "runs/clippy-1/stdout.log": { + "bytes": 310455, + "sha256": "e2692121e9c3536fe9f673de7388c393f23e6fe22dc08bb191a37610392dc0f9" + }, + "runs/core-transition-2/process.json": { + "bytes": 263, + "sha256": "39b8ea38cfb392a251a3279cb7d4904545702ef10a1fb870b5e866af843b8b3b" + }, + "runs/core-transition-2/result.json": { + "bytes": 4667, + "sha256": "3ed748bc46d4e7ebf21881ab6ffea85da6f94a36dde0778068b7a0282212a49d" + }, + "runs/core-transition-2/started.json": { + "bytes": 1484, + "sha256": "3cca432872797dddf8de33e0cf9f931274851acdc8002d5d3599a4fd43ca853d" + }, + "runs/core-transition-2/stderr.log": { + "bytes": 489, + "sha256": "92fd897c8f9608b06cdca0033a5008a6f00c5c28c4a88b3cba4bcbb3aeb4f986" + }, + "runs/core-transition-2/stdout.log": { + "bytes": 43653, + "sha256": "1c35f25e869d6151cbb6de224282a05395caa41d27cd8d2452872c651ba08dbf" + }, + "runs/core-workflows-1/process.json": { + "bytes": 202, + "sha256": "b6a5f0a3c4887888198f10d8e93b2422a1559c4b1214162f6e0954a8f0826828" + }, + "runs/core-workflows-1/result.json": { + "bytes": 3128, + "sha256": "89dccdd6655ffb2cd792d25ce76e7da258efbd884dc4ab47d0ba48f8aa23ec6e" + }, + "runs/core-workflows-1/started.json": { + "bytes": 1413, + "sha256": "a33e662e9743d650f57401b7276b696f97d97b8c5a916c0c783465b02eb3fc3c" + }, + "runs/core-workflows-1/stderr.log": { + "bytes": 271, + "sha256": "bb006c1bb74a6ce4d938f3eb0db36bb9179395fbc3a1b42a7dfb3edad691ca46" + }, + "runs/core-workflows-1/stdout.log": { + "bytes": 43869, + "sha256": "a51bf33e8e8767c73efcdc176f615801c63ff3ec9e369586f640fc634d60c528" + }, + "runs/desktop-workflow-1/process.json": { + "bytes": 223, + "sha256": "3360e8316f62834c74da7c08742e9f2e62856b7a43974f3fd311d95074bfe4cd" + }, + "runs/desktop-workflow-1/result.json": { + "bytes": 3170, + "sha256": "a9626e778ea9626fe76080c95faeac312455c7fd6b7511f1b5887da07bb6676a" + }, + "runs/desktop-workflow-1/started.json": { + "bytes": 1439, + "sha256": "cf9cee18e2a6cd06d1ed12306eecb79a056f2a85ca3913557a219302f9b650c5" + }, + "runs/desktop-workflow-1/stderr.log": { + "bytes": 539, + "sha256": "84734875bfd88145ebb582986937ccaf5fad3fc32ca0b50d03f57554195742e5" + }, + "runs/desktop-workflow-1/stdout.log": { + "bytes": 296022, + "sha256": "0ec72412bc1b3976e0c7470853a06efdf99f051aace8dad540fb3afc3a99bae2" + }, + "runs/format-1/process.json": { + "bytes": 116, + "sha256": "3ed4ed5a510a0b116a3c0fd2baf3e4db7ff7de66b7df0a0464cc098841fff115" + }, + "runs/format-1/result.json": { + "bytes": 1688, + "sha256": "1d5eac33f2174bcb464d89bc858483affe3c73d5016d19db7d0a32412d9ea475" + }, + "runs/format-1/started.json": { + "bytes": 1297, + "sha256": "60fcb6b008530a620534fba89c0cb8e143d423fab2dd2fe08a19a72d21eab904" + }, + "runs/format-1/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/format-1/stdout.log": { + "bytes": 538, + "sha256": "e6eac9f78ecb50fdaa288974ac26df928f6aa437d293d5aaf9ac60190394b88f" + }, + "runs/format-2/process.json": { + "bytes": 116, + "sha256": "20c7c2177f85bb157b2cfff08b26c447bebed42eb11e0e7f6b43c6664c4a494d" + }, + "runs/format-2/result.json": { + "bytes": 1686, + "sha256": "b220a0401f478cde47f2e1386a311de58e11bf7937a722490ac630ab223ab279" + }, + "runs/format-2/started.json": { + "bytes": 1297, + "sha256": "6d87fb899116fed854f2c2f2c358e0810103f462aa2f3f225feaf89b0855af6d" + }, + "runs/format-2/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/format-2/stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "runs/lifecycle-1/process.json": { + "bytes": 213, + "sha256": "ef6976e24b19e881d5d435f5dd2d7a54fd228f8013be6cd4a97110a5078f4494" + }, + "runs/lifecycle-1/result.json": { + "bytes": 3188, + "sha256": "149a0f3c8747b3c5227916aa88e4b94b77415b0c8d765445e92bfdd201069fb0" + }, + "runs/lifecycle-1/started.json": { + "bytes": 1425, + "sha256": "3e3458c4227da8bfbc4d4b6244fe0510687b8c98c2167a4802b2b691431565fa" + }, + "runs/lifecycle-1/stderr.log": { + "bytes": 21458, + "sha256": "2e13355db62b04032baa7007f7d7d691eadaad974f4fde8e0bf0ddd4a8b12027" + }, + "runs/lifecycle-1/stdout.log": { + "bytes": 42779, + "sha256": "9d545eaba4c279233a344b1e8bc845d0df4dbce5de5c4af9de14d288d3d8d7d8" + }, + "runs/windows-build-1/process.json": { + "bytes": 167, + "sha256": "5292a76450540df9e145cd21cc20118b310ed306126da85e893d0c9c221a8564" + }, + "runs/windows-build-1/result.json": { + "bytes": 5583, + "sha256": "91b38045319adc1fb9aa0e51d45d79a4be99d2de9aec08a47f73915e3ac9dd79" + }, + "runs/windows-build-1/started.json": { + "bytes": 1358, + "sha256": "826453a44cd915065caf1db9c0cc547dca0fa5a2b56594e4a72146b19ffe9e8c" + }, + "runs/windows-build-1/stderr.log": { + "bytes": 276, + "sha256": "0a035e700f490f73889da441e363052b34f33b3de5690c30eb1e6c2666c75bc6" + }, + "runs/windows-build-1/stdout.log": { + "bytes": 295257, + "sha256": "6ecb53aef4a76dda4174213dd5ba9b03aabc1434577c3141c4ed3e71adf068fa" + } + }, + "formattingInputChanges": { + "crates/oa-desktop/src/diagram/focus.rs": { + "before": { + "bytes": 9197, + "sha256": "b88a7c43123b08cf6228d8e32257f6ed7fe361f7278f427ec138e233e1ea6ccf" + }, + "after": { + "bytes": 9276, + "sha256": "44e7c13f8f56deb21c62cb7757a412ec8b790344387cebdee983c3a28b6b0160" + } + } + } +} diff --git a/harness/experiments/transition-lifecycle-20260913/verify.py b/harness/experiments/transition-lifecycle-20260913/verify.py new file mode 100644 index 00000000..fd246ca7 --- /dev/null +++ b/harness/experiments/transition-lifecycle-20260913/verify.py @@ -0,0 +1,112 @@ +"""Read-only, Python-standard-library verification. Never executes archived code.""" +from pathlib import Path, PurePosixPath +from datetime import datetime +import hashlib +import io +import json +import re +import zipfile + +ROOT = Path(__file__).resolve().parent + +def require(ok, message): + if not ok: + raise ValueError(message) + +def digest(data): + return {'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()} + +def members(z, expected): + names = z.namelist() + require(len(names) == len(set(names)), 'duplicate ZIP members') + require(set(names) == set(expected), 'archive membership mismatch') + require(all(not PurePosixPath(n).is_absolute() and '..' not in PurePosixPath(n).parts + and '\\' not in n and ':' not in n for n in names), 'unsafe member') + +def main(): + inventory = json.loads((ROOT / 'files.json').read_text()) + for name, expected in inventory.items(): + require(digest((ROOT / name).read_bytes()) == expected, 'external file hash: ' + name) + manifest = json.loads((ROOT / 'manifest.json').read_text()) + with zipfile.ZipFile(ROOT / 'evidence.zip') as z: + members(z, manifest['members']) + for name, expected in manifest['members'].items(): + require(digest(z.read(name)) == expected, 'member hash: ' + name) + def raw(name): return z.read(name) + def obj(name): return json.loads(raw(name)) + checked = set() + for run, spec in manifest['runs'].items(): + if spec['kind'] != 'cargo': + continue + prefix = 'runs/' + run + '/' + start, result, process = (obj(prefix + n + '.json') for n in ('started', 'result', 'process')) + require(all(result[k] == v for k, v in start.items()), run + ': start/result relationship') + require(result['command'] == spec['command'] == process['command'], run + ': command') + require(result['head'] == spec['head'], run + ': HEAD') + require(result['exitCode'] == spec['exitCode'] and result['inputsUnchanged'] is True, run + ': outcome') + require(datetime.fromisoformat(result['finish']) >= datetime.fromisoformat(start['start']), run + ': times') + require(result['seconds'] >= 0, run + ': duration') + require(process['pid']>0 and datetime.fromisoformat(start['start'])<=datetime.fromisoformat(process['observed'])<=datetime.fromisoformat(result['finish']), run+': process observation') + require(result['helper'] == digest(raw('helpers/gate-transition.py')), run + ': helper') + for field, file in [('inputs', spec['inputs']), ('archive', spec['archive']), ('stdout', prefix+'stdout.log'), ('stderr', prefix+'stderr.log')]: + require(result[field] == digest(raw(file)), run + ': receipt ' + field) + inputs = obj(spec['inputs']) + require(len(inputs) == result['inputCount'] == spec['inputCount'], run + ': input count') + require(sum(p.startswith('crates/vendor/iced_widget/') for p in inputs) == 71, run + ': vendor count') + pair = (spec['inputs'], spec['archive']) + if pair not in checked: + with zipfile.ZipFile(io.BytesIO(raw(spec['archive']))) as source: + members(source, inputs) + for name, expected in inputs.items(): + require(digest(source.read(name)) == expected, run + ': source hash ' + name) + checked.add(pair) + stdout = raw(prefix+'stdout.log').decode('utf-8', errors='replace') + rows = [[int(x) for x in row] for row in re.findall(r'test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored; (\d+) measured; (\d+) filtered out;', stdout)] + require(rows == spec['testRows'], run + ': exact test summaries') + require([sum(row[i] for row in rows) for i in range(5)] == spec['testTotals'], run + ': test totals') + artifacts = [] + for line in stdout.splitlines(): + try: item = json.loads(line) + except json.JSONDecodeError: continue + if isinstance(item, dict) and item.get('reason') == 'compiler-artifact' and item.get('executable'): + artifacts.append(item) + require(artifacts == [a['cargo'] for a in result['artifacts']], run + ': artifact receipt relationship') + print(run, 'exit', result['exitCode'], 'test totals', spec['testTotals']) + readbacks=obj('helpers/commit-readbacks.json') + require(set(readbacks)=={spec['inputCommit'] for spec in manifest['runs'].values() if 'inputCommit' in spec}, 'readback commit coverage') + base_inputs=obj(manifest['runs']['core-transition-2']['inputs']) + for commit,readback in readbacks.items(): + require(readback['status']=='PASS' and readback['commit']==commit, 'commit readback status') + specs=[spec for spec in manifest['runs'].values() if spec.get('inputCommit')==commit] + success=specs[0];inputs=obj(success['inputs']) + require(all(obj(spec['inputs'])==inputs for spec in specs), 'per-commit input equality') + require(readback['inputs']==digest(raw(success['inputs'])) and len(inputs)==readback['inputCount']==710, '710 readback') + require(set(readback['gitBlobs'])==set(inputs), 'readback blob inventory') + with zipfile.ZipFile(io.BytesIO(raw(success['archive']))) as source: + for name,oid in readback['gitBlobs'].items(): + b=source.read(name) + require(hashlib.sha1(b'blob '+str(len(b)).encode()+b'\0'+b).hexdigest()==oid, 'readback blob '+name) + if commit==manifest['formattedSourceCommit']: + changed={p:{'before':base_inputs.get(p),'after':inputs.get(p)} for p in sorted(set(base_inputs)|set(inputs)) if base_inputs.get(p)!=inputs.get(p)} + require(changed==manifest['formattingInputChanges'] and set(changed)=={'crates/oa-desktop/src/diagram/focus.rs'}, 'one-file formatting input difference') + with zipfile.ZipFile(io.BytesIO(raw(manifest['runs']['core-transition-2']['archive']))) as old, zipfile.ZipFile(io.BytesIO(raw(success['archive']))) as new: + path='crates/oa-desktop/src/diagram/focus.rs' + before=old.read(path);after=new.read(path) + compact=b' != (self.context.document, self.context.diagram, self.context.epoch)' + expanded=b' != (\n self.context.document,\n self.context.diagram,\n self.context.epoch,\n )' + require(before.count(compact)==1 and before.replace(compact,expanded,1)==after, 'exact tuple-format-only delta') + for run in ('core-transition-2','desktop-workflow-1','core-workflows-1','clippy-1','format-1'): + if run in manifest['runs']:require(manifest['runs'][run]['inputCommit']==manifest['testedSourceCommit'], 'earlier execution source scope '+run) + for run in ('format-2','windows-build-1'): + if run in manifest['runs']:require(manifest['runs'][run]['inputCommit']==manifest['formattedSourceCommit'], 'formatted source scope '+run) + if 'format-2' in manifest['runs']: + require(not raw('runs/format-2/stdout.log') and not raw('runs/format-2/stderr.log'), 'format2 empty success streams') + if 'windows-build-1' in manifest['runs']: + build=obj('runs/windows-build-1/result.json') + require(build['exitCode']==0 and len(build['artifacts'])==3, 'Windows build outcome') + require({a['cargo']['target']['name'] for a in build['artifacts']}=={'arcadia','arcadia-server','arcadia-studio'}, 'Windows build executable membership') + require(obj(manifest['runs']['lifecycle-1']['inputs'])!=base_inputs, 'initial failure remains distinct') + print('PASS:',len(manifest['runs']),'closed runs;',len(manifest['members']),'members;',len(checked),'input pairs;710 successful input blob bindings.') + print('No archived code executed. Local commit-readback summary is not authenticated commit membership.') + +if __name__=='__main__':main()