docs: publish saved-view group selection verification and native evidence

This commit is contained in:
2026-09-23 02:19:57 -07:00
parent f6a6010bae
commit 7e348d967d
44 changed files with 4666 additions and 0 deletions
@@ -0,0 +1,3 @@
# Preserve the exact pinned evidence and verifier bytes through Git round trips.
* -text whitespace=cr-at-eol
incidents/**/*.arcadia whitespace=-blank-at-eof,cr-at-eol
@@ -0,0 +1,96 @@
# Closed multiselect gate evidence
This package preserves all 19 closed captures selected from
`.local/group-movement-gates`: 14 recorded exit 0, and five recorded exit 101.
Every run reports unchanged captured inputs. The five failures remain failures;
their complete original receipts and streams are included. See the separate
[saved-view report](../../../multiselect-saved-view-20260923.md) for scope and
native observations. These standard-library Python 3.10+ tools do not run Cargo,
Git, archived source or executables.
| Run | Recorded exit | Input files |
| --- | ---: | ---: |
| core-1 | 0 | 722 |
| core-2 | 101 | 729 |
| core-3 | 0 | 729 |
| desktop-1 | 101 | 727 |
| desktop-2 | 101 | 728 |
| desktop-3 | 0 | 729 |
| desktop-4 | 0 | 729 |
| desktop-5 | 0 | 729 |
| format-1 | 0 | 729 |
| format-2 | 0 | 729 |
| lint-1 | 101 | 729 |
| lint-2 | 0 | 729 |
| lint-3 | 0 | 729 |
| native-build-1 | 0 | 729 |
| native-build-2 | 0 | 729 |
| oracle-2 | 101 | 729 |
| oracle-3 | 0 | 729 |
| windows-build-1 | 0 | 729 |
| windows-build-2 | 0 | 729 |
Core-3, desktop-4, format-1, lint-2, native-build-1 and windows-build-1 share the
729-file map `55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb`.
Desktop-5, format-2, lint-3, native-build-2 and windows-build-2 share the distinct
729-file map `99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c`.
The [source identity verifier](../source/README.md) compares those maps with Git
commits `12a7352ddef5f69a144ead8219a50916233d63a9` and
`f6a6010baed9e6164a1fcc7ecd58256a562827d7`, respectively. Earlier maps retain
their own evidence scope; they are not reruns against the later source.
To validate this exact raw run list without writing a package, from the checkout
root run:
```text
python -B harness/experiments/multiselect-20260923/checks/prepare.py --root . --runs core-1 core-2 core-3 desktop-1 desktop-2 desktop-3 desktop-4 desktop-5 format-1 format-2 lint-1 lint-2 lint-3 native-build-1 native-build-2 oracle-2 oracle-3 windows-build-1 windows-build-2 --check-only
```
Missing closure, changed inputs, inconsistent receipts, unavailable exact helpers,
and extra/unexpected run files are refused. Run names must be supplied, must be
unique, and cannot contain path separators.
To create a package, use the same explicit `--runs` list, omit `--check-only`, and
optionally supply `--output PATH`. The default output is this checks directory.
An output package is not overwritten. `--helper PATH` can be repeated to supply
an older gate helper whose exact pinned bytes are no longer the current helper.
Default helper candidates are `.local/group-movement-gates/*.py`.
Verify a completed package anywhere, without the original checkout:
```text
python -B PATH_TO_PACKAGE/verify.py
```
The packager preserves the seven original files per run: started/process/result
receipts, stdout/stderr logs, the input map, and its source ZIP. It preserves the
exact helper bytes named by each receipt. Only byte-identical input maps and ZIPs
are deduplicated into hash-named capsules; their per-run logical mapping remains.
ZIP member ordering and timestamps are fixed. Raw input/log bytes are unchanged.
`manifest.json` records the explicit run list, outcomes, commands, recorded HEADs,
input counts, helper paths, logical mapping and every stored member pin.
`files.json` pins `prepare.py`, `verify.py`, this README, the manifest and archive.
The verifier checks safe exact ZIP membership (including nested source ZIPs),
every recorded byte count/hash, input counts, the 71 vendored iced_widget files,
start/process/finish order, receipt relationships, unchanged-input flags, helper
identity, and exact ordered executable-artifact records parsed from Cargo JSON
stdout. Missing JSON artifact records remain missing; they are not synthesized
from paths or inferred from a successful exit. Non-null artifact readback pins
are checked structurally; executable bytes are not included or independently
verified by this package.
The source capsules are **local historical input snapshots**, including captured
uncommitted work. A recorded HEAD alone does not identify their contents. They
are not an integrated release, a hermetic toolchain distribution, or a claim that
one run's gate applies to a later input map. Commands, paths, PIDs, times and
artifact hashes are historical receipts, not authenticated execution records.
The verifier checks their internal consistency and does not access historical
absolute paths, contact services, extract archives or rerun tests. Pin integrity
is not an external signature or proof against coordinated receipt alteration.
This package has no native interaction, focus, selection, movement, saved-model,
Undo/Redo or full #29 acceptance implication. The native evidence and its
independent evaluator belong in their separate reviewed record. The verification
summary reports captured outcomes, including failures; it does not declare the
feature or all captured gates successful.
@@ -0,0 +1,22 @@
{
"prepare.py": {
"bytes": 4818,
"sha256": "29eedcec091874b26572530517f015ab690ed1a9040abea52248e99603ba5f25"
},
"verify.py": {
"bytes": 8873,
"sha256": "c03513407073bef092d57b968f982b8ffc0c58e095f834fe7464c6a0e8454a9a"
},
"README.md": {
"bytes": 5001,
"sha256": "3f5232af2ebb12003c833e6bc6643b4858950ebf015435a9b850c6a826fe27d0"
},
"manifest.json": {
"bytes": 37083,
"sha256": "c23269443cd059895c672330720a10508ab8ecade0d3686ec3d82ff792c9b457"
},
"evidence.zip": {
"bytes": 25914867,
"sha256": "261660dd8a5e93d917c1d36cad19d1eec0b93e312d1e0dd15f9ea16f5e11c864"
}
}
@@ -0,0 +1,935 @@
{
"schema": 1,
"kind": "multiselect-cargo-gates",
"runs": {
"core-1": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--test",
"group_movement",
"--test",
"state_diagrams",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 722,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"core-2": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--test",
"group_movement",
"--test",
"state_diagrams",
"--example",
"multiselect_native",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 101,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"core-3": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--test",
"group_movement",
"--test",
"state_diagrams",
"--example",
"multiselect_native",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"desktop-1": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-desktop",
"multiselect",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 101,
"inputCount": 727,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"desktop-2": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 101,
"inputCount": 728,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"desktop-3": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"desktop-4": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"desktop-5": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--",
"--nocapture"
],
"head": "12a7352ddef5f69a144ead8219a50916233d63a9",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"format-1": {
"command": [
"cargo",
"fmt",
"--all",
"--",
"--check"
],
"head": "12a7352ddef5f69a144ead8219a50916233d63a9",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"format-2": {
"command": [
"cargo",
"fmt",
"--all",
"--",
"--check"
],
"head": "f6a6010baed9e6164a1fcc7ecd58256a562827d7",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"lint-1": {
"command": [
"cargo",
"clippy",
"--locked",
"--offline",
"-p",
"oa-core",
"-p",
"oa-desktop",
"--all-targets",
"--",
"-D",
"warnings"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 101,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"lint-2": {
"command": [
"cargo",
"clippy",
"--locked",
"--offline",
"-p",
"oa-core",
"-p",
"oa-desktop",
"--all-targets",
"--",
"-D",
"warnings"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"lint-3": {
"command": [
"cargo",
"clippy",
"--locked",
"--offline",
"-p",
"oa-core",
"-p",
"oa-desktop",
"--all-targets",
"--",
"-D",
"warnings"
],
"head": "12a7352ddef5f69a144ead8219a50916233d63a9",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"native-build-1": {
"command": [
"cargo",
"build",
"--locked",
"--offline",
"-p",
"oa-core",
"--example",
"multiselect_native",
"--message-format=json"
],
"head": "12a7352ddef5f69a144ead8219a50916233d63a9",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"native-build-2": {
"command": [
"cargo",
"build",
"--locked",
"--offline",
"-p",
"oa-core",
"--example",
"multiselect_native",
"--message-format=json"
],
"head": "f6a6010baed9e6164a1fcc7ecd58256a562827d7",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"oracle-2": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--example",
"multiselect_native",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 101,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"oracle-3": {
"command": [
"cargo",
"test",
"--locked",
"--offline",
"-p",
"oa-core",
"--example",
"multiselect_native",
"--",
"--nocapture"
],
"head": "b8685416f56e53e30bd11ecf93a54cea10ac8458",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"windows-build-1": {
"command": [
"cargo",
"build",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--bin",
"arcadia-studio",
"--message-format=json"
],
"head": "12a7352ddef5f69a144ead8219a50916233d63a9",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"windows-build-2": {
"command": [
"cargo",
"build",
"--locked",
"--offline",
"-p",
"oa-desktop",
"--bin",
"arcadia-studio",
"--message-format=json"
],
"head": "f6a6010baed9e6164a1fcc7ecd58256a562827d7",
"exitCode": 0,
"inputCount": 729,
"helper": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
}
},
"logicalFiles": {
"cargo/core-1/inputs.json": "capsules/a73d565f90b14c986e0f87a7ac3d368c93e053b7e591cffdfa20d8e81e2eae08.json",
"cargo/core-1/inputs.zip": "capsules/2dcb54b1dd51a05cdd983432b114da8a08dce326c42b6e77a6b8772e75d2282f.zip",
"cargo/core-1/process.json": "cargo/core-1/process.json",
"cargo/core-1/result.json": "cargo/core-1/result.json",
"cargo/core-1/started.json": "cargo/core-1/started.json",
"cargo/core-1/stderr.log": "cargo/core-1/stderr.log",
"cargo/core-1/stdout.log": "cargo/core-1/stdout.log",
"cargo/core-2/inputs.json": "capsules/c5b23cd340869d57bd1bc4400041d499ea06a1a7619a6fd6b51e75278c1755e1.json",
"cargo/core-2/inputs.zip": "capsules/df441a733bf28d1c59eab52063ca4b2645067b490b0a2f0072f98fc9225ea2e8.zip",
"cargo/core-2/process.json": "cargo/core-2/process.json",
"cargo/core-2/result.json": "cargo/core-2/result.json",
"cargo/core-2/started.json": "cargo/core-2/started.json",
"cargo/core-2/stderr.log": "cargo/core-2/stderr.log",
"cargo/core-2/stdout.log": "cargo/core-2/stdout.log",
"cargo/core-3/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/core-3/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/core-3/process.json": "cargo/core-3/process.json",
"cargo/core-3/result.json": "cargo/core-3/result.json",
"cargo/core-3/started.json": "cargo/core-3/started.json",
"cargo/core-3/stderr.log": "cargo/core-3/stderr.log",
"cargo/core-3/stdout.log": "cargo/core-3/stdout.log",
"cargo/desktop-1/inputs.json": "capsules/c1083b630ad79ed1fea6933de3221f05b8eb9200694fb0e5dbd637527803579c.json",
"cargo/desktop-1/inputs.zip": "capsules/8d6b08c2b1220cdb48d32cc74004cc9b82e4385f6f50a764f76c4a8630d070bf.zip",
"cargo/desktop-1/process.json": "cargo/desktop-1/process.json",
"cargo/desktop-1/result.json": "cargo/desktop-1/result.json",
"cargo/desktop-1/started.json": "cargo/desktop-1/started.json",
"cargo/desktop-1/stderr.log": "cargo/desktop-1/stderr.log",
"cargo/desktop-1/stdout.log": "cargo/desktop-1/stdout.log",
"cargo/desktop-2/inputs.json": "capsules/5f049dbbee443af86cde70efc74027f290a9bfbd434e5d644aa74ddb4e97566b.json",
"cargo/desktop-2/inputs.zip": "capsules/bf7dc41142e6d087f213b2914e0ffb0e9cd52294f5830301e5e5b78c3470f725.zip",
"cargo/desktop-2/process.json": "cargo/desktop-2/process.json",
"cargo/desktop-2/result.json": "cargo/desktop-2/result.json",
"cargo/desktop-2/started.json": "cargo/desktop-2/started.json",
"cargo/desktop-2/stderr.log": "cargo/desktop-2/stderr.log",
"cargo/desktop-2/stdout.log": "cargo/desktop-2/stdout.log",
"cargo/desktop-3/inputs.json": "capsules/6f8eae7613666bca412e62f67151d6fee9f5bd32fb50363d0ff9b9ac8b190acf.json",
"cargo/desktop-3/inputs.zip": "capsules/cc6233ddec2db0e322659a73a55e1681f5cb3554750ba183a756a29dadf8a8c9.zip",
"cargo/desktop-3/process.json": "cargo/desktop-3/process.json",
"cargo/desktop-3/result.json": "cargo/desktop-3/result.json",
"cargo/desktop-3/started.json": "cargo/desktop-3/started.json",
"cargo/desktop-3/stderr.log": "cargo/desktop-3/stderr.log",
"cargo/desktop-3/stdout.log": "cargo/desktop-3/stdout.log",
"cargo/desktop-4/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/desktop-4/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/desktop-4/process.json": "cargo/desktop-4/process.json",
"cargo/desktop-4/result.json": "cargo/desktop-4/result.json",
"cargo/desktop-4/started.json": "cargo/desktop-4/started.json",
"cargo/desktop-4/stderr.log": "cargo/desktop-4/stderr.log",
"cargo/desktop-4/stdout.log": "cargo/desktop-4/stdout.log",
"cargo/desktop-5/inputs.json": "capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json",
"cargo/desktop-5/inputs.zip": "capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip",
"cargo/desktop-5/process.json": "cargo/desktop-5/process.json",
"cargo/desktop-5/result.json": "cargo/desktop-5/result.json",
"cargo/desktop-5/started.json": "cargo/desktop-5/started.json",
"cargo/desktop-5/stderr.log": "cargo/desktop-5/stderr.log",
"cargo/desktop-5/stdout.log": "cargo/desktop-5/stdout.log",
"cargo/format-1/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/format-1/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/format-1/process.json": "cargo/format-1/process.json",
"cargo/format-1/result.json": "cargo/format-1/result.json",
"cargo/format-1/started.json": "cargo/format-1/started.json",
"cargo/format-1/stderr.log": "cargo/format-1/stderr.log",
"cargo/format-1/stdout.log": "cargo/format-1/stdout.log",
"cargo/format-2/inputs.json": "capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json",
"cargo/format-2/inputs.zip": "capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip",
"cargo/format-2/process.json": "cargo/format-2/process.json",
"cargo/format-2/result.json": "cargo/format-2/result.json",
"cargo/format-2/started.json": "cargo/format-2/started.json",
"cargo/format-2/stderr.log": "cargo/format-2/stderr.log",
"cargo/format-2/stdout.log": "cargo/format-2/stdout.log",
"cargo/lint-1/inputs.json": "capsules/292f6139450109875549801a1da337dac08a8bca4cfa0124139a5d8d042386b9.json",
"cargo/lint-1/inputs.zip": "capsules/d2ec5025067db2c05736bb1c9c9b6250d9199f1b7190e8c09f5a777424790c10.zip",
"cargo/lint-1/process.json": "cargo/lint-1/process.json",
"cargo/lint-1/result.json": "cargo/lint-1/result.json",
"cargo/lint-1/started.json": "cargo/lint-1/started.json",
"cargo/lint-1/stderr.log": "cargo/lint-1/stderr.log",
"cargo/lint-1/stdout.log": "cargo/lint-1/stdout.log",
"cargo/lint-2/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/lint-2/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/lint-2/process.json": "cargo/lint-2/process.json",
"cargo/lint-2/result.json": "cargo/lint-2/result.json",
"cargo/lint-2/started.json": "cargo/lint-2/started.json",
"cargo/lint-2/stderr.log": "cargo/lint-2/stderr.log",
"cargo/lint-2/stdout.log": "cargo/lint-2/stdout.log",
"cargo/lint-3/inputs.json": "capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json",
"cargo/lint-3/inputs.zip": "capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip",
"cargo/lint-3/process.json": "cargo/lint-3/process.json",
"cargo/lint-3/result.json": "cargo/lint-3/result.json",
"cargo/lint-3/started.json": "cargo/lint-3/started.json",
"cargo/lint-3/stderr.log": "cargo/lint-3/stderr.log",
"cargo/lint-3/stdout.log": "cargo/lint-3/stdout.log",
"cargo/native-build-1/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/native-build-1/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/native-build-1/process.json": "cargo/native-build-1/process.json",
"cargo/native-build-1/result.json": "cargo/native-build-1/result.json",
"cargo/native-build-1/started.json": "cargo/native-build-1/started.json",
"cargo/native-build-1/stderr.log": "cargo/native-build-1/stderr.log",
"cargo/native-build-1/stdout.log": "cargo/native-build-1/stdout.log",
"cargo/native-build-2/inputs.json": "capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json",
"cargo/native-build-2/inputs.zip": "capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip",
"cargo/native-build-2/process.json": "cargo/native-build-2/process.json",
"cargo/native-build-2/result.json": "cargo/native-build-2/result.json",
"cargo/native-build-2/started.json": "cargo/native-build-2/started.json",
"cargo/native-build-2/stderr.log": "cargo/native-build-2/stderr.log",
"cargo/native-build-2/stdout.log": "cargo/native-build-2/stdout.log",
"cargo/oracle-2/inputs.json": "capsules/ae16337dbc617e26b23468adb86d963e3bcf7eddf177e8fb4654c69019904548.json",
"cargo/oracle-2/inputs.zip": "capsules/e99bcaf1ab2becbcad0a005bdd0a4eb14fad2075bd7a38433857df4d3cad5e4d.zip",
"cargo/oracle-2/process.json": "cargo/oracle-2/process.json",
"cargo/oracle-2/result.json": "cargo/oracle-2/result.json",
"cargo/oracle-2/started.json": "cargo/oracle-2/started.json",
"cargo/oracle-2/stderr.log": "cargo/oracle-2/stderr.log",
"cargo/oracle-2/stdout.log": "cargo/oracle-2/stdout.log",
"cargo/oracle-3/inputs.json": "capsules/292f6139450109875549801a1da337dac08a8bca4cfa0124139a5d8d042386b9.json",
"cargo/oracle-3/inputs.zip": "capsules/d2ec5025067db2c05736bb1c9c9b6250d9199f1b7190e8c09f5a777424790c10.zip",
"cargo/oracle-3/process.json": "cargo/oracle-3/process.json",
"cargo/oracle-3/result.json": "cargo/oracle-3/result.json",
"cargo/oracle-3/started.json": "cargo/oracle-3/started.json",
"cargo/oracle-3/stderr.log": "cargo/oracle-3/stderr.log",
"cargo/oracle-3/stdout.log": "cargo/oracle-3/stdout.log",
"cargo/windows-build-1/inputs.json": "capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json",
"cargo/windows-build-1/inputs.zip": "capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip",
"cargo/windows-build-1/process.json": "cargo/windows-build-1/process.json",
"cargo/windows-build-1/result.json": "cargo/windows-build-1/result.json",
"cargo/windows-build-1/started.json": "cargo/windows-build-1/started.json",
"cargo/windows-build-1/stderr.log": "cargo/windows-build-1/stderr.log",
"cargo/windows-build-1/stdout.log": "cargo/windows-build-1/stdout.log",
"cargo/windows-build-2/inputs.json": "capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json",
"cargo/windows-build-2/inputs.zip": "capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip",
"cargo/windows-build-2/process.json": "cargo/windows-build-2/process.json",
"cargo/windows-build-2/result.json": "cargo/windows-build-2/result.json",
"cargo/windows-build-2/started.json": "cargo/windows-build-2/started.json",
"cargo/windows-build-2/stderr.log": "cargo/windows-build-2/stderr.log",
"cargo/windows-build-2/stdout.log": "cargo/windows-build-2/stdout.log",
"helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py": "helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py"
},
"members": {
"capsules/292f6139450109875549801a1da337dac08a8bca4cfa0124139a5d8d042386b9.json": {
"bytes": 121985,
"sha256": "292f6139450109875549801a1da337dac08a8bca4cfa0124139a5d8d042386b9"
},
"capsules/2dcb54b1dd51a05cdd983432b114da8a08dce326c42b6e77a6b8772e75d2282f.zip": {
"bytes": 2885634,
"sha256": "2dcb54b1dd51a05cdd983432b114da8a08dce326c42b6e77a6b8772e75d2282f"
},
"capsules/55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb.json": {
"bytes": 121985,
"sha256": "55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb"
},
"capsules/5f049dbbee443af86cde70efc74027f290a9bfbd434e5d644aa74ddb4e97566b.json": {
"bytes": 121820,
"sha256": "5f049dbbee443af86cde70efc74027f290a9bfbd434e5d644aa74ddb4e97566b"
},
"capsules/6f8eae7613666bca412e62f67151d6fee9f5bd32fb50363d0ff9b9ac8b190acf.json": {
"bytes": 121984,
"sha256": "6f8eae7613666bca412e62f67151d6fee9f5bd32fb50363d0ff9b9ac8b190acf"
},
"capsules/8d6b08c2b1220cdb48d32cc74004cc9b82e4385f6f50a764f76c4a8630d070bf.zip": {
"bytes": 2903240,
"sha256": "8d6b08c2b1220cdb48d32cc74004cc9b82e4385f6f50a764f76c4a8630d070bf"
},
"capsules/99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c.json": {
"bytes": 121985,
"sha256": "99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c"
},
"capsules/a73d565f90b14c986e0f87a7ac3d368c93e053b7e591cffdfa20d8e81e2eae08.json": {
"bytes": 120844,
"sha256": "a73d565f90b14c986e0f87a7ac3d368c93e053b7e591cffdfa20d8e81e2eae08"
},
"capsules/aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9.zip": {
"bytes": 2918930,
"sha256": "aa8bb3d7fbd1f73c36913235b0b1d3aa79f6ac418b6c07ade94a7dee4a617bd9"
},
"capsules/ae16337dbc617e26b23468adb86d963e3bcf7eddf177e8fb4654c69019904548.json": {
"bytes": 121984,
"sha256": "ae16337dbc617e26b23468adb86d963e3bcf7eddf177e8fb4654c69019904548"
},
"capsules/bf7dc41142e6d087f213b2914e0ffb0e9cd52294f5830301e5e5b78c3470f725.zip": {
"bytes": 2909281,
"sha256": "bf7dc41142e6d087f213b2914e0ffb0e9cd52294f5830301e5e5b78c3470f725"
},
"capsules/c1083b630ad79ed1fea6933de3221f05b8eb9200694fb0e5dbd637527803579c.json": {
"bytes": 121652,
"sha256": "c1083b630ad79ed1fea6933de3221f05b8eb9200694fb0e5dbd637527803579c"
},
"capsules/c5b23cd340869d57bd1bc4400041d499ea06a1a7619a6fd6b51e75278c1755e1.json": {
"bytes": 121984,
"sha256": "c5b23cd340869d57bd1bc4400041d499ea06a1a7619a6fd6b51e75278c1755e1"
},
"capsules/cc6233ddec2db0e322659a73a55e1681f5cb3554750ba183a756a29dadf8a8c9.zip": {
"bytes": 2917494,
"sha256": "cc6233ddec2db0e322659a73a55e1681f5cb3554750ba183a756a29dadf8a8c9"
},
"capsules/d2ec5025067db2c05736bb1c9c9b6250d9199f1b7190e8c09f5a777424790c10.zip": {
"bytes": 2918296,
"sha256": "d2ec5025067db2c05736bb1c9c9b6250d9199f1b7190e8c09f5a777424790c10"
},
"capsules/df441a733bf28d1c59eab52063ca4b2645067b490b0a2f0072f98fc9225ea2e8.zip": {
"bytes": 2917518,
"sha256": "df441a733bf28d1c59eab52063ca4b2645067b490b0a2f0072f98fc9225ea2e8"
},
"capsules/e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533.zip": {
"bytes": 2918309,
"sha256": "e1c7f3abe7b32616d1081b4a2bb8af2d6d4b071bc2a7cbdd61e96a92ffdc0533"
},
"capsules/e99bcaf1ab2becbcad0a005bdd0a4eb14fad2075bd7a38433857df4d3cad5e4d.zip": {
"bytes": 2917719,
"sha256": "e99bcaf1ab2becbcad0a005bdd0a4eb14fad2075bd7a38433857df4d3cad5e4d"
},
"cargo/core-1/process.json": {
"bytes": 210,
"sha256": "92e5a88b5b86400c13bad4d0a9d490466bb2ef0b6077d14930ac5084187b5506"
},
"cargo/core-1/result.json": {
"bytes": 1821,
"sha256": "c90e020e6d912516fbc5ef5b4bf6a5df5fc668e5f5e19a9108c29bf3723cea9c"
},
"cargo/core-1/started.json": {
"bytes": 1428,
"sha256": "230ea369285569a0fa179fe420b0b2133e7fcb2349601a53d69881e9a66bd39b"
},
"cargo/core-1/stderr.log": {
"bytes": 434,
"sha256": "84a1b0b7352dcde2fe51293feabbddf8e94206d9278e4a38e6d354af8a1bcd48"
},
"cargo/core-1/stdout.log": {
"bytes": 1671,
"sha256": "eb04561c11e394cc368ea1c5e38aa4b1dc8b5c3c44acb168469dd941f80f14e8"
},
"cargo/core-2/process.json": {
"bytes": 245,
"sha256": "020d6cb0ce6e4b9122ac2dcbd86c9c1719479f29d3690247182ade858caba12d"
},
"cargo/core-2/result.json": {
"bytes": 1870,
"sha256": "c97cbcd85b60a3476135bf9026d41868ea091061c12ce4bbc18a40c6023c5b3e"
},
"cargo/core-2/started.json": {
"bytes": 1473,
"sha256": "f367b289c9d378975514fa450e4fa25049f4461156417ba5bd6e79836faf401e"
},
"cargo/core-2/stderr.log": {
"bytes": 5287,
"sha256": "4ea6f38eef014ab8176c3ab1ed9d3be3addb4463a8f073425f1b5493b33a7c86"
},
"cargo/core-2/stdout.log": {
"bytes": 4138,
"sha256": "a2dfdb0d7c6c7ba7e9ef86063a815f43111188a44ae4b0e20717cc3e518b7c3d"
},
"cargo/core-3/process.json": {
"bytes": 245,
"sha256": "b26f22b0aed07e55906b024d1fd94198da1ab1d56363fc5ad66868940ae1c9a4"
},
"cargo/core-3/result.json": {
"bytes": 1867,
"sha256": "6d04a2818750491cb73ebb1b257d214316c048e1ac6165a119a27534d636406c"
},
"cargo/core-3/started.json": {
"bytes": 1473,
"sha256": "49e9d637eb063277925c577266a63e5fd06723ca24726d609dc0e458596e8316"
},
"cargo/core-3/stderr.log": {
"bytes": 539,
"sha256": "f05f7ab2f0244968100eb0e0a82808af8e42dceb5b5de70d034b7ae56bad9489"
},
"cargo/core-3/stdout.log": {
"bytes": 4797,
"sha256": "d0f2180aaecc3b253b473200b77348a19a21594e193ce45c21f040b7242be253"
},
"cargo/desktop-1/process.json": {
"bytes": 172,
"sha256": "d9ba2b6a0968b702af0aa857e7bb8667680eeddc32a0403781cd3d5e2467c067"
},
"cargo/desktop-1/result.json": {
"bytes": 1769,
"sha256": "2384c076e4bbc0e15951671e3a830725213c31cfcded0a27e1bb72802c576dbc"
},
"cargo/desktop-1/started.json": {
"bytes": 1375,
"sha256": "6b1ba478ebe5e14d5ee76199a56874a6a10156c2dd7e9d3830fd5ba5311094d6"
},
"cargo/desktop-1/stderr.log": {
"bytes": 4604,
"sha256": "6a47286c4daaf9f4ac8ac8cca3e98931f7812a44b192128aa67880c1ac930b87"
},
"cargo/desktop-1/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/desktop-2/process.json": {
"bytes": 157,
"sha256": "cc037bab1ec44bd2e4095e165597f5e1d077bae5fce7a96c6a5fd814470d4244"
},
"cargo/desktop-2/result.json": {
"bytes": 1753,
"sha256": "9c037405572273086737e22b60796eff0745f4746ee3f25529f928da53c98fbc"
},
"cargo/desktop-2/started.json": {
"bytes": 1355,
"sha256": "18f71e571722bdb3696195623b3af3a2b9a45d38f98307a68049aacff3fbad9c"
},
"cargo/desktop-2/stderr.log": {
"bytes": 1085,
"sha256": "316e0179675fb071d7d9773d7073d771438ecd70e66c99559f4239e0638a3238"
},
"cargo/desktop-2/stdout.log": {
"bytes": 145051,
"sha256": "7c907317d106ff63347456b5ad2015fa8a9974ffbb7003d0a123afc99879ce42"
},
"cargo/desktop-3/process.json": {
"bytes": 157,
"sha256": "368d265e1ee5cceeb5995172c662dc3bc551591b9600a781c63ed64579760c24"
},
"cargo/desktop-3/result.json": {
"bytes": 1751,
"sha256": "32076fb49a6ddfcef63e77ca9f1edec34700ca80d36f32890581d56035f80054"
},
"cargo/desktop-3/started.json": {
"bytes": 1355,
"sha256": "da1ccd8352380b357d5954a70d86f2c51c8a2da8d1c4b553ca7b281d3000eab9"
},
"cargo/desktop-3/stderr.log": {
"bytes": 626,
"sha256": "5333e25e78f515449877867d0a2bf714b7cb3302c9497d4f4343a1e05e0f8b03"
},
"cargo/desktop-3/stdout.log": {
"bytes": 145562,
"sha256": "dc7e40a7d2ab1e78c74f0ee0344c4b2e5b1402bc6367e93a40780774000e4f81"
},
"cargo/desktop-4/process.json": {
"bytes": 157,
"sha256": "0823d0fbda95fe5efb08a7c11c98a7ac2409b5b3d170cf2e41b702895211abf4"
},
"cargo/desktop-4/result.json": {
"bytes": 1750,
"sha256": "d88b177e9d181f7c9c3685100c8676c0c8954cd0b071344ff5b4bb7a8e498865"
},
"cargo/desktop-4/started.json": {
"bytes": 1355,
"sha256": "0f9927d5c0b09c7fcc8922c68a2c88a4d840e0420a7be90193f566b02312a3d3"
},
"cargo/desktop-4/stderr.log": {
"bytes": 628,
"sha256": "992db238282b7acf1bbfeee7f2c459f9afe4bce814761d70df789e4f6239afcf"
},
"cargo/desktop-4/stdout.log": {
"bytes": 145802,
"sha256": "70c38e8c98cac4f220999481908beb549e5377f6f48c31931f9412ed25a67a41"
},
"cargo/desktop-5/process.json": {
"bytes": 157,
"sha256": "83bf9efc58fa5692f3ed038c107c081e5483d91117c73eddba62d3eb45cc7267"
},
"cargo/desktop-5/result.json": {
"bytes": 1751,
"sha256": "7cbbae8bbceec07cebb4696b999701cd29d46bfd047351aa3e20ea49d7c67ae6"
},
"cargo/desktop-5/started.json": {
"bytes": 1355,
"sha256": "0bfd2a6c185afb1b301e3b6b5f746d0e37251f147590aa2e9f25e370e99f53e8"
},
"cargo/desktop-5/stderr.log": {
"bytes": 631,
"sha256": "466f26c41956ed05629b633827d7ffca497c57c87ff67acff6351043c7bdefd4"
},
"cargo/desktop-5/stdout.log": {
"bytes": 146577,
"sha256": "e89cf5f2375fd40ae70261471d797cbaca5127cb27730e6094a616afa12514ae"
},
"cargo/format-1/process.json": {
"bytes": 116,
"sha256": "bb8e0a7620b40bb5f0932643848a57b0d207dde39006a9a20141c00f13d94284"
},
"cargo/format-1/result.json": {
"bytes": 1687,
"sha256": "967eeddb3fc6a0dc0fdf9a75f575d75fa8f8b0b5ea9c8a422590bcbece6de77b"
},
"cargo/format-1/started.json": {
"bytes": 1299,
"sha256": "ceb354dfbc4a41d72e496342e28475ddcce5a3c17a4e1553f0d699404c374657"
},
"cargo/format-1/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/format-1/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/format-2/process.json": {
"bytes": 116,
"sha256": "aa31b91d224845b7dd1df777e865c88c5b8f55b66f173053be318132d1bc3870"
},
"cargo/format-2/result.json": {
"bytes": 1687,
"sha256": "c4d5529c8d2feae1b805bd8d404a3817053a5a0cd4ec341aa8c1e0a5c05eed5b"
},
"cargo/format-2/started.json": {
"bytes": 1299,
"sha256": "2ea70bb29d7fef73a194acd7aa36836fd4a54ae8a4be173f919cd2fc32e97919"
},
"cargo/format-2/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/format-2/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/lint-1/process.json": {
"bytes": 196,
"sha256": "d30e400277dc0bb4a1618689b16ab86be7838cc1b42688185d655df235080286"
},
"cargo/lint-1/result.json": {
"bytes": 1808,
"sha256": "7ffb361d398def4520afc48683a69effbb8b066efd9442ba3b356c8124aae6d9"
},
"cargo/lint-1/started.json": {
"bytes": 1414,
"sha256": "771b5bdc31662fb3b4f76735e92b0e89d31a02188fbce35c5cfb0aea4c37c0ca"
},
"cargo/lint-1/stderr.log": {
"bytes": 1023,
"sha256": "9cbab357d810ce8164a0e614491f53529e61c1cad79793ca429e13897a8dc5ed"
},
"cargo/lint-1/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/lint-2/process.json": {
"bytes": 196,
"sha256": "f4aed65014ed120dc72bd08160559ae0285bc5c4968305a5fb86cf29e8c0d347"
},
"cargo/lint-2/result.json": {
"bytes": 1805,
"sha256": "b873add4777fd8f7516513e2423f9d3eb4a40505a3b1fa7edfbee89fb5c7e0d3"
},
"cargo/lint-2/started.json": {
"bytes": 1414,
"sha256": "0d01a20ec0f7cd796c066c95936c74df0abf8947fca655d900a5bdd4f8dbd610"
},
"cargo/lint-2/stderr.log": {
"bytes": 207,
"sha256": "e6f76746d5864a4de1e9d238c74799e2080e2c6214f51b68a4692d5e15f5b107"
},
"cargo/lint-2/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/lint-3/process.json": {
"bytes": 196,
"sha256": "620094b52dab8f23f389687cf72b8b3aa4effa55697842206a618293537eb869"
},
"cargo/lint-3/result.json": {
"bytes": 1805,
"sha256": "1e7dc472c03d653094850ed653599cee41e50d1639389bbc3fee45e40a754b5c"
},
"cargo/lint-3/started.json": {
"bytes": 1414,
"sha256": "b921ee7102386187c288c1b25aea96a3019ff00a4a508065aefbc4499b7c7818"
},
"cargo/lint-3/stderr.log": {
"bytes": 137,
"sha256": "d19e47547a69ce7956c74f2a65cd1064571985d073bcf497a11a0b0eebcfbd04"
},
"cargo/lint-3/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/native-build-1/process.json": {
"bytes": 194,
"sha256": "390cb979d680b9fdb7e0afa05d6b9d10a25dc27abaff16596d113bb0b2142b43"
},
"cargo/native-build-1/result.json": {
"bytes": 3132,
"sha256": "35f76499ac2a49446b896932c963fd8734a5755e00e3511cedf1e584e7b17704"
},
"cargo/native-build-1/started.json": {
"bytes": 1397,
"sha256": "5f37fc095aa00eae8fae043651a29f387f484bf4a0cc454e3919ea4f49567126"
},
"cargo/native-build-1/stderr.log": {
"bytes": 130,
"sha256": "731d61ee089d75c107edcd02d2cdedcddaad57ec06607ccd0822d9dc71a72720"
},
"cargo/native-build-1/stdout.log": {
"bytes": 41700,
"sha256": "832dc599cad2c9ba28ff9153537fb428390d8f25959f5b4a080cd432f6bea0e8"
},
"cargo/native-build-2/process.json": {
"bytes": 194,
"sha256": "46ff130840d8b12272be43f479adeb0b2ace94ee1d5389c5638a61b22d732496"
},
"cargo/native-build-2/result.json": {
"bytes": 3131,
"sha256": "fbecac3b0f7913db5e2ad19043c7df167a92287833ddf3ea4f24766e86ae523b"
},
"cargo/native-build-2/started.json": {
"bytes": 1397,
"sha256": "cbd2c7ad98baddc3719a5c03bef103747d4cb5c560d631376149f116ede49584"
},
"cargo/native-build-2/stderr.log": {
"bytes": 60,
"sha256": "b2558545bbfa50a0f0c26623c0982eb5f96d71ea228d7c56180edbac0d0b295d"
},
"cargo/native-build-2/stdout.log": {
"bytes": 41699,
"sha256": "7884b8ea1a92d58c7174657560ec38ff9a073e52f93cc19a78290840f2ab5486"
},
"cargo/oracle-2/process.json": {
"bytes": 189,
"sha256": "1e8ffd7a03b22bf2ec43b0d66ae3cc98016a431c4a07499faf3ca0c635b92337"
},
"cargo/oracle-2/result.json": {
"bytes": 1789,
"sha256": "e0b7331751bae8564ee5c28d05029071f1c8460195e6f9e2f0d00a5ae4e05a16"
},
"cargo/oracle-2/started.json": {
"bytes": 1397,
"sha256": "b7a8278dfa2324f0c3ff6e9616a65ef7a51c99699ad700adfe90e2accc435765"
},
"cargo/oracle-2/stderr.log": {
"bytes": 520,
"sha256": "9dd8b849afdbbb2207a9ad82f1b6c6f07fd9cd0846fe4591f33c40fdadcbb3ac"
},
"cargo/oracle-2/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"cargo/oracle-3/process.json": {
"bytes": 189,
"sha256": "a2cb30f512ee390bb03c9fcf5ea8069ca3a05da91f798985efc3f9f54670ace4"
},
"cargo/oracle-3/result.json": {
"bytes": 1791,
"sha256": "f0768fecc9f6711dd3cfc627c60aaf6118216bce47e76faa4cbdda571ac675e4"
},
"cargo/oracle-3/started.json": {
"bytes": 1397,
"sha256": "30cf614b6dede363ae4bdeca56fc4a1ddb7ee19a7e592b1b1616d4a98a53b535"
},
"cargo/oracle-3/stderr.log": {
"bytes": 307,
"sha256": "b4ccc583c5001d81b7208fe6f2e52788d0d40b63c7da034ca1fb90ec2adb18a4"
},
"cargo/oracle-3/stdout.log": {
"bytes": 2968,
"sha256": "e0a62ca8b008370c5a41378eb4c9e2a229a2fcde7bdba55426313c7d23da8aca"
},
"cargo/windows-build-1/process.json": {
"bytes": 189,
"sha256": "4e6b57dc0d5f10ac1b4af991f8b0f7558f4fc5b626e00f1a49c5782ea13abe18"
},
"cargo/windows-build-1/result.json": {
"bytes": 3082,
"sha256": "3cdd09a859288afe71dde6fb51bcc4bca84e47ceb9cb6389d57f6722d9e23fdf"
},
"cargo/windows-build-1/started.json": {
"bytes": 1392,
"sha256": "a3ebcdffc01e93fd5609005a0539eb11bf473b45bc28eee71dd175b943b387eb"
},
"cargo/windows-build-1/stderr.log": {
"bytes": 319,
"sha256": "7201ff3f71fe793907482992a00682023fc6ee1ac0a016f53a048b299ec2fffd"
},
"cargo/windows-build-1/stdout.log": {
"bytes": 284182,
"sha256": "3fc90b8c923415496c7990d33a5fe7211423b83df833a80111079fad71f04a2d"
},
"cargo/windows-build-2/process.json": {
"bytes": 189,
"sha256": "f18acb4c9feede438e1aa67bb86ce2d74f5b3aa0142499ae99b56b23daaf834b"
},
"cargo/windows-build-2/result.json": {
"bytes": 3081,
"sha256": "d7b191ee07c302ffed1017374b0c5d8b86245c0f3348fbac4778ae573397b9de"
},
"cargo/windows-build-2/started.json": {
"bytes": 1392,
"sha256": "b6a6656d966559060f01e87ccbd75837b0cf67e70c77246b20f587167bdbf651"
},
"cargo/windows-build-2/stderr.log": {
"bytes": 137,
"sha256": "aafe81cdd7c1e5558e957d4296d46e3238c72af79ba79d6147c5cc16f938d6ef"
},
"cargo/windows-build-2/stdout.log": {
"bytes": 284179,
"sha256": "cfba733cb79a9496004109bb0bc8b8996df5ec1645691fd79b952063faa519c5"
},
"helpers/6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06.py": {
"bytes": 3502,
"sha256": "6b8fcf64a1eb0869ae29abd66b4e89564a1813fef5898b54f2a17a3230dbaa06"
}
}
}
@@ -0,0 +1,90 @@
"""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):
gates = root / ".local/group-movement-gates"
candidates = sorted(gates.glob("*.py")) + helpers
helper_bytes = [path.read_bytes() for path in candidates]
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
for run in runs:
folder = gates / run
need(folder.is_dir(), "run directory missing: " + run)
paths = list(folder.iterdir())
need(all(path.is_file() and not path.is_symlink() for path in paths)
and {path.name for path in paths} == RAW_FILES, "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
manifest = {"schema": 1, "kind": "multiselect-cargo-gates", "runs": specs,
"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, default=HERE.parents[3], help="checkout holding .local/group-movement-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("--output", type=Path, default=HERE, help="package directory; existing evidence is never overwritten")
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")
payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper)
if args.check_only:
print("PASS raw consistency; no package written:", summary)
return
out = args.output.resolve()
out.mkdir(parents=True, exist_ok=True)
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,164 @@
"""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"] == "multiselect-cargo-gates", "manifest schema")
runs, logical, stored = manifest["runs"], manifest["logicalFiles"], manifest["members"]
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())
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])
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")
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), "logicalFiles": len(logical), "storedMembers": len(stored), "sourceCapsulePairs": len(seen_capsules)}
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,35 @@
# Run-2 baseline checker environment incident
The first baseline checker invocation exited `3221225781` (`0xC0000135`) at
2026-09-23 09:07:10 UTC with empty stdout/stderr. The parent reported that this
shell omitted dot-sourcing the toolchain `env.ps1`. After that environment setup,
the same checker command succeeded at 09:08:08 UTC with a complete-Project PASS.
This records a checker-process launch incident, not a failure of the running GUI.
No particular missing DLL was measured or identified.
`run-2-baseline-runtime-environment/` is an exact copy of the failed snapshot:
started/result receipts, empty streams and all nine source files. Its unchanged
command text still names the original `run-2/snapshots/baseline` location; the
parent moved the failed directory aside before retrying. Paths in these records
are historical labels and have not been rewritten.
`retry-baseline/` preserves the successful retry's original started/result
receipts and streams. Direct comparison confirmed identical command, build
receipt, binary, helper, baseline and source pins between attempts. All three
unchanged flags are true in both results. The nine retry source files were
also compared byte for byte with the failed snapshot and are identical; they
are not duplicated here. The successful run's complete snapshots belong in the
separate native evidence package.
`helpers/check-snapshot-2.py` matches the helper pin in both receipts.
`helpers/env.ps1` preserves the environment setup script available when this
incident was packaged. It sets toolchain paths and runtime search paths and
contains no credentials. The checker receipts do not record the environment or
pin `env.ps1`, so the omitted/setup distinction is the parent's invocation
observation, not an independently measured environment comparison. Both scripts
are historical data; this package does not execute them.
The checker binary pin in both attempts is
`4de47a2b62192be6a1394e654f368be19e36fb966d60d6c833a5d51d18247bb1`.
`files.json` pins every included file except itself. Raw bytes are preserved.
No frozen checks, source-identity or native packaging tools were changed.
@@ -0,0 +1,82 @@
{
"helpers/check-snapshot-2.py": {
"bytes": 2494,
"sha256": "1dbfff41f07bd750d4e550660d91ae9790d2442fbfe685dc88b7f63a47f5acb8"
},
"helpers/env.ps1": {
"bytes": 621,
"sha256": "d7eb6249bef73adacdb05cebefe7ca478758c3c38de17a1731bf01f8b25dc379"
},
"README.md": {
"bytes": 2146,
"sha256": "d5a853c62713a6c87d28acfbe28c03bd95459275d0a2eb752d978e5a9b427bc8"
},
"retry-baseline/result.json": {
"bytes": 2758,
"sha256": "ae16cbc54bf5b6054750ef082f47bf0a26ee2dfb7bce46f19c8fd2c1ac622d7f"
},
"retry-baseline/started.json": {
"bytes": 2356,
"sha256": "e172a36f0872d49a8fe0f7200fb56d597b71fd1849dc9902d53ac1813a3c7d4a"
},
"retry-baseline/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"retry-baseline/stdout.log": {
"bytes": 441,
"sha256": "12842cc4e483e2546f5c8615b17fe72c5fe07f3fb4440469071433c82d9a9b30"
},
"run-2-baseline-runtime-environment/result.json": {
"bytes": 2765,
"sha256": "539b950952461cc300876dbc45fa9ee02a9ecefb6d712fce6b74bad3fa701b30"
},
"run-2-baseline-runtime-environment/source/oa/activities/activity_activity_a.arcadia": {
"bytes": 474,
"sha256": "9bf7c5637d87c97213cf869118e942e8a29a67b429fa58e4de42235bba0980ee"
},
"run-2-baseline-runtime-environment/source/oa/activities/activity_activity_b.arcadia": {
"bytes": 286,
"sha256": "152007669b7c570674aff99615a48a6f557be50f88bbbb3a5edc20b423c79a1f"
},
"run-2-baseline-runtime-environment/source/oa/activities/activity_activity_c.arcadia": {
"bytes": 153,
"sha256": "d726b6b4e1200edd9ef752bb767e38d3d69dcac8eb6135d5f83c93832ff849b1"
},
"run-2-baseline-runtime-environment/source/project.arcadia": {
"bytes": 597,
"sha256": "e7bd67c5785a78766298255ed3d53ff6d65dcd24bde1570ac8a0ff45cc9dc385"
},
"run-2-baseline-runtime-environment/source/sa/functions/function_sa_function.arcadia": {
"bytes": 162,
"sha256": "1c724a9204784435e729badd4ad164b1a6b891840bb1ddc354ac1e175e3d712c"
},
"run-2-baseline-runtime-environment/source/traceability.arcadia": {
"bytes": 522,
"sha256": "26b0b10715ced7aefcde941e6d1c1a6973f174997eae989e32a25c695dfb7cd1"
},
"run-2-baseline-runtime-environment/source/views/diagram_oa_other.arcadia": {
"bytes": 315,
"sha256": "06ceef9cfdbb3ef229a22db6c48d8bb808388e027c37294648555ecbfb6bfab9"
},
"run-2-baseline-runtime-environment/source/views/diagram_oa_view.arcadia": {
"bytes": 1896,
"sha256": "4e7d47d6a03153070687136c89faf01fc6df45ae89e2695beeab2fe4872dbc88"
},
"run-2-baseline-runtime-environment/source/views/diagram_sa_view.arcadia": {
"bytes": 331,
"sha256": "c75b0fe14496631c9b017a32e277d1e5ad5b25e00e06b804fc54d950d7fb57f6"
},
"run-2-baseline-runtime-environment/started.json": {
"bytes": 2356,
"sha256": "338c14c7dc827bd4ab09009bb974ad3c481b07cdbad2437f5291b1ff67b5ba42"
},
"run-2-baseline-runtime-environment/stderr.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"run-2-baseline-runtime-environment/stdout.log": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
@@ -0,0 +1,41 @@
"""Copy stable native-saved source and check its complete Project independently."""
from pathlib import Path
import datetime, hashlib, json, re, shutil, subprocess, sys
root = Path('C:/ar-multiselect-9e8r6t')
native = root / '.local/multiselect-native'
label, mode, *rest = sys.argv[1:]
assert not rest and re.fullmatch('[a-z0-9-]+', label)
working = native / 'working-2'
out = native / 'run-2/snapshots' / label
out.mkdir(parents=True, exist_ok=False)
gate_path = root / '.local/group-movement-gates/native-build-2/result.json'
gate = json.loads(gate_path.read_bytes())
assert gate['exitCode'] == 0 and gate['inputsUnchanged']
artifact, = [a for a in gate['artifacts'] if a['cargo']['target']['name'] == 'multiselect_native']
binary = Path(artifact['cargo']['executable'])
baseline = native / 'fixture-2/baseline.json'
def pin(path):
b = path.read_bytes()
return {'bytes': len(b), 'sha256': hashlib.sha256(b).hexdigest()}
def inventory():
return {p.relative_to(working).as_posix():pin(p) for p in sorted(working.rglob('*.arcadia')) if p.is_file()}
def now(): return datetime.datetime.now(datetime.timezone.utc).isoformat()
before = inventory()
assert 'project.arcadia' in before and pin(binary) == artifact['readback']
for name in before:
target = out/'source'/name
target.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(working/name, target)
assert before == inventory() == {name:pin(out/'source'/name) for name in before}
command = [str(binary), 'check', mode, str(baseline), str(out/'source/project.arcadia')]
start = {'start':now(), 'command':command, 'buildReceipt':pin(gate_path), 'binary':pin(binary), 'helper':pin(Path(__file__)), 'source':before, 'baseline':pin(baseline)}
(out/'started.json').write_text(json.dumps(start,indent=2),encoding='utf-8')
r = subprocess.run(command,cwd=root,capture_output=True)
(out/'stdout.log').write_bytes(r.stdout)
(out/'stderr.log').write_bytes(r.stderr)
result = {**start, 'finish':now(), 'exitCode':r.returncode, 'binaryUnchanged':pin(binary)==artifact['readback'], 'workingSourceUnchanged':before==inventory(), 'baselineUnchanged':pin(baseline)==start['baseline'], 'stdout':pin(out/'stdout.log'), 'stderr':pin(out/'stderr.log')}
(out/'result.json').write_text(json.dumps(result,indent=2),encoding='utf-8')
print(r.stdout.decode(errors='replace'))
print(r.stderr.decode(errors='replace'))
assert result['binaryUnchanged'] and result['workingSourceUnchanged'] and result['baselineUnchanged']
sys.exit(r.returncode)
@@ -0,0 +1,9 @@
$taskRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$env:RUSTUP_HOME = Join-Path $taskRoot '.local\toolchain\rustup'
$env:CARGO_HOME = Join-Path $taskRoot '.local\toolchain\cargo'
$env:RUSTUP_TOOLCHAIN = 'stable-x86_64-pc-windows-gnullvm'
$env:PATH = "$env:CARGO_HOME\bin;$(Join-Path $taskRoot '.local\toolchain\llvm-mingw-20260826-ucrt-x86_64\bin');$env:PATH"
$env:CARGO_TARGET_DIR = Join-Path $taskRoot '.local\target-gnullvm'
# Keep this small development disk from accumulating multi-GiB incremental caches.
$env:CARGO_INCREMENTAL = '0'
$env:CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_LINKER = 'clang.exe'
@@ -0,0 +1,77 @@
{
"start": "2026-09-23T09:08:07.906733+00:00",
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\examples\\multiselect_native.exe",
"check",
"unchanged",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\fixture-2\\baseline.json",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\run-2\\snapshots\\baseline\\source\\project.arcadia"
],
"buildReceipt": {
"bytes": 3131,
"sha256": "fbecac3b0f7913db5e2ad19043c7df167a92287833ddf3ea4f24766e86ae523b"
},
"binary": {
"bytes": 22162432,
"sha256": "4de47a2b62192be6a1394e654f368be19e36fb966d60d6c833a5d51d18247bb1"
},
"helper": {
"bytes": 2494,
"sha256": "1dbfff41f07bd750d4e550660d91ae9790d2442fbfe685dc88b7f63a47f5acb8"
},
"source": {
"oa/activities/activity_activity_a.arcadia": {
"bytes": 474,
"sha256": "9bf7c5637d87c97213cf869118e942e8a29a67b429fa58e4de42235bba0980ee"
},
"oa/activities/activity_activity_b.arcadia": {
"bytes": 286,
"sha256": "152007669b7c570674aff99615a48a6f557be50f88bbbb3a5edc20b423c79a1f"
},
"oa/activities/activity_activity_c.arcadia": {
"bytes": 153,
"sha256": "d726b6b4e1200edd9ef752bb767e38d3d69dcac8eb6135d5f83c93832ff849b1"
},
"project.arcadia": {
"bytes": 597,
"sha256": "e7bd67c5785a78766298255ed3d53ff6d65dcd24bde1570ac8a0ff45cc9dc385"
},
"sa/functions/function_sa_function.arcadia": {
"bytes": 162,
"sha256": "1c724a9204784435e729badd4ad164b1a6b891840bb1ddc354ac1e175e3d712c"
},
"traceability.arcadia": {
"bytes": 522,
"sha256": "26b0b10715ced7aefcde941e6d1c1a6973f174997eae989e32a25c695dfb7cd1"
},
"views/diagram_oa_other.arcadia": {
"bytes": 315,
"sha256": "06ceef9cfdbb3ef229a22db6c48d8bb808388e027c37294648555ecbfb6bfab9"
},
"views/diagram_oa_view.arcadia": {
"bytes": 1896,
"sha256": "4e7d47d6a03153070687136c89faf01fc6df45ae89e2695beeab2fe4872dbc88"
},
"views/diagram_sa_view.arcadia": {
"bytes": 331,
"sha256": "c75b0fe14496631c9b017a32e277d1e5ad5b25e00e06b804fc54d950d7fb57f6"
}
},
"baseline": {
"bytes": 8944,
"sha256": "d1278e58cd31e1d61093292eddc1d7b2cc9c8cdc7fe5dd3801de8411af8db89d"
},
"finish": "2026-09-23T09:08:08.158861+00:00",
"exitCode": 0,
"binaryUnchanged": true,
"workingSourceUnchanged": true,
"baselineUnchanged": true,
"stdout": {
"bytes": 441,
"sha256": "12842cc4e483e2546f5c8615b17fe72c5fe07f3fb4440469071433c82d9a9b30"
},
"stderr": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
@@ -0,0 +1,64 @@
{
"start": "2026-09-23T09:08:07.906733+00:00",
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\examples\\multiselect_native.exe",
"check",
"unchanged",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\fixture-2\\baseline.json",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\run-2\\snapshots\\baseline\\source\\project.arcadia"
],
"buildReceipt": {
"bytes": 3131,
"sha256": "fbecac3b0f7913db5e2ad19043c7df167a92287833ddf3ea4f24766e86ae523b"
},
"binary": {
"bytes": 22162432,
"sha256": "4de47a2b62192be6a1394e654f368be19e36fb966d60d6c833a5d51d18247bb1"
},
"helper": {
"bytes": 2494,
"sha256": "1dbfff41f07bd750d4e550660d91ae9790d2442fbfe685dc88b7f63a47f5acb8"
},
"source": {
"oa/activities/activity_activity_a.arcadia": {
"bytes": 474,
"sha256": "9bf7c5637d87c97213cf869118e942e8a29a67b429fa58e4de42235bba0980ee"
},
"oa/activities/activity_activity_b.arcadia": {
"bytes": 286,
"sha256": "152007669b7c570674aff99615a48a6f557be50f88bbbb3a5edc20b423c79a1f"
},
"oa/activities/activity_activity_c.arcadia": {
"bytes": 153,
"sha256": "d726b6b4e1200edd9ef752bb767e38d3d69dcac8eb6135d5f83c93832ff849b1"
},
"project.arcadia": {
"bytes": 597,
"sha256": "e7bd67c5785a78766298255ed3d53ff6d65dcd24bde1570ac8a0ff45cc9dc385"
},
"sa/functions/function_sa_function.arcadia": {
"bytes": 162,
"sha256": "1c724a9204784435e729badd4ad164b1a6b891840bb1ddc354ac1e175e3d712c"
},
"traceability.arcadia": {
"bytes": 522,
"sha256": "26b0b10715ced7aefcde941e6d1c1a6973f174997eae989e32a25c695dfb7cd1"
},
"views/diagram_oa_other.arcadia": {
"bytes": 315,
"sha256": "06ceef9cfdbb3ef229a22db6c48d8bb808388e027c37294648555ecbfb6bfab9"
},
"views/diagram_oa_view.arcadia": {
"bytes": 1896,
"sha256": "4e7d47d6a03153070687136c89faf01fc6df45ae89e2695beeab2fe4872dbc88"
},
"views/diagram_sa_view.arcadia": {
"bytes": 331,
"sha256": "c75b0fe14496631c9b017a32e277d1e5ad5b25e00e06b804fc54d950d7fb57f6"
}
},
"baseline": {
"bytes": 8944,
"sha256": "d1278e58cd31e1d61093292eddc1d7b2cc9c8cdc7fe5dd3801de8411af8db89d"
}
}
@@ -0,0 +1,9 @@
{
"baseline": "C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\fixture-2\\baseline.json",
"comparison": "complete Project equality",
"inferred_common_delta": null,
"limits": "Invariant evaluator only; no pointer/action/focus/Undo/source-byte acceptance claim",
"mode": "unchanged",
"result": "PASS",
"saved": "C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\run-2\\snapshots\\baseline\\source\\project.arcadia"
}
@@ -0,0 +1,77 @@
{
"start": "2026-09-23T09:07:10.546708+00:00",
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\examples\\multiselect_native.exe",
"check",
"unchanged",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\fixture-2\\baseline.json",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\run-2\\snapshots\\baseline\\source\\project.arcadia"
],
"buildReceipt": {
"bytes": 3131,
"sha256": "fbecac3b0f7913db5e2ad19043c7df167a92287833ddf3ea4f24766e86ae523b"
},
"binary": {
"bytes": 22162432,
"sha256": "4de47a2b62192be6a1394e654f368be19e36fb966d60d6c833a5d51d18247bb1"
},
"helper": {
"bytes": 2494,
"sha256": "1dbfff41f07bd750d4e550660d91ae9790d2442fbfe685dc88b7f63a47f5acb8"
},
"source": {
"oa/activities/activity_activity_a.arcadia": {
"bytes": 474,
"sha256": "9bf7c5637d87c97213cf869118e942e8a29a67b429fa58e4de42235bba0980ee"
},
"oa/activities/activity_activity_b.arcadia": {
"bytes": 286,
"sha256": "152007669b7c570674aff99615a48a6f557be50f88bbbb3a5edc20b423c79a1f"
},
"oa/activities/activity_activity_c.arcadia": {
"bytes": 153,
"sha256": "d726b6b4e1200edd9ef752bb767e38d3d69dcac8eb6135d5f83c93832ff849b1"
},
"project.arcadia": {
"bytes": 597,
"sha256": "e7bd67c5785a78766298255ed3d53ff6d65dcd24bde1570ac8a0ff45cc9dc385"
},
"sa/functions/function_sa_function.arcadia": {
"bytes": 162,
"sha256": "1c724a9204784435e729badd4ad164b1a6b891840bb1ddc354ac1e175e3d712c"
},
"traceability.arcadia": {
"bytes": 522,
"sha256": "26b0b10715ced7aefcde941e6d1c1a6973f174997eae989e32a25c695dfb7cd1"
},
"views/diagram_oa_other.arcadia": {
"bytes": 315,
"sha256": "06ceef9cfdbb3ef229a22db6c48d8bb808388e027c37294648555ecbfb6bfab9"
},
"views/diagram_oa_view.arcadia": {
"bytes": 1896,
"sha256": "4e7d47d6a03153070687136c89faf01fc6df45ae89e2695beeab2fe4872dbc88"
},
"views/diagram_sa_view.arcadia": {
"bytes": 331,
"sha256": "c75b0fe14496631c9b017a32e277d1e5ad5b25e00e06b804fc54d950d7fb57f6"
}
},
"baseline": {
"bytes": 8944,
"sha256": "d1278e58cd31e1d61093292eddc1d7b2cc9c8cdc7fe5dd3801de8411af8db89d"
},
"finish": "2026-09-23T09:07:10.828848+00:00",
"exitCode": 3221225781,
"binaryUnchanged": true,
"workingSourceUnchanged": true,
"baselineUnchanged": true,
"stdout": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
"stderr": {
"bytes": 0,
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
}
@@ -0,0 +1,14 @@
oa_activity activity_a "A - receive request" id "f0149281-4798-58d3-acff-131eed250959" {
description "Preserve engineering record activity_a.";
}
oa_activity activity_child "A.1 - classify request" id "5a80d3af-c7ee-59eb-9680-eb80d60cb94f" {
description "Preserve engineering record activity_child.";
parent @activity_a;
}
interaction internal "Request assessment" id "be7a39d9-3463-534e-b37b-76a74077d434" {
source @activity_a;
target @activity_b;
}
@@ -0,0 +1,9 @@
oa_activity activity_b "B - assess request" id "ecf076b7-e8be-5f64-8808-6a2edae5b9e2" {
description "Preserve engineering record activity_b.";
}
interaction external "Response decision" id "927dfa82-40d2-5c5f-a525-6a884725ea1d" {
source @activity_b;
target @activity_c;
}
@@ -0,0 +1,4 @@
oa_activity activity_c "C - dispatch response" id "3b258d00-854d-5ddd-a057-16eedbe31714" {
description "Preserve engineering record activity_c.";
}
@@ -0,0 +1,12 @@
arcadia 7;
project multiselect_native "Multiselect native" id "c1deb118-0fb0-5692-8b80-d24339e5b6c3" {
description "Shift-select A and B; move together, retain C and engineering semantics.";
include "oa/activities/activity_activity_a.arcadia";
include "oa/activities/activity_activity_b.arcadia";
include "oa/activities/activity_activity_c.arcadia";
include "sa/functions/function_sa_function.arcadia";
include "traceability.arcadia";
include "views/diagram_oa_other.arcadia";
include "views/diagram_oa_view.arcadia";
include "views/diagram_sa_view.arcadia";
}
@@ -0,0 +1,4 @@
sa_function sa_function "Technical request processing" id "878a1b33-a7c2-5a68-a8b6-d8273c6354e0" {
description "Preserve engineering record sa_function.";
}
@@ -0,0 +1,16 @@
trace preserved_refinement "Reviewed request refinement" id "b42fb6e3-db90-5349-b957-faeba373ba91" {
baseline {
oa {
description "Preserve engineering record activity_a.";
name "A - receive request";
};
sa {
description "Preserve engineering record sa_function.";
name "Technical request processing";
};
};
description "Group geometry and Hide preserve this trace and both endpoints.";
oa @activity_a;
sa @sa_function;
}
@@ -0,0 +1,13 @@
diagram oa_other "Other OA view - preserve" id "c4a58011-d2d7-59b1-ad58-feacef0e2d78" {
description "Selection changes placement geometry only.";
}
node other_a id "9aa9a68b-4c26-5d21-bc35-63d3f0f311d6" {
diagram @oa_other;
element @activity_a;
position {
x 40.0;
y 60.0;
};
}
@@ -0,0 +1,93 @@
diagram oa_view "Multiselect native - OA overview" id "00000000-0000-0000-0000-000000290001" {
description "Selection changes placement geometry only.";
routes [{
edge @internal;
label {
fraction 0.44999998807907104;
offset {
x 7.0;
y -19.0;
};
};
source_attachment {
offset 0.25;
side Right;
};
target_attachment {
offset 0.699999988079071;
side Left;
};
waypoints [{
x 420.0;
y 145.0;
}, {
x 420.0;
y 186.0;
}];
}, {
edge @external;
label {
fraction 0.44999998807907104;
offset {
x 7.0;
y -19.0;
};
};
source_attachment {
offset 0.25;
side Right;
};
target_attachment {
offset 0.699999988079071;
side Left;
};
waypoints [{
x 725.0;
y 150.0;
}, {
x 725.0;
y 336.0;
}];
}];
}
node node_a id "2670dd46-9fe7-5047-b13d-59817cff96dd" {
diagram @oa_view;
element @activity_a;
position {
x 80.0;
y 80.0;
};
size {
height 260.0;
width 310.0;
};
}
node node_b id "70e322db-f401-58c8-a50e-2f71c61ad721" {
diagram @oa_view;
element @activity_b;
position {
x 470.0;
y 120.0;
};
}
node node_c id "d6b89a5a-6e2f-50f9-9d1e-993304a54583" {
diagram @oa_view;
element @activity_c;
position {
x 780.0;
y 270.0;
};
}
node node_child id "87f4652b-15ef-55ed-ad7e-cc5d22b7facb" {
diagram @oa_view;
element @activity_child;
position {
x 120.0;
y 210.0;
};
}
@@ -0,0 +1,14 @@
diagram sa_view "SA engineering - preserve" id "637b9a3e-bd74-534c-9be5-4470a408729f" {
description "Selection changes placement geometry only.";
layer Sa;
}
node sa_node id "5f1b1c24-0583-5923-a69c-d0ea99ccb18c" {
diagram @sa_view;
element @sa_function;
position {
x 100.0;
y 110.0;
};
}
@@ -0,0 +1,64 @@
{
"start": "2026-09-23T09:07:10.546708+00:00",
"command": [
"C:\\Users\\User\\Documents\\Git\\ARCADIA-Studio\\.local\\target-gnullvm\\debug\\examples\\multiselect_native.exe",
"check",
"unchanged",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\fixture-2\\baseline.json",
"C:\\ar-multiselect-9e8r6t\\.local\\multiselect-native\\run-2\\snapshots\\baseline\\source\\project.arcadia"
],
"buildReceipt": {
"bytes": 3131,
"sha256": "fbecac3b0f7913db5e2ad19043c7df167a92287833ddf3ea4f24766e86ae523b"
},
"binary": {
"bytes": 22162432,
"sha256": "4de47a2b62192be6a1394e654f368be19e36fb966d60d6c833a5d51d18247bb1"
},
"helper": {
"bytes": 2494,
"sha256": "1dbfff41f07bd750d4e550660d91ae9790d2442fbfe685dc88b7f63a47f5acb8"
},
"source": {
"oa/activities/activity_activity_a.arcadia": {
"bytes": 474,
"sha256": "9bf7c5637d87c97213cf869118e942e8a29a67b429fa58e4de42235bba0980ee"
},
"oa/activities/activity_activity_b.arcadia": {
"bytes": 286,
"sha256": "152007669b7c570674aff99615a48a6f557be50f88bbbb3a5edc20b423c79a1f"
},
"oa/activities/activity_activity_c.arcadia": {
"bytes": 153,
"sha256": "d726b6b4e1200edd9ef752bb767e38d3d69dcac8eb6135d5f83c93832ff849b1"
},
"project.arcadia": {
"bytes": 597,
"sha256": "e7bd67c5785a78766298255ed3d53ff6d65dcd24bde1570ac8a0ff45cc9dc385"
},
"sa/functions/function_sa_function.arcadia": {
"bytes": 162,
"sha256": "1c724a9204784435e729badd4ad164b1a6b891840bb1ddc354ac1e175e3d712c"
},
"traceability.arcadia": {
"bytes": 522,
"sha256": "26b0b10715ced7aefcde941e6d1c1a6973f174997eae989e32a25c695dfb7cd1"
},
"views/diagram_oa_other.arcadia": {
"bytes": 315,
"sha256": "06ceef9cfdbb3ef229a22db6c48d8bb808388e027c37294648555ecbfb6bfab9"
},
"views/diagram_oa_view.arcadia": {
"bytes": 1896,
"sha256": "4e7d47d6a03153070687136c89faf01fc6df45ae89e2695beeab2fe4872dbc88"
},
"views/diagram_sa_view.arcadia": {
"bytes": 331,
"sha256": "c75b0fe14496631c9b017a32e277d1e5ad5b25e00e06b804fc54d950d7fb57f6"
}
},
"baseline": {
"bytes": 8944,
"sha256": "d1278e58cd31e1d61093292eddc1d7b2cc9c8cdc7fe5dd3801de8411af8db89d"
}
}
@@ -0,0 +1,91 @@
# Native multiselect evidence package
This package preserves native run-1 and run-2, both closed with exit 0, empty app
stdout/stderr and all three GUI/checker/fixture unchanged flags true. Each run
contains nine positive complete-Project checker snapshots, nine source files per
snapshot and three exact source-history equality groups. Only
`views/diagram_oa_view.arcadia` differs from baseline in its move and hidden
states. These artifacts do not establish native acceptance on their own; consult
the separate [saved-view report](../../../multiselect-saved-view-20260923.md) for
action observations, usability findings and the implemented subset of issue 29.
| Run | Source commit | Captures | Layout scope |
| --- | --- | ---: | --- |
| run-1 | `12a7352ddef5f69a144ead8219a50916233d63a9` | 27 | Before selection/status toolbar correction |
| run-2 | `f6a6010baed9e6164a1fcc7ecd58256a562827d7` | 24 | Corrected toolbar layout build |
Run-1 GUI/checker build receipts refer to the 729-file input map
`55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb`;
run-2 refers to the distinct 729-file map
`99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c`.
The [source identity evidence](../source/README.md) ties those maps to the commits
above. The GUI binary pins differ; the recorded checker binary pins match.
Run-1 is retained as evidence of the earlier layout, not as verification of the
corrected build.
The first run-2 baseline checker attempt failed before the successful retry after
the toolchain environment was initialized. Its unchanged raw snapshot and retry
comparison are preserved separately in the [environment incident](../incidents/README.md).
The successful retry is the baseline snapshot included in this native package;
the failed invocation is not silently reclassified or presented as a GUI failure.
These Python 3.10+ standard-library tools never operate the GUI or rerun the model
checker. From the checkout root, validate both raw runs without writing a package:
```text
python -B harness/experiments/multiselect-20260923/native/prepare.py --root . --runs run-1 run-2 --check-only
```
Omit `--check-only` to package; optionally choose `--output DIRECTORY`. The default
is this native directory. Existing package outputs are not overwritten. A missing
or unfinished run, changed recorded inputs, missing/extra fixture or snapshot
files, unmatched helper bytes, or inconsistent receipts fails preparation.
Verify a completed package independently of the original machine:
```text
python -B PATH_TO_PACKAGE/verify.py
```
Each run includes all original capture JSON/images, process/start/finish records,
generation and app streams, all nine source snapshots and checker streams/receipts,
and the history-bytes record. Its fixture includes baseline JSON, the manifest,
and canonical source files. Exact helpers are found by their recorded hashes among
the native directory's `.py`/`.js` files, so original and suffixed run-2 helpers can
coexist. Helpers are archived as data and never executed by these tools.
Referenced GUI/checker build results, exact gate helpers and input maps are
included. The checker example is read from its pinned historical input ZIP, not
from current source.
Full build logs and large source ZIPs belong in the sibling `checks` package;
verify that package separately. This package validates build receipt, input map,
example-source and executable-pin relationships without duplicating those ZIPs.
It does not contain or execute the GUI/checker binaries.
The verifier checks every archived byte pin and exact safe membership, clean
recorded exit and unchanged flags, process and capture lifetimes, each capture's
normalized executable path against the launched GUI, one consistent positive
window ID per run, fixture/source inventories, nine positive complete-Project
checker reports, baseline/binary/helper
relationships, and the actual archived bytes in three history equality groups.
It verifies that only `views/diagram_oa_view.arcadia` differs from baseline in the
move and hidden source states, and that baseline source bytes match the fixture.
Window identity checks join recorded metadata; the receipts do not independently
map that window handle to the recorded PID. Source models are not recompiled by
this offline Python verifier. Screenshot dimensions are recorded metadata, not a
minimum-window usability evaluation.
`manifest.json` maps each run's original historical paths to archived run,
fixture, helper, build and checker-source members and pins their bytes.
`files.json` pins the packager, verifier, README, manifest and archive. Raw bytes
are preserved; ZIP ordering and timestamps are fixed. Historic absolute paths are
labels and are not accessed by offline verification.
GUI actions remain separately documented parent observations. Screenshots do
not prove which inputs occurred, and the checker infers a bounded common delta
from saved geometry; it cannot validate the exact pointer destination. Source
history byte equality supports the stated saved-state relationships but does not
independently authenticate button presses, focus behavior or Undo stack structure.
Run-1 evidence does not establish the corrected toolbar's usability or any later
binary's behavior. Consult the parent report for the evaluated version, observed
limitations, run differences and the remaining full-issue acceptance work.
@@ -0,0 +1,22 @@
{
"prepare.py": {
"bytes": 7237,
"sha256": "d9d49d3082e485e670b43010822ebd3ab7a79762b36a247dcd3bdfc6b5d7f41d"
},
"verify.py": {
"bytes": 14703,
"sha256": "7ef5f28b6c9a43bf0361eec2d8be33a1e9f284d0ffc21b50fd09a2d082642ce3"
},
"README.md": {
"bytes": 5418,
"sha256": "8d6fa25d8bd97c654e78b89194bd499637427ce027157d568215e13421b22c03"
},
"manifest.json": {
"bytes": 72794,
"sha256": "de7642ad43aa881f7d984629db52ea41b62d0ebacc09260edd80a5c1fee7dd7b"
},
"evidence.zip": {
"bytes": 4399281,
"sha256": "7dc3e0571179e0f67fefe3c73462308b79e4c7f7a09bbd805e0acf0e4faeb1cf"
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,129 @@
"""Package explicit completed native runs; helpers are pinned data, never executed."""
from pathlib import Path
import argparse
import json
import re
import zipfile
from verify import pin, parsed, need, norm, relative, safe, verify_data, verify_package
HERE = Path(__file__).resolve().parent
def collect(root, runs):
native = root / ".local/multiselect-native"
candidates = [path for path in native.iterdir() if path.is_file() and path.suffix in (".py", ".js")]
candidates.extend(sorted((root / ".local/group-movement-gates").glob("*.py")))
helpers = [(path.suffix, path.read_bytes()) for path 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
def tree(folder, prefix):
need(folder.is_dir(), "missing directory: " + str(folder))
for path in sorted(folder.rglob("*")):
need(not path.is_symlink(), "symlink evidence input")
if path.is_file():
add(prefix + path.relative_to(folder).as_posix(), path.read_bytes())
for run in runs:
folder = native / run
start = parsed((folder / "started.json").read_bytes())
end = parsed((folder / "finished.json").read_bytes())
need(end["exitCode"] == 0 and all(end[k] is True for k in
("guiUnchanged", "checkerUnchanged", "fixtureUnchanged")), "unfinished/changed native run: " + run)
generation = parsed((folder / "generation.json").read_bytes())
history = parsed((folder / "history-bytes.json").read_bytes())
tree(folder, "runs/" + run + "/raw/")
fixture_relative = relative(generation["command"][2], start["cwd"])
need(fixture_relative.startswith(".local/multiselect-native/"), "fixture outside native root")
tree(root / fixture_relative, "runs/" + run + "/fixture/")
spec = {"originalRun": norm(start["cwd"]) + "/.local/multiselect-native/" + run,
"originalFixture": norm(generation["command"][2]), "helpers": {}, "builds": {}}
for key, expected in [("helper", start["helper"]), ("capture", start["capture"]),
("snapshotHelper", start["snapshotHelper"]), ("history", history["helper"])]:
matches = [(suffix, data) for suffix, data in helpers if pin(data) == expected]
need(bool(matches), "exact historical helper unavailable: " + key)
suffix, data = matches[0]
member = "helpers/" + expected["sha256"] + suffix
add(member, data)
spec["helpers"][key] = member
for kind in ("gui", "checker"):
recorded = start[kind]
rel = relative(recorded["receipt"], start["cwd"])
need(rel.startswith(".local/group-movement-gates/") and rel.endswith("/result.json"), "unexpected build receipt location")
receipt = root / rel
data = receipt.read_bytes()
need(pin(data) == recorded["receiptPin"], "historical build receipt changed")
prefix = "builds/" + pin(data)["sha256"] + "/"
add(prefix + "result.json", data)
inputs_data = (receipt.parent / "inputs.json").read_bytes()
need(pin(inputs_data) == recorded["inputs"], "historical build input map changed")
add(prefix + "inputs.json", inputs_data)
spec["builds"][kind] = {"receipt": prefix + "result.json", "inputs": prefix + "inputs.json", "originalRelative": rel}
build_helper = parsed(data)["helper"]
matching_helpers = [(suffix, value) for suffix, value in helpers if pin(value) == build_helper]
need(bool(matching_helpers), "exact historical build helper unavailable")
suffix, helper_data = matching_helpers[0]
helper_member = "helpers/" + build_helper["sha256"] + suffix
add(helper_member, helper_data)
spec["builds"][kind]["helper"] = helper_member
if kind == "checker":
# Read only the pinned historical example, not today's checkout.
archive_path = receipt.parent / "inputs.zip"
need(pin(archive_path.read_bytes()) == parsed(data)["archive"], "checker input archive pin")
source_path = "crates/oa-core/examples/multiselect_native.rs"
with zipfile.ZipFile(archive_path) as archive:
source = archive.read(source_path)
need(pin(source) == parsed(inputs_data)[source_path], "historical checker source pin")
member = "checker-source/" + pin(source)["sha256"] + ".rs"
add(member, source)
spec["checkerSource"] = {"inputPath": source_path, "member": member}
specs[run] = spec
manifest = {"schema": 1, "kind": "multiselect-native", "runs": specs,
"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 stream:
stream.write((json.dumps(value, indent=2) + "\n").encode())
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, default=HERE.parents[3])
parser.add_argument("--runs", nargs="+", required=True)
parser.add_argument("--output", type=Path, default=HERE)
parser.add_argument("--check-only", action="store_true")
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")
payload, manifest, summary = collect(args.root.resolve(), args.runs)
if args.check_only:
print("PASS raw consistency; no archive written:", summary)
return
out = args.output.resolve()
out.mkdir(parents=True, exist_ok=True)
for name in ("evidence.zip", "manifest.json", "files.json"):
need(not (out / name).exists(), "existing output refused: " + name)
for name in ("prepare.py", "verify.py", "README.md"):
data = (HERE / name).read_bytes()
if (out / name).exists():
need((out / name).read_bytes() == data, "different existing package tool")
else:
with (out / name).open("xb") as stream:
stream.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 evidence")
print("PASS package readback:", out, summary)
if __name__ == "__main__":
main()
@@ -0,0 +1,235 @@
"""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 math
import stat
import zipfile
BASE = {"started.json", "finished.json", "generation.json", "generation.stdout.log",
"generation.stderr.log", "app.stdout.log", "app.stderr.log", "processes.json", "history-bytes.json"}
GROUPS = [["baseline", "move-undo", "before-hide", "hide-undo"], ["move", "move-redo"],
["hidden", "hide-redo", "reopened-hidden"]]
MODES = {name: mode for group, mode in zip(GROUPS, ["unchanged", "moved", "hide"]) for name in group}
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"] == "multiselect-native", "manifest kind")
members, runs = manifest["members"], manifest["runs"]
need(bool(runs) and all(safe(run) and "/" not in 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 = 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, "exact pinned tree: " + prefix)
return actual
for run, spec in runs.items():
prefix = "runs/" + run + "/raw/"
start, end = obj(prefix + "started.json"), obj(prefix + "finished.json")
generation, process = obj(prefix + "generation.json"), obj(prefix + "processes.json")
history = obj(prefix + "history-bytes.json")
need(end["exitCode"] == 0 and all(end[key] is True for key in
("guiUnchanged", "checkerUnchanged", "fixtureUnchanged")), run + ": clean unchanged closure")
need(ordered(generation["start"], generation["finish"], process["CreationDate"], start["start"], end["finish"], history["verified"]), run + ": process/generation times")
need(process["ProcessId"] == start["pid"] and type(start["pid"]) is int and start["pid"] > 0, run + ": process identity")
need(norm(process["ExecutablePath"]) == norm(start["gui"]["binary"])
and start["command"] == [start["gui"]["binary"]], run + ": GUI command")
need(spec["originalRun"] == norm(start["cwd"]) + "/.local/multiselect-native/" + run, run + ": original run mapping")
need(generation["exitCode"] == 0 and generation["checker"] == start["checker"], run + ": generation checker")
need(generation["command"][:2] == [start["checker"]["binary"], "generate"]
and len(generation["command"]) == 3 and norm(generation["command"][2]) == spec["originalFixture"], run + ": generation command")
for stream in ("stdout", "stderr"):
need(end[stream] == pin(raw(prefix + "app." + stream + ".log")), run + ": app stream")
need(generation[stream] == pin(raw(prefix + "generation." + stream + ".log")), run + ": generation stream")
fixture = pinned_tree("runs/" + run + "/fixture/", start["fixture"])
need(set(fixture) == {"baseline.json", "manifest.json"} | {"source/" + name for name in
obj(prefix + "snapshots/baseline/result.json")["source"]}, run + ": fixture membership")
fixture_manifest = parsed(fixture["manifest.json"])
need(fixture_manifest["fixture"] == "multiselect-native-20260923"
and fixture_manifest["source_entry"] == "project.arcadia", run + ": fixture identity")
need(parsed(fixture["baseline.json"])["id"] == fixture_manifest["ids"]["project"], run + ": baseline identity")
for key, expected in [("helper", start["helper"]), ("capture", start["capture"]),
("snapshotHelper", start["snapshotHelper"]), ("history", history["helper"])]:
need(pin(raw(spec["helpers"][key])) == expected, run + ": helper " + key)
builds = {}
for kind, target in [("gui", "arcadia-studio"), ("checker", "multiselect_native")]:
recorded = start[kind]
build = obj(spec["builds"][kind]["receipt"])
need(pin(raw(spec["builds"][kind]["receipt"])) == recorded["receiptPin"], run + ": build receipt pin")
need(relative(recorded["receipt"], start["cwd"]) == spec["builds"][kind]["originalRelative"], run + ": build path mapping")
need(build["exitCode"] == 0 and build["inputsUnchanged"] is True
and ordered(build["start"], build["finish"], generation["start"]), run + ": accepted preceding build")
need(build["inputs"] == recorded["inputs"] == pin(raw(spec["builds"][kind]["inputs"])), run + ": build input map")
need(pin(raw(spec["builds"][kind]["helper"])) == build["helper"], run + ": build helper pin")
inputs = obj(spec["builds"][kind]["inputs"])
need(len(inputs) == build["inputCount"] and sum(name.startswith("crates/vendor/iced_widget/") for name in inputs) == 71, run + ": build input count")
artifacts = [item for item in build["artifacts"] if item["cargo"]["target"]["name"] == target]
need(len(artifacts) == 1 and artifacts[0]["readback"] == recorded["pin"]
and artifacts[0]["cargo"]["executable"] == recorded["binary"], run + ": executable relationship")
builds[kind] = inputs
need(start["gui"]["inputs"] == start["checker"]["inputs"], run + ": matching GUI/checker inputs")
source = spec["checkerSource"]
need(source["inputPath"] == "crates/oa-core/examples/multiselect_native.rs"
and pin(raw(source["member"])) == builds["checker"][source["inputPath"]], run + ": archived exact checker source")
top = {name[len(prefix):] for name in members if name.startswith(prefix) and "/" not in name[len(prefix):]}
captures = sorted(name for name in top - BASE if name.endswith(".json"))
need(bool(captures), run + ": missing captures")
expected_top = set(BASE) | set(captures)
captured_window = None
for name in captures:
capture = obj(prefix + name)
need(ordered(start["start"], capture["time"], end["finish"]), run + ": capture lifetime")
window = capture["window"]
app = window["app"]
need(isinstance(app, str) and app.startswith("process:")
and norm(app[len("process:"):]) == norm(start["gui"]["binary"]), run + ": captured executable relationship")
need(type(window["id"]) is int and window["id"] > 0, run + ": captured window identity")
if captured_window is None:
captured_window = window["id"]
need(window["id"] == captured_window, run + ": inconsistent captured window identity")
need(isinstance(capture["images"], list), run + ": capture images")
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")), run + ": capture image mapping")
need(type(image["width"]) is int and image["width"] > 0
and type(image["height"]) is int and image["height"] > 0, run + ": image dimensions")
need(filename not in expected_top, run + ": duplicate image reference")
expected_top.add(filename)
raw(prefix + filename)
need(top == expected_top, run + ": extra/missing top-level run files")
snapshots = {name[len(prefix + "snapshots/"):].split("/")[0] for name in members if name.startswith(prefix + "snapshots/")}
need(snapshots == set(MODES), run + ": exact nine snapshot labels")
states = {}
for label, mode in MODES.items():
folder = prefix + "snapshots/" + label + "/"
began, result = obj(folder + "started.json"), obj(folder + "result.json")
need(all(result.get(key) == value for key, value in began.items()), label + ": start/result")
need(result["exitCode"] == 0 and all(result[key] is True for key in
("binaryUnchanged", "workingSourceUnchanged", "baselineUnchanged")), label + ": unchanged successful checker")
need(ordered(start["start"], result["start"], result["finish"], end["finish"]), label + ": checker lifetime")
need(result["buildReceipt"] == start["checker"]["receiptPin"] and result["binary"] == start["checker"]["pin"]
and result["helper"] == start["snapshotHelper"], label + ": checker provenance")
need(result["baseline"] == pin(fixture["baseline.json"]), label + ": baseline pin")
command = result["command"]
need(len(command) == 5 and command[:3] == [start["checker"]["binary"], "check", mode]
and norm(command[3]) == spec["originalFixture"] + "/baseline.json"
and norm(command[4]) == spec["originalRun"] + "/snapshots/" + label + "/source/project.arcadia", label + ": exact checker command")
for stream in ("stdout", "stderr"):
need(result[stream] == pin(raw(folder + stream + ".log")), label + ": stream pin")
need(not raw(folder + "stderr.log"), label + ": checker stderr")
report = obj(folder + "stdout.log")
need(report["result"] == "PASS" and report["comparison"] == "complete Project equality"
and report["mode"] == mode and report["baseline"] == command[3] and report["saved"] == command[4], label + ": positive checker report")
delta = report["inferred_common_delta"]
if mode == "moved":
need(isinstance(delta, dict) and set(delta) == {"x", "y"}
and all(type(v) in (int, float) and math.isfinite(v) and abs(v) <= 500 for v in delta.values())
and math.hypot(delta["x"], delta["y"]) >= 10, label + ": inferred movement bounds")
else:
need(delta is None, label + ": unexpected inferred delta")
states[label] = pinned_tree(folder + "source/", result["source"])
need(len(states[label]) == history["sourceFilesPerSnapshot"] == 9, label + ": source count")
expected = {folder + name for name in ("started.json", "result.json", "stdout.log", "stderr.log")}
expected.update(folder + "source/" + name for name in states[label])
need({name for name in members if name.startswith(folder)} == expected, label + ": extra snapshot files")
need(history["status"] == "PASS" and history["equalByteGroups"] == GROUPS, run + ": history groups")
for group in GROUPS:
need(all(states[label] == states[group[0]] for label in group), run + ": actual history bytes " + str(group))
need(all(states[a[0]] != states[b[0]] for i, a in enumerate(GROUPS) for b in GROUPS[i + 1:]), run + ": distinct history states")
need(states["baseline"] == {name[7:]: data for name, data in fixture.items() if name.startswith("source/")}, run + ": baseline source exact")
changed = {label: sorted(name for name in set(states["baseline"]) | set(states[label])
if states["baseline"].get(name) != states[label].get(name)) for label in ("move", "hidden")}
need(changed == history["changedFilesFromBaseline"]
== {label: ["views/diagram_oa_view.arcadia"] for label in ("move", "hidden")}, run + ": changed source files")
print(run, "closed exit 0;", len(captures), "captures; nine positive snapshots; exact three-group source history")
need(used == set(members), "unreferenced/extra package members")
return {"runs": len(runs), "members": len(members)}
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)
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 native evidence byte/receipt consistency:", verify_package(args.package))
print("No GUI/checker execution; actions and native acceptance require the separate parent review.")
if __name__ == "__main__":
main()
@@ -0,0 +1,2 @@
# Preserve pinned historical receipts and helper bytes through Git round trips.
* -text whitespace=cr-at-eol
@@ -0,0 +1,52 @@
# Captured inputs and committed source identity
This directory preserves exact historical `committed-desktop-4.json` and
`committed-desktop-5.json` receipts plus `verify-committed-inputs.py` as data.
The original helper contains its historical absolute checkout path; do not run
it for portable verification. The receipts do not themselves pin that helper;
`files.json` pins the copies distributed here and the new verifier/README.
The local `.gitattributes` preserves those pinned bytes through Git round trips;
retain it with this directory rather than normalizing the historical text.
With Python 3.10+, Git, a repository containing both commits, and the completed
sibling checks package, run:
```text
python -B SOURCE_DIRECTORY/verify.py --repo REPOSITORY --checks CHECKS_PACKAGE_DIRECTORY
```
Before that package exists, an explicitly optional raw-input mode is available:
```text
python -B harness/experiments/multiselect-20260923/source/verify.py --repo . --raw-gates .local/group-movement-gates
```
The verifier checks source-evidence pins, captured map byte hashes, recorded gate
success/unchanged flags, counts and 71 vendored iced_widget inputs. It compares the
complete relevant Git tree inventory and every blob's size/SHA-256 at these
commits with their corresponding captured input maps:
- `desktop-4`: `12a7352ddef5f69a144ead8219a50916233d63a9`
- `desktop-5`: `f6a6010baed9e6164a1fcc7ecd58256a562827d7`
The scope matches the historical helper: Cargo manifests/lock/toolchain file,
`crates/`, `build/`, `.cargo/`, `scripts/`, `docs/`, `examples/`,
`harness/fixtures/`, and `harness/prototypes/`. This is the complete inventory
within that scope, not a whole-repository identity claim. Worktree contents,
current HEAD, line-ending checkout conversion and original machine paths do not
participate. Git objects are read by object ID; no checkout, build or archived
helper runs. Both commits must already be available; lazy object fetching is
disabled for these reads.
In package mode, outer checks-package pins and selected member/run relationships
are also checked. Run the checks package's own verifier for its full source ZIP,
logs, helpers and all other gate relationships. Raw mode reads the named local
maps/receipts directly and is not a substitute for packaged-evidence verification.
No source maps or ZIPs are duplicated in this directory.
Historical receipts report an earlier comparison. A successful run of this new
verifier performs a fresh Git-object comparison against the pinned maps. A gate's
recorded HEAD can predate its later source-identical commit; that difference is
why blob comparison is necessary. This evidence identifies tested source bytes;
it does not rerun tests or establish native usability, release integration or
full #29 acceptance.
@@ -0,0 +1,11 @@
{
"checked": "2026-09-23T08:11:54.115058+00:00",
"commit": "12a7352ddef5f69a144ead8219a50916233d63a9",
"gate": "desktop-4",
"inputCount": 729,
"inputMap": {
"bytes": 121985,
"sha256": "55a5f354bb5049a8c77ba9bafa833438ebf754649b0cf5d175d0c8dcfcedd7bb"
},
"comparison": "Exact committed Git blobs equal every captured input; same complete filtered inventory"
}
@@ -0,0 +1,11 @@
{
"checked": "2026-09-23T08:53:15.452246+00:00",
"commit": "f6a6010baed9e6164a1fcc7ecd58256a562827d7",
"gate": "desktop-5",
"inputCount": 729,
"inputMap": {
"bytes": 121985,
"sha256": "99dc46645236e674244e7c4867595a6000d3d85b54bcc9ab2b0c601923ecf66c"
},
"comparison": "Exact committed Git blobs equal every captured input; same complete filtered inventory"
}
@@ -0,0 +1,26 @@
{
".gitattributes": {
"bytes": 109,
"sha256": "aca8eef17dbab8cfedcbe18e1175cfee115802376fac4ec69e8c3320a6399d6c"
},
"README.md": {
"bytes": 2792,
"sha256": "b8db0c2c71e491b6179b3e57d27e5dfb23c9283894219feea328bc632603f2aa"
},
"verify.py": {
"bytes": 7255,
"sha256": "2ed667c127470efb669fb43d5dcdb288f891e42e10e67ef98ca4cd1125df09d1"
},
"verify-committed-inputs.py": {
"bytes": 2138,
"sha256": "ac2b50a73f678456b9628684347484c013f5f9c78f054de72b74f56a34c990d5"
},
"committed-desktop-4.json": {
"bytes": 390,
"sha256": "47c6774bcb7d0c37c50e0ed50f8fb58ee9b55c6fcee30af488481c314a4e66e8"
},
"committed-desktop-5.json": {
"bytes": 390,
"sha256": "da1f08e06bd0af6512da4196618b71d0c4ecc090012f061bb82b6a36f5b7686c"
}
}
@@ -0,0 +1,36 @@
"""Check the tested source inventory against exact Git blobs, not HEAD alone."""
from pathlib import Path
import datetime, hashlib, json, subprocess, sys
root=Path('C:/ar-multiselect-9e8r6t')
run,=sys.argv[1:]
gate=root/'.local/group-movement-gates'/run
inputs=json.loads((gate/'inputs.json').read_bytes())
result=json.loads((gate/'result.json').read_bytes())
assert result['exitCode']==0 and result['inputsUnchanged']
head=subprocess.check_output(['git','rev-parse','HEAD'],cwd=root,text=True).strip()
def relevant(p):
return p in ('Cargo.toml','Cargo.lock','rust-toolchain.toml') or p.startswith(('crates/','build/','.cargo/','scripts/','docs/','examples/','harness/fixtures/','harness/prototypes/'))
paths=subprocess.check_output(['git','ls-tree','-r','--name-only','-z',head],cwd=root).decode().split('\0')
assert set(inputs)=={p for p in paths if p and relevant(p)}, 'Committed input inventory differs'
assert all('\n' not in p for p in inputs)
request=''.join(head+':'+p+'\n' for p in inputs).encode()
raw=subprocess.run(['git','cat-file','--batch'],cwd=root,input=request,capture_output=True,check=True).stdout
offset=0
actual={}
for path in inputs:
end=raw.index(b'\n',offset)
oid,kind,size=raw[offset:end].split()
assert kind==b'blob'
size=int(size)
data=raw[end+1:end+1+size]
assert len(data)==size and raw[end+1+size:end+2+size]==b'\n'
actual[path]={'bytes':size,'sha256':hashlib.sha256(data).hexdigest()}
offset=end+2+size
assert offset==len(raw)
changed=[p for p in inputs if inputs[p]!=actual[p]]
assert not changed, 'Tested bytes differ from committed blobs: '+repr(changed)
data=(gate/'inputs.json').read_bytes()
report={'checked':datetime.datetime.now(datetime.timezone.utc).isoformat(),'commit':head,'gate':run,'inputCount':len(inputs),'inputMap':{'bytes':len(data),'sha256':hashlib.sha256(data).hexdigest()},'comparison':'Exact committed Git blobs equal every captured input; same complete filtered inventory'}
out=root/'.local/group-movement-gates'/('committed-'+run+'.json')
with out.open('x',encoding='utf-8') as f: json.dump(report,f,indent=2)
print(json.dumps(report,indent=2))
@@ -0,0 +1,149 @@
"""Compare captured input maps to exact named Git trees; no builds or checkouts."""
from pathlib import Path, PurePosixPath
import argparse
import hashlib
import json
import os
import subprocess
import zipfile
HERE = Path(__file__).resolve().parent
COMMITS = {"desktop-4": "12a7352ddef5f69a144ead8219a50916233d63a9",
"desktop-5": "f6a6010baed9e6164a1fcc7ecd58256a562827d7"}
COMPARISON = "Exact committed Git blobs equal every captured input; same complete filtered inventory"
FILES = {".gitattributes", "verify.py", "README.md", "verify-committed-inputs.py",
"committed-desktop-4.json", "committed-desktop-5.json"}
def need(ok, message):
if not ok:
raise ValueError(message)
def pin(data):
return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
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 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(part not in ("", ".", "..") for part in name.split("/")))
def relevant(path):
return path in ("Cargo.toml", "Cargo.lock", "rust-toolchain.toml") or path.startswith(
("crates/", "build/", ".cargo/", "scripts/", "docs/", "examples/", "harness/fixtures/", "harness/prototypes/"))
def git(repo, *arguments, data=None):
environment = dict(os.environ, GIT_NO_LAZY_FETCH="1")
return subprocess.run(["git", *arguments], cwd=repo, input=data, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, check=True, env=environment).stdout
def compare_commit(repo, commit, inputs):
need(git(repo, "rev-parse", "--verify", commit + "^{commit}").decode().strip() == commit, "named commit unavailable")
entries = git(repo, "ls-tree", "-r", "--full-tree", "-z", commit).split(b"\0")
blobs = {}
for entry in filter(None, entries):
header, path_bytes = entry.split(b"\t", 1)
path = path_bytes.decode("utf-8")
if relevant(path):
_mode, kind, oid = header.split()
need(kind == b"blob", "relevant non-blob tree entry: " + path)
need(path not in blobs, "duplicate tree path")
blobs[path] = oid
need(set(blobs) == set(inputs), "complete filtered Git inventory differs; missing="
+ repr(sorted(set(inputs) - set(blobs))) + "; additional=" + repr(sorted(set(blobs) - set(inputs))))
# Object IDs avoid path quoting and commit:path interpretation in batch input.
paths = sorted(blobs)
data = git(repo, "cat-file", "--batch", data=b"".join(blobs[path] + b"\n" for path in paths))
offset, actual = 0, {}
for path in paths:
end = data.index(b"\n", offset)
oid, kind, size_bytes = data[offset:end].split()
size = int(size_bytes)
need(oid == blobs[path] and kind == b"blob" and size >= 0, "Git batch object relationship")
content = data[end + 1:end + 1 + size]
need(len(content) == size and data[end + 1 + size:end + 2 + size] == b"\n", "Git batch framing")
actual[path] = pin(content)
offset = end + 2 + size
need(offset == len(data), "trailing Git batch bytes")
different = [path for path in paths if actual[path] != inputs[path]]
need(not different, "captured bytes differ from named commit: " + repr(different))
def packaged(checks, runs):
files = parsed((checks / "files.json").read_bytes())
need(set(files) == {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"}, "checks outer inventory")
for name, expected in files.items():
need(pin((checks / name).read_bytes()) == expected, "checks outer pin: " + name)
manifest = parsed((checks / "manifest.json").read_bytes())
need(manifest["schema"] == 1 and manifest["kind"] == "multiselect-cargo-gates", "checks manifest kind")
captured = {}
with zipfile.ZipFile(checks / "evidence.zip") as archive:
names = archive.namelist()
need(len(names) == len(set(names)) and set(names) == set(manifest["members"])
and all(safe(name) for name in names), "checks exact safe members")
def raw(logical):
member = manifest["logicalFiles"][logical]
data = archive.read(member)
need(pin(data) == manifest["members"][member], "checks member pin: " + logical)
return data
for run in runs:
prefix = "cargo/" + run + "/"
result = parsed(raw(prefix + "result.json"))
spec = manifest["runs"][run]
need(all(result[key] == spec[key] for key in ("command", "head", "exitCode", "inputCount")), run + ": checks run relationships")
captured[run] = (raw(prefix + "inputs.json"), result)
return captured
def verify(repo, captured):
outer = parsed((HERE / "files.json").read_bytes())
need(set(outer) == FILES, "source evidence file inventory")
for name, expected in outer.items():
need(pin((HERE / name).read_bytes()) == expected, "source evidence pin: " + name)
for run, commit in COMMITS.items():
receipt = parsed((HERE / ("committed-" + run + ".json")).read_bytes())
need(receipt["gate"] == run and receipt["commit"] == commit
and receipt["comparison"] == COMPARISON, run + ": historical identity relationship")
map_bytes, result = captured[run]
inputs = parsed(map_bytes)
need(pin(map_bytes) == receipt["inputMap"] == result["inputs"], run + ": exact captured input map")
need(result["exitCode"] == 0 and result["inputsUnchanged"] is True, run + ": accepted unchanged gate")
need(len(inputs) == receipt["inputCount"] == result["inputCount"], run + ": input counts")
need(all(safe(path) and relevant(path) for path in inputs), run + ": input scope")
need(sum(path.startswith("crates/vendor/iced_widget/") for path in inputs) == 71, run + ": vendor count")
compare_commit(repo, commit, inputs)
print("PASS exact Git tree/blobs:", run, commit, len(inputs), "captured inputs")
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--repo", type=Path, required=True, help="repository with both named commits already present")
source = parser.add_mutually_exclusive_group(required=True)
source.add_argument("--checks", type=Path, help="portable checks package directory")
source.add_argument("--raw-gates", type=Path, help="optional preparation mode: raw gate directory, not a packaged-evidence verification")
args = parser.parse_args()
if args.checks:
captured = packaged(args.checks, COMMITS)
else:
captured = {run: ((args.raw_gates / run / "inputs.json").read_bytes(),
parsed((args.raw_gates / run / "result.json").read_bytes())) for run in COMMITS}
verify(args.repo, captured)
print("Source identity only; no build, checkout, helper execution or native acceptance claim.")
if __name__ == "__main__":
main()