Record verified Allocation assignment planner and portable evidence

This commit is contained in:
2026-09-23 11:29:58 -07:00
parent 33e880103c
commit 16b30a6760
13 changed files with 918 additions and 2 deletions
@@ -0,0 +1 @@
** -text whitespace=cr-at-eol
@@ -0,0 +1,24 @@
# Allocation captured-gate evidence tools
Adapted from the reviewed Process prepare/verify/selfcheck tools. Read-only preparation consumes explicitly selected **closed** runs in CHECKOUT/.local/allocation-group-gates. No Cargo, source execution, checkout, GUI, network or archived helper execution occurs.
```powershell
python -B prepare.py --root CHECKOUT --runs experiment-1 experiment-2 experiment-3 planner-document-1 probe-lint-1 format-1 --check-only
```
Keep failed experiment-2: verification preserves its recorded compile failure rather than converting archive consistency into test success. The example selects the first six closed gates. Later closed planner runs can be explicitly listed with the same interface; the final package manifest is authoritative for its exact inventory. No implicit discovery includes active directories.
To create a portable package, replace --check-only with `--output NEW_DIRECTORY`. Existing output refuses. The exact seven raw files are required, with only `source-proof.json` accepted as an optional eighth file. No raw byte normalization or receipt rewriting occurs. Maps and nested input ZIPs deduplicate by SHA-256; other logical raw files keep their names. All original helper bytes, failed-run streams and optional proof bytes remain archived. The Allocation-specific manifest kind distinguishes this extension from the seven-file Process schema.
The gate.py and source-proof.py helper catalog is preserved. Every gate's recorded helper must match available bytes; use repeatable `--helper PATH` for older captures. If a proof exists, its exact comparator bytes must be available at the default `.local/process-source-evidence-tools/verify.py` or a repeatable `--comparator PATH`. They are archived under their content hash and never executed.
An optional source proof is independently pinned in the manifest with its full named commit. Verification binds it to the enclosing run, exact result receipt, captured map/count, completed gate time, status and comparator bytes/hash. Captured HEAD is preserved as historical metadata and is not substituted for the named source commit. This packager checks historical proof consistency; it does **not** repeat Git blob comparison. A source proof on a failed gate is source-identity evidence only, never a passing-test claim.
```powershell
python -B PACKAGE/verify.py
python -B selfcheck.py --root CHECKOUT --runs experiment-1 experiment-2 experiment-3 planner-document-1 probe-lint-1 format-1 --output TOOLS/NEW_SELFCHECK_DIRECTORY
```
The verifier checks pins, exact ZIP inventory, process/start/result relationships, streams, command/exit identities, source capsules, vendor inventory and Cargo artifact relationships. Selfchecks compare packaged raw bytes to originals, reject existing output, and mutate only in-memory copies to test stream/helper/exit/capsule/proof corruption. The package contains tools, manifest, files.json and evidence.zip; selfcheck is a preparation utility, not packaged runtime input.
Limits: internal consistency is not external authentication, hermetic build proof, native usability, a new source comparison or production acceptance. Review exact run results and source identity separately. Run with `python -B` to avoid incidental bytecode writes.
@@ -0,0 +1,22 @@
{
"prepare.py": {
"bytes": 6316,
"sha256": "aa52592fb8e373c2a90007e187734d29129d38d9fce9dc45461482c7f6376bff"
},
"verify.py": {
"bytes": 11440,
"sha256": "584187370a1076e13190914158fc72a9ab65f07e72cc6a0d3b5c319f3dc7f05f"
},
"README.md": {
"bytes": 3284,
"sha256": "3ff0a61fb15ca26e54b8903962c99ba7802a87f0204e7b71f2d04c812b9588b7"
},
"manifest.json": {
"bytes": 17748,
"sha256": "f053e2f1492ee4fdfa2d4dfd7e48c5768d098cf96b629471699810d06cb61537"
},
"evidence.zip": {
"bytes": 8984108,
"sha256": "51b898205ee7a2907ce746389882f0607f7ad7290a1759b392cd307ef9e9ef5a"
}
}
@@ -0,0 +1,396 @@
{
"schema": 1,
"kind": "allocation-multiselect-cargo-gates",
"runs": {
"assignment-planner-1": {
"command": [
"cargo",
"test",
"-p",
"oa-desktop",
"--example",
"allocation_policy_probe",
"--message-format=json",
"--",
"--test-threads=1"
],
"head": "eed80ffd6e94c7127491de1fd45c0415685f6328",
"exitCode": 0,
"inputCount": 749,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
},
"assignment-planner-2": {
"command": [
"cargo",
"test",
"-p",
"oa-desktop",
"--example",
"allocation_policy_probe",
"--message-format=json",
"--",
"--test-threads=1"
],
"head": "eed80ffd6e94c7127491de1fd45c0415685f6328",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
},
"assignment-lint-1": {
"command": [
"cargo",
"clippy",
"-p",
"oa-desktop",
"--example",
"allocation_policy_probe",
"--tests",
"--message-format=json",
"--",
"-D",
"warnings"
],
"head": "eed80ffd6e94c7127491de1fd45c0415685f6328",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
},
"assignment-format-1": {
"command": [
"cargo",
"fmt",
"--all",
"--",
"--check"
],
"head": "eed80ffd6e94c7127491de1fd45c0415685f6328",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py"
},
"assignment-planner-3": {
"command": [
"cargo",
"test",
"-p",
"oa-desktop",
"--example",
"allocation_policy_probe",
"--message-format=json",
"--",
"--test-threads=1"
],
"head": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
"sourceProof": {
"commit": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"pin": {
"bytes": 599,
"sha256": "3b249398b0ade218ec9737677e1021e21eae7aa03deeb6bc071e0e7e7fe6182b"
},
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
}
},
"assignment-lint-2": {
"command": [
"cargo",
"clippy",
"-p",
"oa-desktop",
"--example",
"allocation_policy_probe",
"--tests",
"--message-format=json",
"--",
"-D",
"warnings"
],
"head": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
"sourceProof": {
"commit": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"pin": {
"bytes": 596,
"sha256": "3a8f4d17bc6e696f8c0a1373f739650da5aa5b84683478c697e71b280d07b430"
},
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
}
},
"assignment-format-2": {
"command": [
"cargo",
"fmt",
"--all",
"--",
"--check"
],
"head": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"exitCode": 0,
"inputCount": 750,
"helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
"sourceProof": {
"commit": "33e880103c5fa935a4431ec3dc089e2c4c92f680",
"pin": {
"bytes": 598,
"sha256": "41553cf5d5e5f6414930ad088fa82515630d3478da53a5ac961c8bf4191d1bc6"
},
"comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py"
}
}
},
"captureHelpers": {
"gate.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
"source-proof.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py"
},
"logicalFiles": {
"cargo/assignment-format-1/inputs.json": "capsules/e41e7d1a2b9519b78730821f96c1bf7ca8431935fe67efa203daa80d3f15c437.json",
"cargo/assignment-format-1/inputs.zip": "capsules/b471d434d8eac790ef7cc9073be0d395c9c9ad1472ba06a05b5818269ef03dfe.zip",
"cargo/assignment-format-1/process.json": "cargo/assignment-format-1/process.json",
"cargo/assignment-format-1/result.json": "cargo/assignment-format-1/result.json",
"cargo/assignment-format-1/started.json": "cargo/assignment-format-1/started.json",
"cargo/assignment-format-1/stderr.log": "cargo/assignment-format-1/stderr.log",
"cargo/assignment-format-1/stdout.log": "cargo/assignment-format-1/stdout.log",
"cargo/assignment-format-2/inputs.json": "capsules/ce988ecaeaca395d0f120844db7e3da90d039633beef10d2d4a8b8f19e92ee27.json",
"cargo/assignment-format-2/inputs.zip": "capsules/ae03a0a847a5c2000ba46e356e3dcd13a219e5fb699be8ad71a619b593e13c23.zip",
"cargo/assignment-format-2/process.json": "cargo/assignment-format-2/process.json",
"cargo/assignment-format-2/result.json": "cargo/assignment-format-2/result.json",
"cargo/assignment-format-2/source-proof.json": "cargo/assignment-format-2/source-proof.json",
"cargo/assignment-format-2/started.json": "cargo/assignment-format-2/started.json",
"cargo/assignment-format-2/stderr.log": "cargo/assignment-format-2/stderr.log",
"cargo/assignment-format-2/stdout.log": "cargo/assignment-format-2/stdout.log",
"cargo/assignment-lint-1/inputs.json": "capsules/e41e7d1a2b9519b78730821f96c1bf7ca8431935fe67efa203daa80d3f15c437.json",
"cargo/assignment-lint-1/inputs.zip": "capsules/b471d434d8eac790ef7cc9073be0d395c9c9ad1472ba06a05b5818269ef03dfe.zip",
"cargo/assignment-lint-1/process.json": "cargo/assignment-lint-1/process.json",
"cargo/assignment-lint-1/result.json": "cargo/assignment-lint-1/result.json",
"cargo/assignment-lint-1/started.json": "cargo/assignment-lint-1/started.json",
"cargo/assignment-lint-1/stderr.log": "cargo/assignment-lint-1/stderr.log",
"cargo/assignment-lint-1/stdout.log": "cargo/assignment-lint-1/stdout.log",
"cargo/assignment-lint-2/inputs.json": "capsules/ce988ecaeaca395d0f120844db7e3da90d039633beef10d2d4a8b8f19e92ee27.json",
"cargo/assignment-lint-2/inputs.zip": "capsules/ae03a0a847a5c2000ba46e356e3dcd13a219e5fb699be8ad71a619b593e13c23.zip",
"cargo/assignment-lint-2/process.json": "cargo/assignment-lint-2/process.json",
"cargo/assignment-lint-2/result.json": "cargo/assignment-lint-2/result.json",
"cargo/assignment-lint-2/source-proof.json": "cargo/assignment-lint-2/source-proof.json",
"cargo/assignment-lint-2/started.json": "cargo/assignment-lint-2/started.json",
"cargo/assignment-lint-2/stderr.log": "cargo/assignment-lint-2/stderr.log",
"cargo/assignment-lint-2/stdout.log": "cargo/assignment-lint-2/stdout.log",
"cargo/assignment-planner-1/inputs.json": "capsules/4e237aa6ba6359490d65efd40e15a697991ce53350af2080503c0635d2d9de3e.json",
"cargo/assignment-planner-1/inputs.zip": "capsules/1bb6e8b18022977f43e29bd44d25238acbf8c424bd4bf736474fce74bd8de8bc.zip",
"cargo/assignment-planner-1/process.json": "cargo/assignment-planner-1/process.json",
"cargo/assignment-planner-1/result.json": "cargo/assignment-planner-1/result.json",
"cargo/assignment-planner-1/started.json": "cargo/assignment-planner-1/started.json",
"cargo/assignment-planner-1/stderr.log": "cargo/assignment-planner-1/stderr.log",
"cargo/assignment-planner-1/stdout.log": "cargo/assignment-planner-1/stdout.log",
"cargo/assignment-planner-2/inputs.json": "capsules/e41e7d1a2b9519b78730821f96c1bf7ca8431935fe67efa203daa80d3f15c437.json",
"cargo/assignment-planner-2/inputs.zip": "capsules/b471d434d8eac790ef7cc9073be0d395c9c9ad1472ba06a05b5818269ef03dfe.zip",
"cargo/assignment-planner-2/process.json": "cargo/assignment-planner-2/process.json",
"cargo/assignment-planner-2/result.json": "cargo/assignment-planner-2/result.json",
"cargo/assignment-planner-2/started.json": "cargo/assignment-planner-2/started.json",
"cargo/assignment-planner-2/stderr.log": "cargo/assignment-planner-2/stderr.log",
"cargo/assignment-planner-2/stdout.log": "cargo/assignment-planner-2/stdout.log",
"cargo/assignment-planner-3/inputs.json": "capsules/ce988ecaeaca395d0f120844db7e3da90d039633beef10d2d4a8b8f19e92ee27.json",
"cargo/assignment-planner-3/inputs.zip": "capsules/ae03a0a847a5c2000ba46e356e3dcd13a219e5fb699be8ad71a619b593e13c23.zip",
"cargo/assignment-planner-3/process.json": "cargo/assignment-planner-3/process.json",
"cargo/assignment-planner-3/result.json": "cargo/assignment-planner-3/result.json",
"cargo/assignment-planner-3/source-proof.json": "cargo/assignment-planner-3/source-proof.json",
"cargo/assignment-planner-3/started.json": "cargo/assignment-planner-3/started.json",
"cargo/assignment-planner-3/stderr.log": "cargo/assignment-planner-3/stderr.log",
"cargo/assignment-planner-3/stdout.log": "cargo/assignment-planner-3/stdout.log",
"comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py",
"helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py",
"helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py"
},
"members": {
"capsules/1bb6e8b18022977f43e29bd44d25238acbf8c424bd4bf736474fce74bd8de8bc.zip": {
"bytes": 3008043,
"sha256": "1bb6e8b18022977f43e29bd44d25238acbf8c424bd4bf736474fce74bd8de8bc"
},
"capsules/4e237aa6ba6359490d65efd40e15a697991ce53350af2080503c0635d2d9de3e.json": {
"bytes": 125475,
"sha256": "4e237aa6ba6359490d65efd40e15a697991ce53350af2080503c0635d2d9de3e"
},
"capsules/ae03a0a847a5c2000ba46e356e3dcd13a219e5fb699be8ad71a619b593e13c23.zip": {
"bytes": 3013577,
"sha256": "ae03a0a847a5c2000ba46e356e3dcd13a219e5fb699be8ad71a619b593e13c23"
},
"capsules/b471d434d8eac790ef7cc9073be0d395c9c9ad1472ba06a05b5818269ef03dfe.zip": {
"bytes": 3013606,
"sha256": "b471d434d8eac790ef7cc9073be0d395c9c9ad1472ba06a05b5818269ef03dfe"
},
"capsules/ce988ecaeaca395d0f120844db7e3da90d039633beef10d2d4a8b8f19e92ee27.json": {
"bytes": 125659,
"sha256": "ce988ecaeaca395d0f120844db7e3da90d039633beef10d2d4a8b8f19e92ee27"
},
"capsules/e41e7d1a2b9519b78730821f96c1bf7ca8431935fe67efa203daa80d3f15c437.json": {
"bytes": 125659,
"sha256": "e41e7d1a2b9519b78730821f96c1bf7ca8431935fe67efa203daa80d3f15c437"
},
"cargo/assignment-format-1/process.json": {
"bytes": 116,
"sha256": "ea332ddf4129442f2a8f19b150a6c2fc21a41299eadc32287ba6ba67769e2b58"
},
"cargo/assignment-format-1/result.json": {
"bytes": 1872,
"sha256": "46047bb39986083c89d12751153b678eedd660963b9dafb02c1738986f0dd47a"
},
"cargo/assignment-format-1/started.json": {
"bytes": 1484,
"sha256": "3657a2a7ac270bca405c128328557fb5e1725f913ae0c9c5baa1ba08269bb501"
},
"cargo/assignment-format-1/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/assignment-format-1/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/assignment-format-2/process.json": {
"bytes": 116,
"sha256": "8371d4a455f0dd7678c5b8fb91f679355c05f9f0594985460aee9796bd6adc65"
},
"cargo/assignment-format-2/result.json": {
"bytes": 1872,
"sha256": "319d67031a3f30f70b21f869d755b91196ce0be68d8132775288b3d86b223d06"
},
"cargo/assignment-format-2/source-proof.json": {
"bytes": 598,
"sha256": "41553cf5d5e5f6414930ad088fa82515630d3478da53a5ac961c8bf4191d1bc6"
},
"cargo/assignment-format-2/started.json": {
"bytes": 1483,
"sha256": "a59985096b89da3518c367131b3ec257596725d18f62307bfc174ccb7969c362"
},
"cargo/assignment-format-2/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/assignment-format-2/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/assignment-lint-1/process.json": {
"bytes": 213,
"sha256": "b14d908c775b772f6993b40965a21ae894a406665fa5c2794ebfdb7ffe082769"
},
"cargo/assignment-lint-1/result.json": {
"bytes": 2006,
"sha256": "a8c6cc8a726c9bee821b2c12a0768d860bb1c40261783bcc23da2ea19a677959"
},
"cargo/assignment-lint-1/started.json": {
"bytes": 1610,
"sha256": "3f42270e22476b1698f19cfdc8cd6c78b0754480b613963d582d98d89bf541f6"
},
"cargo/assignment-lint-1/stderr.log": {
"bytes": 137,
"sha256": "d64f9789f0e3e22b0c98af77d19231a9026083ad317f6b2f989ebebd556f1269"
},
"cargo/assignment-lint-1/stdout.log": {
"bytes": 268845,
"sha256": "98a24be8306e586a1acb6a72c3e62005afc0db01fa4ec0b242c420aafadcf779"
},
"cargo/assignment-lint-2/process.json": {
"bytes": 212,
"sha256": "17b1f10f739cdf456da58ef2dcd9c15a8569132904876b8e2289ea543f1217d7"
},
"cargo/assignment-lint-2/result.json": {
"bytes": 2005,
"sha256": "ec3bc72c846cc08188ff95d38aa743c52ac9ec2c616fb8acb7566a6619490b68"
},
"cargo/assignment-lint-2/source-proof.json": {
"bytes": 596,
"sha256": "3a8f4d17bc6e696f8c0a1373f739650da5aa5b84683478c697e71b280d07b430"
},
"cargo/assignment-lint-2/started.json": {
"bytes": 1610,
"sha256": "afdad6e675e3351c749dccea6759c01f8b303a0d598f41592f62beecbc94fdf7"
},
"cargo/assignment-lint-2/stderr.log": {
"bytes": 137,
"sha256": "6ceb01ea1a2f7759c0f7e4fcc98504fae7f6f9cb758b16a2701f804c88ec401d"
},
"cargo/assignment-lint-2/stdout.log": {
"bytes": 268845,
"sha256": "8b993ec00e2a4a58b15af1e57051906cbee8d3d51f4314b71f71af28f582a675"
},
"cargo/assignment-planner-1/process.json": {
"bytes": 202,
"sha256": "1aec12d9a133576033cb736bdec098873005e8b248e09157a3e7608c2d551fdc"
},
"cargo/assignment-planner-1/result.json": {
"bytes": 3388,
"sha256": "b1bc1f3f3013c9df43f7af3cef801e0b977ec484457cfc314e4aa2f1c8d6db98"
},
"cargo/assignment-planner-1/started.json": {
"bytes": 1589,
"sha256": "75d0eeca99ff5f2819a0302cbdc739d2377a2f524890f448f040585288680d2e"
},
"cargo/assignment-planner-1/stderr.log": {
"bytes": 324,
"sha256": "8ee7484db45f8ddf1bf0057317feb689990758c35dc0946c12e0eef0de08e808"
},
"cargo/assignment-planner-1/stdout.log": {
"bytes": 301624,
"sha256": "7be201e6c1a812d8a32d73e75999e5e50a07af2f11eebc77f442aee44f64e5af"
},
"cargo/assignment-planner-2/process.json": {
"bytes": 202,
"sha256": "5837e6b91cbd5c6c95bbeaf08ac89a47149e84c4c3f20004457e80c316e388c9"
},
"cargo/assignment-planner-2/result.json": {
"bytes": 3387,
"sha256": "2dd1c6036eb805cd8e95050661e3dce9d132f9071186165097d4212f2b8253c0"
},
"cargo/assignment-planner-2/started.json": {
"bytes": 1589,
"sha256": "a4384901a0d3a29631a29d5e91b6d3dc944cefca1bb7653901d351a7bd906ec1"
},
"cargo/assignment-planner-2/stderr.log": {
"bytes": 324,
"sha256": "a046d75d45956402707b7c1089ec5005b0ba640857473e1f284a8f377f896f2c"
},
"cargo/assignment-planner-2/stdout.log": {
"bytes": 302839,
"sha256": "1905a2726b6e9c388566af75d7705b3916ade3a7d2c9dab772bffbb5b115762b"
},
"cargo/assignment-planner-3/process.json": {
"bytes": 202,
"sha256": "ec191e2d953d52f6da8c54bc6e9dfa5638273eb6c351823fc4871628320b3bab"
},
"cargo/assignment-planner-3/result.json": {
"bytes": 3388,
"sha256": "117bcfa31629682df708dfebb892464f01060888388ea680a231b12cd447db67"
},
"cargo/assignment-planner-3/source-proof.json": {
"bytes": 599,
"sha256": "3b249398b0ade218ec9737677e1021e21eae7aa03deeb6bc071e0e7e7fe6182b"
},
"cargo/assignment-planner-3/started.json": {
"bytes": 1589,
"sha256": "30cf725d9475a24b177c2dbddb3f59b7d298343556598bc0e760d51ad7e111e5"
},
"cargo/assignment-planner-3/stderr.log": {
"bytes": 324,
"sha256": "d3a0110134db80cd8715e6081027595056203feada2278053fdc62ae75c6df31"
},
"cargo/assignment-planner-3/stdout.log": {
"bytes": 302839,
"sha256": "aa832fe75c46be8990d0c679e6e321494c0ea6638657634010bae7022b7a2ee9"
},
"comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": {
"bytes": 10094,
"sha256": "7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a"
},
"helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": {
"bytes": 3827,
"sha256": "1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20"
},
"helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": {
"bytes": 1399,
"sha256": "58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119"
}
}
}
@@ -0,0 +1,110 @@
"""Package explicitly selected closed gate captures without running Cargo."""
from pathlib import Path
import argparse
import json
import zipfile
from verify import RAW_FILES, pin, parsed, need, run_name, verify_data, verify_package
HERE = Path(__file__).resolve().parent
def collect(root, runs, helpers, comparators=()):
gates = root / ".local/allocation-group-gates"
candidates = [gates / name for name in ("gate.py", "source-proof.py")] + helpers
helper_bytes = [path.read_bytes() for path in candidates]
comparator_paths = [root / ".local/process-source-evidence-tools/verify.py", *comparators]
comparator_bytes = [path.read_bytes() for path in comparator_paths if path.is_file()]
payload, logical, specs = {}, {}, {}
def add(name, data):
stored = ("capsules/" + pin(data)["sha256"] + Path(name).suffix
if name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"} else name)
need(stored not in payload or payload[stored] == data, "deduplication collision")
payload[stored] = data
logical[name] = stored
helper_catalog = {}
for name, data in zip(("gate.py", "source-proof.py"), helper_bytes):
helper = "helpers/" + pin(data)["sha256"] + ".py"
add(helper, data)
helper_catalog[name] = helper
for run in runs:
folder = gates / run
need(folder.is_dir(), "run directory missing: " + run)
paths = list(folder.iterdir())
names = {path.name for path in paths}
need(all(path.is_file() and not path.is_symlink() for path in paths)
and names in (RAW_FILES, RAW_FILES | {"source-proof.json"}), "exact closed raw files required: " + run)
raw = {path.name: path.read_bytes() for path in paths}
result = parsed(raw["result.json"])
need("finish" in result and result["inputsUnchanged"] is True, "unfinished/changed run refused: " + run)
matches = [data for data in helper_bytes if pin(data) == result["helper"]]
need(bool(matches), "exact historical helper unavailable for " + run + "; supply --helper PATH")
helper = "helpers/" + result["helper"]["sha256"] + ".py"
add(helper, matches[0])
for name, data in sorted(raw.items()):
add("cargo/" + run + "/" + name, data)
specs[run] = {key: result[key] for key in ("command", "head", "exitCode", "inputCount")}
specs[run]["helper"] = helper
if "source-proof.json" in raw:
proof = parsed(raw["source-proof.json"])
matches = [data for data in comparator_bytes if pin(data) == proof["comparator"]]
need(bool(matches), "exact source comparator unavailable for " + run + "; supply --comparator PATH")
comparator = "comparators/" + proof["comparator"]["sha256"] + ".py"
add(comparator, matches[0])
specs[run]["sourceProof"] = {"commit": proof["commit"], "pin": pin(raw["source-proof.json"]), "comparator": comparator}
manifest = {"schema": 1, "kind": "allocation-multiselect-cargo-gates", "runs": specs,
"captureHelpers": helper_catalog,
"logicalFiles": dict(sorted(logical.items())),
"members": {name: pin(data) for name, data in sorted(payload.items())}}
summary = verify_data(manifest, payload.__getitem__)
return payload, manifest, summary
def write_json(path, value):
with path.open("xb") as output:
output.write((json.dumps(value, indent=2) + "\n").encode("utf-8"))
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, required=True, help="checkout holding .local/allocation-group-gates")
parser.add_argument("--runs", nargs="+", required=True, help="explicit run names, including failures to retain")
parser.add_argument("--helper", type=Path, action="append", default=[], help="additional exact historical helper (repeatable)")
parser.add_argument("--comparator", type=Path, action="append", default=[], help="additional exact historical source comparator (repeatable)")
parser.add_argument("--output", type=Path, help="fresh, nonexistent package directory (required unless --check-only)")
parser.add_argument("--check-only", action="store_true", help="validate raw captures in memory without creating an archive")
args = parser.parse_args()
need(all(run_name(run) for run in args.runs) and len(args.runs) == len(set(args.runs)), "unique safe run names required")
need(args.check_only or args.output is not None, "--output is required unless --check-only")
if not args.check_only:
need(not args.output.exists(), "output must be a fresh directory: " + str(args.output))
payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper, args.comparator)
if args.check_only:
print("PASS raw consistency; no package written:", summary)
return
out = args.output.resolve()
out.mkdir(parents=True, exist_ok=False)
for name in ("evidence.zip", "manifest.json", "files.json"):
need(not (out / name).exists(), "existing package output refused: " + name)
for name in ("prepare.py", "verify.py", "README.md"):
data = (HERE / name).read_bytes()
destination = out / name
if destination.exists():
need(destination.read_bytes() == data, "different existing package tool: " + name)
else:
with destination.open("xb") as output:
output.write(data)
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)
names = ("prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip")
write_json(out / "files.json", {name: pin((out / name).read_bytes()) for name in names})
need(verify_package(out) == summary, "written package differs from validated captures")
print("PASS package readback:", out, summary)
if __name__ == "__main__":
main()
@@ -0,0 +1,194 @@
"""Offline consistency checks only; never execute or extract archived inputs."""
from pathlib import Path, PurePosixPath
from datetime import datetime
import argparse
import hashlib
import io
import json
import math
import re
import stat
import zipfile
RAW_FILES = {"started.json", "process.json", "result.json", "stdout.log", "stderr.log", "inputs.json", "inputs.zip"}
OUTER_FILES = {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"}
def need(condition, message):
if not condition:
raise ValueError(message)
def pin(data):
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
def valid_pin(value):
return (isinstance(value, dict) and set(value) == {"bytes", "sha256"}
and type(value["bytes"]) is int and value["bytes"] >= 0
and isinstance(value["sha256"], str)
and re.fullmatch(r"[0-9a-f]{64}", value["sha256"]) is not None)
def safe(name):
return (isinstance(name, str) and bool(name) and "\\" not in name and ":" not in name
and all(ord(char) >= 32 for char in name)
and not PurePosixPath(name).is_absolute()
and all(part not in ("", ".", "..") for part in name.split("/")))
def run_name(name):
return isinstance(name, str) and re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]*", name) is not None
def parsed(data):
def pairs(items):
result = {}
for key, value in items:
need(key not in result, "duplicate JSON key: " + key)
result[key] = value
return result
def constant(value):
raise ValueError("nonfinite JSON constant: " + value)
return json.loads(data, object_pairs_hook=pairs, parse_constant=constant)
def inventory(archive, expected):
names = archive.namelist()
need(len(names) == len(set(names)) and set(names) == set(expected), "exact ZIP membership")
for entry in archive.infolist():
need(safe(entry.filename) and not entry.is_dir(), "unsafe ZIP member: " + entry.filename)
need(not stat.S_ISLNK(entry.external_attr >> 16), "ZIP symlink: " + entry.filename)
need(valid_pin(expected[entry.filename]), "invalid member pin: " + entry.filename)
need(entry.file_size == expected[entry.filename]["bytes"], "ZIP recorded size: " + entry.filename)
def ordered_times(*values):
times = [datetime.fromisoformat(value) for value in values]
return all(value.utcoffset() is not None for value in times) and times == sorted(times)
def verify_data(manifest, read):
"""Shared read-only verifier for packaged bytes or prepare's in-memory payload."""
need(manifest["schema"] == 1 and manifest["kind"] == "allocation-multiselect-cargo-gates", "manifest schema")
runs, logical, stored = manifest["runs"], manifest["logicalFiles"], manifest["members"]
helpers = manifest["captureHelpers"]
need(isinstance(helpers, dict) and set(helpers) == {"gate.py", "source-proof.py"}, "capture helper names")
need(all(isinstance(name, str) and re.fullmatch(r"helpers/[0-9a-f]{64}\.py", name)
for name in helpers.values()), "capture helper mapping")
need(isinstance(runs, dict) and bool(runs) and all(run_name(run) for run in runs), "explicit run inventory")
need(all(safe(name) for name in logical) and all(safe(name) for name in stored), "unsafe manifest path")
need(set(logical.values()) == set(stored), "unreferenced or absent stored members")
for name, expected in stored.items():
need(valid_pin(expected) and pin(read(name)) == expected, "stored member hash: " + name)
expected_logical = {"cargo/" + run + "/" + name for run in runs for name in RAW_FILES}
expected_logical.update(spec["helper"] for spec in runs.values())
expected_logical.update(helpers.values())
for run, spec in runs.items():
if "sourceProof" in spec:
proof_spec = spec["sourceProof"]
need(set(proof_spec) == {"commit", "pin", "comparator"}, run + ": exact source proof spec")
need(isinstance(proof_spec["commit"], str) and re.fullmatch(r"[0-9a-f]{40}", proof_spec["commit"]), run + ": named full source commit")
need(valid_pin(proof_spec["pin"]), run + ": source proof pin")
need(isinstance(proof_spec["comparator"], str) and re.fullmatch(r"comparators/[0-9a-f]{64}\.py", proof_spec["comparator"]), run + ": comparator path")
expected_logical.update({"cargo/" + run + "/source-proof.json", proof_spec["comparator"]})
need(set(logical) == expected_logical, "exact logical raw/helper inventory")
for name, destination in logical.items():
if name.startswith("cargo/") and name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"}:
expected = "capsules/" + stored[destination]["sha256"] + PurePosixPath(name).suffix
need(destination == expected, "input capsule mapping: " + name)
else:
need(destination == name, "only input maps/archives may be deduplicated: " + name)
def raw(name):
return read(logical[name])
for name, helper in helpers.items():
need(helper == "helpers/" + pin(raw(helper))["sha256"] + ".py", "named helper hash: " + name)
seen_capsules = set()
for run, spec in runs.items():
prefix = "cargo/" + run + "/"
start = parsed(raw(prefix + "started.json"))
process = parsed(raw(prefix + "process.json"))
result = parsed(raw(prefix + "result.json"))
required_start = {"start", "command", "cwd", "head", "scope", "inputs", "archive",
"inputCount", "environment", "helper", "cargo", "rustc"}
need(required_start <= start.keys(), run + ": incomplete start receipt")
need(all(result.get(key) == value for key, value in start.items()), run + ": start/result relationship")
command = result["command"]
need(isinstance(command, list) and command and command[0] == "cargo"
and all(isinstance(arg, str) for arg in command), run + ": Cargo command")
need(command == process["command"] == spec["command"], run + ": command relationship")
need(result["head"] == spec["head"] and re.fullmatch(r"(?:[0-9a-f]{40}|[0-9a-f]{64})", result["head"]), run + ": HEAD")
need(type(result["exitCode"]) is int and result["exitCode"] == spec["exitCode"], run + ": recorded exit")
need(result["inputsUnchanged"] is True, run + ": changed inputs refused")
need(type(result["seconds"]) in (int, float) and math.isfinite(result["seconds"])
and result["seconds"] >= 0, run + ": duration")
need(type(process["pid"]) is int and process["pid"] > 0, run + ": process identity")
need(ordered_times(start["start"], process["observed"], result["finish"]), run + ": completed timestamp order")
for field, filename in [("inputs", "inputs.json"), ("archive", "inputs.zip"), ("stdout", "stdout.log"), ("stderr", "stderr.log")]:
need(result[field] == pin(raw(prefix + filename)), run + ": " + field + " pin")
need(valid_pin(result["helper"]) and result["helper"] == pin(raw(spec["helper"])), run + ": helper pin")
need(spec["helper"] == "helpers/" + result["helper"]["sha256"] + ".py", run + ": helper mapping")
inputs = parsed(raw(prefix + "inputs.json"))
need(isinstance(inputs, dict) and all(safe(name) for name in inputs), run + ": safe input inventory")
need(type(result["inputCount"]) is int and len(inputs) == result["inputCount"] == spec["inputCount"], run + ": input counts")
if "sourceProof" in spec:
proof_spec = spec["sourceProof"]
proof_bytes = raw(prefix + "source-proof.json")
proof = parsed(proof_bytes)
need(pin(proof_bytes) == proof_spec["pin"], run + ": source proof pinned bytes")
need(proof["run"] == run and proof["commit"] == proof_spec["commit"], run + ": proof run/commit identity")
need(proof["status"] == "PASS exact captured input inventory and Git blob bytes", run + ": source proof status")
need(proof["inputCount"] == len(inputs) and proof["inputMap"] == result["inputs"], run + ": proof input relationship")
need(proof["result"] == pin(raw(prefix + "result.json")), run + ": proof result relationship")
need(ordered_times(result["finish"], proof["verified"]), run + ": proof time after closed gate")
comparator = proof_spec["comparator"]
need(valid_pin(proof["comparator"]) and pin(raw(comparator)) == proof["comparator"], run + ": comparator bytes")
need(comparator == "comparators/" + proof["comparator"]["sha256"] + ".py", run + ": comparator identity")
need(sum(name.startswith("crates/vendor/iced_widget/") for name in inputs) == 71, run + ": vendor count")
capsule = (logical[prefix + "inputs.json"], logical[prefix + "inputs.zip"])
if capsule not in seen_capsules:
with zipfile.ZipFile(io.BytesIO(raw(prefix + "inputs.zip"))) as source:
inventory(source, inputs)
for name, expected in inputs.items():
need(pin(source.read(name)) == expected, run + ": source hash " + name)
seen_capsules.add(capsule)
artifacts = []
for line in raw(prefix + "stdout.log").decode("utf-8", errors="replace").splitlines():
try:
value = json.loads(line)
except json.JSONDecodeError:
continue
if isinstance(value, dict) and value.get("reason") == "compiler-artifact" and value.get("executable"):
artifacts.append(value)
need(isinstance(result["artifacts"], list), run + ": artifact records")
need(artifacts == [record["cargo"] for record in result["artifacts"]], run + ": Cargo JSON artifact relationship")
for record in result["artifacts"]:
need(set(record) == {"cargo", "readback"}
and (record["readback"] is None or valid_pin(record["readback"])), run + ": artifact readback pin")
print(run, "recorded exit", result["exitCode"], "inputs", len(inputs), "executable records", len(artifacts))
return {"runs": len(runs), "recordedFailures": sum(spec["exitCode"] != 0 for spec in runs.values()),
"logicalFiles": len(logical), "storedMembers": len(stored), "sourceCapsulePairs": len(seen_capsules),
"captureHelpers": helpers, "sourceProofs": sum("sourceProof" in spec for spec in runs.values())}
def verify_package(root):
files = parsed((root / "files.json").read_bytes())
need(set(files) == OUTER_FILES, "outer file inventory")
for name, expected in files.items():
need(valid_pin(expected) and pin((root / name).read_bytes()) == expected, "outer hash: " + name)
manifest = parsed((root / "manifest.json").read_bytes())
with zipfile.ZipFile(root / "evidence.zip") as archive:
inventory(archive, manifest["members"])
return verify_data(manifest, archive.read)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("package", nargs="?", type=Path, default=Path(__file__).resolve().parent)
args = parser.parse_args()
print("PASS offline consistency:", verify_package(args.package))
print("Historical receipts only; no source/binary execution or native acceptance claim.")
if __name__ == "__main__":
main()
@@ -0,0 +1,16 @@
# Assignment review archive
Exact historical design, fixtures and independent review notes, with original
`.local` paths preserved inside the archive. Their relative links refer to that
original checkout context; extract only into a separate scratch directory if
needed. Do not interpret historical plans or source-derived predictions as
executed results. The review addendum inspects the recorded 84-test gate without
claiming an independent rerun. The App adapter plan is design only.
The newline diagnosis records why three initial exact source comparisons
refused. Their captures were retained and canonical-byte gates rerun; historical
receipts were not rewritten. Current accepted facts and limitations are in the
[planner report](../../allocation-assignment-planner-20260923.md).
`files.json` pins this archive/index/readme; `members.json` pins every exact ZIP
member. Neither internal hashes nor independent review replace runtime evidence.
@@ -0,0 +1,14 @@
{
"reviews.zip": {
"bytes": 26141,
"sha256": "35a5faaf9f60eaa88d8c97f8a34dceac7a2cebf356ac6f69ec0e794cec258101"
},
"members.json": {
"bytes": 840,
"sha256": "3b1ce35c9b65b241b80367c90adc0ffbc65155d9cea8872f98e58901b2d52513"
},
"README.md": {
"bytes": 952,
"sha256": "a518a056c78b982c45f8d9a2098729f27df8f1702132c0e4cc6c555c603dbd22"
}
}
@@ -0,0 +1,22 @@
{
".local/allocation-group-design/assignment-plan.md": {
"bytes": 16268,
"sha256": "000b80e13845a1532e083281ee94486964306af0ce7fb27fee3a9eb2074f2405"
},
".local/allocation-group-design/assignment-fixtures.md": {
"bytes": 11563,
"sha256": "507e5d33745ffb65f096a8c5640f6e22d61ecb8701eb13769bfe538069e71ecc"
},
".local/allocation-group-design/assignment-review.md": {
"bytes": 11510,
"sha256": "f1c36cdba4a6f74770d541d9529d7f116473b2bc78bc2b2902c80f387eba82d1"
},
".local/allocation-group-design/app-adapter-plan.md": {
"bytes": 21648,
"sha256": "316633ae45d8f9836212d37e64639251cdb2fd96cda522d0a979d9bc81782cf7"
},
".local/allocation-evidence-tools/assignment-newline-diagnosis.json": {
"bytes": 622,
"sha256": "60631de3a45d0cb6c4108e7aaaf170b80e43e00e076674aabf379d05ee77a62a"
}
}