diff --git a/harness/prerelease37-connection-admission-20260924.md b/harness/prerelease37-connection-admission-20260924.md index 06026add..b799a122 100644 --- a/harness/prerelease37-connection-admission-20260924.md +++ b/harness/prerelease37-connection-admission-20260924.md @@ -6,7 +6,7 @@ Branch contribution by Codex-9e8r6t; release coordination is [issue 37](http://2 Source `72b1bb7aa723128f57b407f4dc55e55c3bc34818` adds early admission for captured Connection Endpoint/Restart events before shared Allocation retirement. A captured drawing event must match both the live route context and an extant drawing session. An old event therefore cannot retire a newer Arrange arm, active group press or preview. Current Choose/Begin and Restart retain their intentional tool-boundary behavior. -Successor source `6f247af795b7bec1818c588b2dabf203f8f68d8a` also admits captured Route Commit/CommitAttachment before retirement. Their captured context and changed edge must match the current context and selected edge. There is no invented route-session requirement. Selecting a placement group does not necessarily advance the canvas context, so context equality alone is insufficient. Stale route commits now preserve existing feedback instead of reaching the former late cancellation diagnostic. Current route edits and unscoped route commands retain their existing handlers. +Production successor `6f247af795b7bec1818c588b2dabf203f8f68d8a`, with test-helper qualification corrected at final tested source `e68a83959900e556768d8470640e28a7df7d8cb8`, also admits captured Route Commit/CommitAttachment before retirement. Their captured context and changed edge must match the current context and selected edge. There is no invented route-session requirement. Selecting a placement group does not necessarily advance the canvas context, so context equality alone is insufficient. Stale route commits now preserve existing feedback instead of reaching the former late cancellation diagnostic. Current route edits and unscoped route commands retain their existing handlers. The three Connection and six Route regression cases protect ownership, selection, preview/Document identity, complete model/source state, and exact Undo/Redo history. Positive cases prove current drawing and route edits remain usable. Context and selected-edge predicates have separate discriminating cases. The retained group movement uses literal expected placements and saved pin `(1100, 400)`, independently of the movement planner. @@ -26,9 +26,27 @@ The first focused/format attempts at `4421730` failed because the nested test mo Initial archive SHA-256: `30087db61aa4e045a522cf9db56d6b85b595012ebb6a1bb1d03bfb8bb213bd5c` (6,087,017 bytes). Standalone verification and selfcheck passed: seven runs, two retained failures, five source proofs, original-byte equality and eleven corruption-rejection checks. Archive consistency is not a fresh test run or an authenticated build. -## Route successor validation status at source handoff +## Final Route and combined local admission validation -The six Route tests and guard have independent source review and were formatted before commit. Recorded route regressions, Allocation regressions, formatting and strict Clippy are running against `6f247af`; their results are not yet claimed here. This source is made available so the release owner can perform the combined checks without waiting for duplicate local code generation. A subsequent evidence update must name the tested source and results before this contribution is treated as locally validated. +Final tested contribution source is `e68a83959900e556768d8470640e28a7df7d8cb8`. Each final gate captured the same 756 input files unchanged, and a separate exact Git-blob comparison binds its input map to that source. Environment matches the initial Windows GNU LLVM gates above. Test filters overlap; these row counts must not be summed into a unique-test total. + +| Captured run | Command/filter and result | +| --- | --- | +| route-regressions-3 | Desktop `route` filter: 31 passed, 0 failed, including all six new Route cases | +| allocation-regressions-2 | Desktop `app::allocation_drag::tests`: 51 passed, 0 failed, including the three Connection and six Route cases | +| route-attachments-1 | Desktop `attachment` filter: 28 passed, 0 failed | +| route-format-2 | `cargo fmt --all -- --check`, exit 0 | +| route-lint-1 | `cargo clippy -p oa-desktop --all-targets -- -D warnings`, exit 0 | + +The [Route evidence package](prerelease37-connection-evidence-20260924/route-checks/README.md) retains seven completed runs: these five final gates, earlier successful format at 6f247af, and the failed route-regressions-2 compile at 6f247af. The latter failed E0425 because the new test fixture used unqualified `project_view`; no tests ran. The one-line `projection::project_view` correction at e68a839 changes only that test helper. Seven source proofs bind the five final gates to e68a839 and the two historical gates to 6f247af; a source proof on a failed gate does not convert it to a pass. + +The failed route-regressions-2 receipt records checked-out HEAD `c655c5eeaaa32c1c21074a7543844ae99a1d6fd5`, the documentation-only descendant of 6f247af. Its separate source proof names 6f247af because all captured compiler inputs match that commit exactly; the raw HEAD receipt is preserved unchanged. + +An earlier [interrupted route compilation](prerelease37-connection-evidence-20260924/interrupted/README.md) is retained separately with its six partial raw files. It has no result receipt, known exit code or established test outcome and is excluded from the completed-run counts. + +Standalone archive verification and selfcheck passed: seven completed runs, one retained compiler failure, seven source proofs, exact original-byte equality, existing-output refusal and eleven corruption-rejection checks. Final Route archive SHA-256: `501f01c7279bc9d719151abe9b729769dd0078678c702448671356e91965015f` (`6,094,831` bytes). Its schema/tool name retains the existing Connection-admission evidence name; the explicit run inventory identifies its Route scope. These checks establish captured evidence consistency, not hermetic compilation or full workspace acceptance. + +The published initial evidence ZIP was also freshly downloaded from Gitea and matched its exact 6,087,017 bytes/hash; the [transport receipt](prerelease37-connection-evidence-20260924/transport-readback.json) records 26.0 seconds. This establishes artifact availability and one successful Windows transfer, not Linux networking or package runtime behavior. ## Reviews and scope @@ -36,5 +54,8 @@ The six Route tests and guard have independent source review and were formatted - [Connection guard review](prerelease37-connection-evidence-20260924/reviews/connection-envelope-review.md): initial evaluator finding and addressed readback. - [Route guard review](prerelease37-connection-evidence-20260924/reviews/route-envelope-review.md): same-context selection defect and addressed readback. - [Candidate Text Apply review](prerelease37-connection-evidence-20260924/reviews/candidate-text-review.md): scoped source evidence, not execution. +- [Final delivery review](prerelease37-connection-evidence-20260924/reviews/final-delivery-review.md): independent receipt, archive and source-identity readback. + +The release owner's integrated candidate `897d9f049406d5be597543eb0a6755b796259302` was fetched and inspected. Both new regression modules are byte-identical to tested contribution source e68a839. Its code difference from the prior candidate9e99618c is exactly the test-helper qualification. This confirms that the known compiler correction was integrated; it does not substitute these contribution gates for combined-source execution. This narrow contribution has no fresh GUI build, mounted native reproduction or packaged acceptance claim. Earlier [Allocation native evidence](allocation-group-app-20260924.md) remains bound to `495464e`. The release owner's final integrated source, workspace gates, native tests and separate-machine downloaded-package launch are distinct acceptance steps. Preserved Scenario group work is excluded. diff --git a/harness/prerelease37-connection-evidence-20260924/interrupted/README.md b/harness/prerelease37-connection-evidence-20260924/interrupted/README.md new file mode 100644 index 00000000..318ba0bb --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/interrupted/README.md @@ -0,0 +1,7 @@ +# Interrupted route compilation + +This is an exact archive of the six partial files left by route-regressions-1 when the task was interrupted. No result.json, process exit or test result was observed. The external observation in receipt.json was recorded after resume; it does not rewrite the original gate receipts. The interrupted run must not be counted as passed or as a known compiler failure. + +The input map matches the independently completed route-format-1 capture for source6f247af. A separate restarted run (route-regressions-2) subsequently exposed a missing test-helper qualifier; that later compiler failure does not retroactively establish this interrupted process's exit. + +Archive creation read back every entry and compared it byte-for-byte with the retained original. receipt.json pins the complete member inventory and ZIP. These checks establish preserved bytes, not execution success. diff --git a/harness/prerelease37-connection-evidence-20260924/interrupted/receipt.json b/harness/prerelease37-connection-evidence-20260924/interrupted/receipt.json new file mode 100644 index 00000000..687fb829 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/interrupted/receipt.json @@ -0,0 +1,37 @@ +{ + "run": "route-regressions-1", + "observed": "2026-09-24T06:26:51.595717+00:00", + "status": "interrupted before result receipt; no exit code or test outcome established", + "observation": "After user interruption/resume, original unified session was unknown and Win32 process inventory contained no cargo/rustc/python/clippy driver. Raw partial files retained unchanged.", + "files": { + "inputs.json": { + "bytes": 126743, + "sha256": "db306addb9c9012a9f928210bd67615e0245ac3c59e32abba8412e8c7d5265e9" + }, + "inputs.zip": { + "bytes": 3043591, + "sha256": "4a0ae23e1599f7647c5b62eedfbac7c1d714362990b957aa59553fd363e46bbe" + }, + "process.json": { + "bytes": 198, + "sha256": "72a94cab687f14ec3b1783815b4c37e1d673e84eb916d6dc8cae8c9171e7e13f" + }, + "started.json": { + "bytes": 1590, + "sha256": "63344e4bd93a43122bd0b5608381141321e5204945d166ca82857971a57aeb3c" + }, + "stderr.log": { + "bytes": 76, + "sha256": "9ff4708671bbf79cd3ed1dee3cafa7e469f39da63407423fc8f2b42b6f4c4f73" + }, + "stdout.log": { + "bytes": 294729, + "sha256": "5ffb2106f188ee05ebab10c8096f8959cef4e7010eff877b4d2591d7a9c62237" + } + }, + "archive": { + "file": "route-regressions-1.zip", + "bytes": 3004097, + "sha256": "9eaed652053596f940406460a02d23f87045bf9c45ac5af748fb5daef59bd9c2" + } +} diff --git a/harness/prerelease37-connection-evidence-20260924/interrupted/route-regressions-1.zip b/harness/prerelease37-connection-evidence-20260924/interrupted/route-regressions-1.zip new file mode 100644 index 00000000..1bf267db Binary files /dev/null and b/harness/prerelease37-connection-evidence-20260924/interrupted/route-regressions-1.zip differ diff --git a/harness/prerelease37-connection-evidence-20260924/reviews/final-delivery-review.md b/harness/prerelease37-connection-evidence-20260924/reviews/final-delivery-review.md new file mode 100644 index 00000000..d89f4c9f --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/reviews/final-delivery-review.md @@ -0,0 +1,27 @@ +# Final admission delivery review — prerelease 37 + +2026-09-24. Independent bounded read-only source/evidence review at contribution HEAD `e68a83959900e556768d8470640e28a7df7d8cb8` in `C:/ar-multiselect-9e8r6t`. This report is the reviewer's only written artifact. No Cargo, formatter, compiler, GUI, network request, Git mutation or archived-source execution was performed. + +## Result + +No material finding in the final contribution report, completed-run package, source pins or preserved failure/interruption boundaries. This is acceptance of the scoped evidence delivery, not the combined prerelease, a native workflow, a packaged executable or publication availability. + +## Source readback + +- The final `e68a839` commit changes exactly one test-helper reference, from `project_view` to `projection::project_view`. Production admission guards remain those reviewed at `6f247af`: Connection Endpoint/Restart requires current context and matching extant drawing-session context; Route Commit/CommitAttachment requires current context and the selected edge. Both reject before shared Allocation retirement. +- Read back the prior independent reviews and their addressed evaluator/selected-edge findings. The six Route cases retain separate context and selected-edge discriminators, successful current edits and literal route/placement/history expectations. This review found no additional scoped correction and does not substitute for broader integration review. + +## Independently verified evidence + +- Read all seven completed result receipts, stream/capsule hashes and source proofs. Five final gates bind to `e68a839`; the historical successful format and failed compile bind to `6f247af`. Every capture has 756 unchanged inputs. +- Direct independent `git cat-file --batch` comparison of both distinct source capsules verified all 756 archived inputs byte-for-byte against each named source, including each manifest size/hash. These comparisons did not execute the archived comparator. +- Ran the final package's read-only standalone verifier with Python `-B`: PASS, seven runs, one recorded failure, seven source proofs, 59 logical files, 49 stored members and two distinct source capsule pairs. +- Independently compared every packaged logical raw file to its retained original. The final archive is exactly 6,094,831 bytes, SHA-256 `501f01c7279bc9d719151abe9b729769dd0078678c702448671356e91965015f`. +- Read the actual test streams: Route 31, Allocation 51, attachment 28 passed, each with zero failures. The Allocation output names all nine new cases (three Connection, six Route) as passing. Final format and strict all-targets desktop Clippy receipts have exit 0. The report correctly warns that overlapping filters cannot be summed into a unique-test total. +- The historical `route-regressions-2` stream contains E0425 for unqualified `project_view`, exit 101 and no test result. Its raw HEAD remains `c655c5eeaaa32c1c21074a7543844ae99a1d6fd5`, the documentation-only descendant of `6f247af`; the report explicitly distinguishes that HEAD from the equal-input source proof. +- Independently verified the separate interrupted archive's complete six-member inventory, hashes and byte equality with retained partial originals. Its input map equals historical `route-format-1`; no final receipt or exit is inferred. It remains outside the seven completed runs. +- Read the retained `route-checks/selfcheck-final.txt`: command, stdout, empty stderr and exit 0 record original-byte equality, existing-output refusal and eleven named corruption rejections. This supplemental transcript is separate from the package's standard pinned file inventory, as in the initial evidence delivery. + +## Claim boundaries + +The updated top-level report keeps initial 755-input Connection evidence at `72b1bb7` separate from final 756-input evidence, preserves the earlier failures and interrupted run, and identifies the one-line test correction. It does not promote archive consistency into fresh tests, authenticated/hermetic compilation, full workspace acceptance or native/package acceptance. The recorded initial Gitea transport receipt matches the stated 6,087,017-byte initial archive hash and 26.032-second transfer; this reviewer did not independently repeat that network transfer. Earlier Allocation native evidence remains pinned to its earlier source. Combined-source checks, Windows native verification and separate-machine downloaded-package launch remain the release owner's distinct acceptance work. diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/README.md b/harness/prerelease37-connection-evidence-20260924/route-checks/README.md new file mode 100644 index 00000000..63f98104 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/README.md @@ -0,0 +1,24 @@ +# Prerelease 37 Connection admission captured-gate evidence tools + +Adapted from the reviewed Allocation prepare/verify/selfcheck tools. Read-only preparation consumes explicitly selected **closed** runs in CHECKOUT/.local/prerelease37-gates. No Cargo, source execution, checkout, GUI, network or archived helper execution occurs. + +```powershell +python -B prepare.py --root CHECKOUT --runs connection-focused-1 connection-format-1 --check-only +``` + +Keep failed connection-focused-1 and connection-format-1: verification preserves their recorded failures rather than converting archive consistency into test success. The example selects those two historical failures. Later closed Connection admission runs can be explicitly listed with the same interface; the final package manifest is authoritative for its exact inventory. No implicit discovery includes active directories. + +To create a portable package, replace --check-only with `--output NEW_DIRECTORY`. Existing output refuses. The exact seven raw files are required, with only `source-proof.json` accepted as an optional eighth file. No raw byte normalization or receipt rewriting occurs. Maps and nested input ZIPs deduplicate by SHA-256; other logical raw files keep their names. All original helper bytes, failed-run streams and optional proof bytes remain archived. The prerelease37 Connection admission manifest kind distinguishes this evidence from Allocation and Process packages. + +The gate.py and source-proof.py helper catalog is preserved. Every gate's recorded helper must match available bytes; use repeatable `--helper PATH` for older captures. If a proof exists, its exact comparator bytes must be available at the default `.local/process-source-evidence-tools/verify.py` or a repeatable `--comparator PATH`. They are archived under their content hash and never executed. + +An optional source proof is independently pinned in the manifest with its full named commit. Verification binds it to the enclosing run, exact result receipt, captured map/count, completed gate time, status and comparator bytes/hash. Captured HEAD is preserved as historical metadata and is not substituted for the named source commit. This packager checks historical proof consistency; it does **not** repeat Git blob comparison. A source proof on a failed gate is source-identity evidence only, never a passing-test claim. + +```powershell +python -B PACKAGE/verify.py +python -B selfcheck.py --root CHECKOUT --runs connection-focused-1 connection-format-1 --output TOOLS/NEW_SELFCHECK_DIRECTORY +``` + +The verifier checks pins, exact ZIP inventory, process/start/result relationships, streams, command/exit identities, source capsules, vendor inventory and Cargo artifact relationships. Selfchecks compare packaged raw bytes to originals, reject existing output, and mutate only in-memory copies to test stream/helper/exit/capsule/proof corruption. The package contains tools, manifest, files.json and evidence.zip; selfcheck is a preparation utility, not packaged runtime input. + +Limits: internal consistency is not external authentication, hermetic build proof, native usability, a new source comparison or production acceptance. Review exact run results and source identity separately. Run with `python -B` to avoid incidental bytecode writes. diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/evidence.zip b/harness/prerelease37-connection-evidence-20260924/route-checks/evidence.zip new file mode 100644 index 00000000..8c892c66 Binary files /dev/null and b/harness/prerelease37-connection-evidence-20260924/route-checks/evidence.zip differ diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/files.json b/harness/prerelease37-connection-evidence-20260924/route-checks/files.json new file mode 100644 index 00000000..81cfd519 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/files.json @@ -0,0 +1,22 @@ +{ + "prepare.py": { + "bytes": 6319, + "sha256": "ece8199911549266ee8ff6a3cd5636534cc13f15315fdce8838e269071a14383" + }, + "verify.py": { + "bytes": 11451, + "sha256": "87e29134dd04f38040ed7be0fb36954ef6c5873ff7fe844217ce72fd1aa3f92f" + }, + "README.md": { + "bytes": 3287, + "sha256": "cfa094bdf820db71002e84a0617ed86f4e2de2e693809f308ff02b6a80a21d07" + }, + "manifest.json": { + "bytes": 19486, + "sha256": "16bdf6f8ce82e701a82bc232ae4d19c8e08ea4f21a71d42276d95a9b8ff04438" + }, + "evidence.zip": { + "bytes": 6094831, + "sha256": "501f01c7279bc9d719151abe9b729769dd0078678c702448671356e91965015f" + } +} diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/manifest.json b/harness/prerelease37-connection-evidence-20260924/route-checks/manifest.json new file mode 100644 index 00000000..3a697a12 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/manifest.json @@ -0,0 +1,440 @@ +{ + "schema": 1, + "kind": "prerelease37-connection-admission-cargo-gates", + "runs": { + "route-format-1": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "6f247af795b7bec1818c588b2dabf203f8f68d8a", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "6f247af795b7bec1818c588b2dabf203f8f68d8a", + "pin": { + "bytes": 593, + "sha256": "3d1b4749654f7182ea5a59b402aac7de6863872df256a2876bc182ff295df60d" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "route-regressions-2": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "--bin", + "arcadia-studio", + "--message-format=json", + "route", + "--", + "--test-threads=1" + ], + "head": "c655c5eeaaa32c1c21074a7543844ae99a1d6fd5", + "exitCode": 101, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "6f247af795b7bec1818c588b2dabf203f8f68d8a", + "pin": { + "bytes": 598, + "sha256": "5f217f1318566ce1aa2637e848d324fe8933205c6740f48ff15532b8956d5411" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "route-format-2": { + "command": [ + "cargo", + "fmt", + "--all", + "--", + "--check" + ], + "head": "e68a83959900e556768d8470640e28a7df7d8cb8", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "e68a83959900e556768d8470640e28a7df7d8cb8", + "pin": { + "bytes": 593, + "sha256": "d14829233926a809d061b031194f19541bea0203c56beb441f4c596d585f699b" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "route-regressions-3": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "--bin", + "arcadia-studio", + "--message-format=json", + "route", + "--", + "--test-threads=1" + ], + "head": "e68a83959900e556768d8470640e28a7df7d8cb8", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "e68a83959900e556768d8470640e28a7df7d8cb8", + "pin": { + "bytes": 598, + "sha256": "dce6830e0fa49bcbf4437d090ade5114b5a86d4a9fe6ad2015fc51fb1f63c54f" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "allocation-regressions-2": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "--bin", + "arcadia-studio", + "--message-format=json", + "app::allocation_drag::tests", + "--", + "--test-threads=1" + ], + "head": "e68a83959900e556768d8470640e28a7df7d8cb8", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "e68a83959900e556768d8470640e28a7df7d8cb8", + "pin": { + "bytes": 603, + "sha256": "25c573fa3c37474de2a44b9e298daddc01aa84717435ee8bad080fd4ad5db594" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "route-attachments-1": { + "command": [ + "cargo", + "test", + "-p", + "oa-desktop", + "--bin", + "arcadia-studio", + "--message-format=json", + "attachment", + "--", + "--test-threads=1" + ], + "head": "e68a83959900e556768d8470640e28a7df7d8cb8", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "e68a83959900e556768d8470640e28a7df7d8cb8", + "pin": { + "bytes": 598, + "sha256": "6cf60c7f472b27928a19573a5f558e42176a8f77a8e76462f4f54226b58578a6" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + }, + "route-lint-1": { + "command": [ + "cargo", + "clippy", + "-p", + "oa-desktop", + "--all-targets", + "--message-format=json", + "--", + "-D", + "warnings" + ], + "head": "e68a83959900e556768d8470640e28a7df7d8cb8", + "exitCode": 0, + "inputCount": 756, + "helper": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "sourceProof": { + "commit": "e68a83959900e556768d8470640e28a7df7d8cb8", + "pin": { + "bytes": 591, + "sha256": "6b643a140f408ce706aef87b31c716cb8b6b7ea1dd632ee6b60d96fc27d26a52" + }, + "comparator": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py" + } + } + }, + "captureHelpers": { + "gate.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "source-proof.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py" + }, + "logicalFiles": { + "cargo/allocation-regressions-2/inputs.json": "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json", + "cargo/allocation-regressions-2/inputs.zip": "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip", + "cargo/allocation-regressions-2/process.json": "cargo/allocation-regressions-2/process.json", + "cargo/allocation-regressions-2/result.json": "cargo/allocation-regressions-2/result.json", + "cargo/allocation-regressions-2/source-proof.json": "cargo/allocation-regressions-2/source-proof.json", + "cargo/allocation-regressions-2/started.json": "cargo/allocation-regressions-2/started.json", + "cargo/allocation-regressions-2/stderr.log": "cargo/allocation-regressions-2/stderr.log", + "cargo/allocation-regressions-2/stdout.log": "cargo/allocation-regressions-2/stdout.log", + "cargo/route-attachments-1/inputs.json": "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json", + "cargo/route-attachments-1/inputs.zip": "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip", + "cargo/route-attachments-1/process.json": "cargo/route-attachments-1/process.json", + "cargo/route-attachments-1/result.json": "cargo/route-attachments-1/result.json", + "cargo/route-attachments-1/source-proof.json": "cargo/route-attachments-1/source-proof.json", + "cargo/route-attachments-1/started.json": "cargo/route-attachments-1/started.json", + "cargo/route-attachments-1/stderr.log": "cargo/route-attachments-1/stderr.log", + "cargo/route-attachments-1/stdout.log": "cargo/route-attachments-1/stdout.log", + "cargo/route-format-1/inputs.json": "capsules/db306addb9c9012a9f928210bd67615e0245ac3c59e32abba8412e8c7d5265e9.json", + "cargo/route-format-1/inputs.zip": "capsules/4a0ae23e1599f7647c5b62eedfbac7c1d714362990b957aa59553fd363e46bbe.zip", + "cargo/route-format-1/process.json": "cargo/route-format-1/process.json", + "cargo/route-format-1/result.json": "cargo/route-format-1/result.json", + "cargo/route-format-1/source-proof.json": "cargo/route-format-1/source-proof.json", + "cargo/route-format-1/started.json": "cargo/route-format-1/started.json", + "cargo/route-format-1/stderr.log": "cargo/route-format-1/stderr.log", + "cargo/route-format-1/stdout.log": "cargo/route-format-1/stdout.log", + "cargo/route-format-2/inputs.json": "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json", + "cargo/route-format-2/inputs.zip": "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip", + "cargo/route-format-2/process.json": "cargo/route-format-2/process.json", + "cargo/route-format-2/result.json": "cargo/route-format-2/result.json", + "cargo/route-format-2/source-proof.json": "cargo/route-format-2/source-proof.json", + "cargo/route-format-2/started.json": "cargo/route-format-2/started.json", + "cargo/route-format-2/stderr.log": "cargo/route-format-2/stderr.log", + "cargo/route-format-2/stdout.log": "cargo/route-format-2/stdout.log", + "cargo/route-lint-1/inputs.json": "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json", + "cargo/route-lint-1/inputs.zip": "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip", + "cargo/route-lint-1/process.json": "cargo/route-lint-1/process.json", + "cargo/route-lint-1/result.json": "cargo/route-lint-1/result.json", + "cargo/route-lint-1/source-proof.json": "cargo/route-lint-1/source-proof.json", + "cargo/route-lint-1/started.json": "cargo/route-lint-1/started.json", + "cargo/route-lint-1/stderr.log": "cargo/route-lint-1/stderr.log", + "cargo/route-lint-1/stdout.log": "cargo/route-lint-1/stdout.log", + "cargo/route-regressions-2/inputs.json": "capsules/db306addb9c9012a9f928210bd67615e0245ac3c59e32abba8412e8c7d5265e9.json", + "cargo/route-regressions-2/inputs.zip": "capsules/4a0ae23e1599f7647c5b62eedfbac7c1d714362990b957aa59553fd363e46bbe.zip", + "cargo/route-regressions-2/process.json": "cargo/route-regressions-2/process.json", + "cargo/route-regressions-2/result.json": "cargo/route-regressions-2/result.json", + "cargo/route-regressions-2/source-proof.json": "cargo/route-regressions-2/source-proof.json", + "cargo/route-regressions-2/started.json": "cargo/route-regressions-2/started.json", + "cargo/route-regressions-2/stderr.log": "cargo/route-regressions-2/stderr.log", + "cargo/route-regressions-2/stdout.log": "cargo/route-regressions-2/stdout.log", + "cargo/route-regressions-3/inputs.json": "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json", + "cargo/route-regressions-3/inputs.zip": "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip", + "cargo/route-regressions-3/process.json": "cargo/route-regressions-3/process.json", + "cargo/route-regressions-3/result.json": "cargo/route-regressions-3/result.json", + "cargo/route-regressions-3/source-proof.json": "cargo/route-regressions-3/source-proof.json", + "cargo/route-regressions-3/started.json": "cargo/route-regressions-3/started.json", + "cargo/route-regressions-3/stderr.log": "cargo/route-regressions-3/stderr.log", + "cargo/route-regressions-3/stdout.log": "cargo/route-regressions-3/stdout.log", + "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py", + "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py", + "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py" + }, + "members": { + "capsules/4a0ae23e1599f7647c5b62eedfbac7c1d714362990b957aa59553fd363e46bbe.zip": { + "bytes": 3043591, + "sha256": "4a0ae23e1599f7647c5b62eedfbac7c1d714362990b957aa59553fd363e46bbe" + }, + "capsules/cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35.zip": { + "bytes": 3043596, + "sha256": "cb78349d30b9b3828711f50a700e0db8e46b31977d5909e775a6abbf57a2dd35" + }, + "capsules/db306addb9c9012a9f928210bd67615e0245ac3c59e32abba8412e8c7d5265e9.json": { + "bytes": 126743, + "sha256": "db306addb9c9012a9f928210bd67615e0245ac3c59e32abba8412e8c7d5265e9" + }, + "capsules/e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5.json": { + "bytes": 126743, + "sha256": "e8d0acc2de87827cc220143aafcd4963122cfa6529cc679f886f9870954f30f5" + }, + "cargo/allocation-regressions-2/process.json": { + "bytes": 220, + "sha256": "8e65fce3dd862b78a7c5070711822af2e4099ee56dee15f4559e0adda7f65abb" + }, + "cargo/allocation-regressions-2/result.json": { + "bytes": 3345, + "sha256": "9aeea52a19472c7cd6274af330ba611382c7031b1a3cfa3728f13ba4353c1a95" + }, + "cargo/allocation-regressions-2/source-proof.json": { + "bytes": 603, + "sha256": "25c573fa3c37474de2a44b9e298daddc01aa84717435ee8bad080fd4ad5db594" + }, + "cargo/allocation-regressions-2/started.json": { + "bytes": 1612, + "sha256": "b8b5e728cc5758d7225f17a0878880c39a6e879f03e2107b6df261c9a2b6598b" + }, + "cargo/allocation-regressions-2/stderr.log": { + "bytes": 210, + "sha256": "1a13b97ab1dfa891ef6fa0e981e0b8bc4e17bc115bb6b2bce0e168a47c369981" + }, + "cargo/allocation-regressions-2/stdout.log": { + "bytes": 299506, + "sha256": "5553cfb160507bcfeba793a9336d60526e9849b89a11685de2410af742501443" + }, + "cargo/route-attachments-1/process.json": { + "bytes": 203, + "sha256": "cc6531c8d12842f011c909960547cbfd80f8b467435d0338971e8fea7d1e2e67" + }, + "cargo/route-attachments-1/result.json": { + "bytes": 3328, + "sha256": "ee3c271a97e9b6938c8e33cbb35a17b53bc8a6c7cd814dbf01c5897a08f4042d" + }, + "cargo/route-attachments-1/source-proof.json": { + "bytes": 598, + "sha256": "6cf60c7f472b27928a19573a5f558e42176a8f77a8e76462f4f54226b58578a6" + }, + "cargo/route-attachments-1/started.json": { + "bytes": 1595, + "sha256": "d47d26d311036a3f60c0c526d581744bcb8c089254bdbb4d9fdee9f5eed121d4" + }, + "cargo/route-attachments-1/stderr.log": { + "bytes": 210, + "sha256": "3e213115378cb561ca1805b9ac76d6ced710a1c9bc05358237ef2dc0aa5afa25" + }, + "cargo/route-attachments-1/stdout.log": { + "bytes": 296666, + "sha256": "1ee3c68790b0bbb3a6114d4a06f80866abdd75cd85105ed1e06b38e8486164e1" + }, + "cargo/route-format-1/process.json": { + "bytes": 116, + "sha256": "7a53591a1e2b9b70f4bfa1cac5e99b8f655ad197bc77f85e6b41bdde9c478632" + }, + "cargo/route-format-1/result.json": { + "bytes": 1872, + "sha256": "098a5b5002922967dddc30330555ab4b34574c91763171adad7732f620f70780" + }, + "cargo/route-format-1/source-proof.json": { + "bytes": 593, + "sha256": "3d1b4749654f7182ea5a59b402aac7de6863872df256a2876bc182ff295df60d" + }, + "cargo/route-format-1/started.json": { + "bytes": 1484, + "sha256": "e05f56bcd42f4c1faeace30b1090e13253d53c58c56c4be55bcabb05d3d12ba1" + }, + "cargo/route-format-1/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/route-format-1/stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/route-format-2/process.json": { + "bytes": 116, + "sha256": "896d65f9ccef7389e768bb47cfee5e660cd3fcb9fc4e5d7539bfeabd0a1186c3" + }, + "cargo/route-format-2/result.json": { + "bytes": 1872, + "sha256": "d73e18d2ed84ac8030e8e1b896f4a09367d27f2f0c43a242df1c02f7b1cd61c8" + }, + "cargo/route-format-2/source-proof.json": { + "bytes": 593, + "sha256": "d14829233926a809d061b031194f19541bea0203c56beb441f4c596d585f699b" + }, + "cargo/route-format-2/started.json": { + "bytes": 1484, + "sha256": "5319f5aad6f40b648701d52640f3eec07ee47bcde7a343bcd735cd7a2ec68d6d" + }, + "cargo/route-format-2/stderr.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/route-format-2/stdout.log": { + "bytes": 0, + "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + }, + "cargo/route-lint-1/process.json": { + "bytes": 179, + "sha256": "19449fa3c3005ab019daa4f8dc4ad032195dc3192983a0f05aab56bb38f7deaa" + }, + "cargo/route-lint-1/result.json": { + "bytes": 1961, + "sha256": "5cc9b045529ca458e7980ccceeb6f7ae98ef3ac86f9d7b8aedeae9065a81e6ce" + }, + "cargo/route-lint-1/source-proof.json": { + "bytes": 591, + "sha256": "6b643a140f408ce706aef87b31c716cb8b6b7ea1dd632ee6b60d96fc27d26a52" + }, + "cargo/route-lint-1/started.json": { + "bytes": 1566, + "sha256": "9acc933713a5c8171ea379812548f1d51ace982bc29bda1546f321066f864784" + }, + "cargo/route-lint-1/stderr.log": { + "bytes": 137, + "sha256": "2233336da05e39aa60c45cae62339002a904cf342d551ca5e68869c206c3ed23" + }, + "cargo/route-lint-1/stdout.log": { + "bytes": 269521, + "sha256": "ff8a21497364f30c012ca736f2f46dc73ea5a7ec46f1ee4ee534e50f38244a91" + }, + "cargo/route-regressions-2/process.json": { + "bytes": 198, + "sha256": "89f42020b064a65a6979a975e05f02e091cf939bce4a0be29220b75d7e023213" + }, + "cargo/route-regressions-2/result.json": { + "bytes": 1988, + "sha256": "5e437ac0f2c4db94352f8199ac53172b3af60a709de922cdf81361a46b21a838" + }, + "cargo/route-regressions-2/source-proof.json": { + "bytes": 598, + "sha256": "5f217f1318566ce1aa2637e848d324fe8933205c6740f48ff15532b8956d5411" + }, + "cargo/route-regressions-2/started.json": { + "bytes": 1590, + "sha256": "5f7cbe5936440e1eb91300babe5b64489880ed65129d5c1ac1bf5e6632a332a1" + }, + "cargo/route-regressions-2/stderr.log": { + "bytes": 166, + "sha256": "ad39fc56f685f7f3c6a9b4a342abff1f19f9daad28c394673be0e3a2a1cf2523" + }, + "cargo/route-regressions-2/stdout.log": { + "bytes": 295421, + "sha256": "8d488ecf03a78a1bee6f419ab1f8ea8d60d8b082d78df3ca9d1f1053898c09b3" + }, + "cargo/route-regressions-3/process.json": { + "bytes": 198, + "sha256": "f0f320268fb9038a69794983635473518c80729678ad2e5367e882f54f2a7ab6" + }, + "cargo/route-regressions-3/result.json": { + "bytes": 3325, + "sha256": "6ea156b2e27520e99a5d6cae234cae38bc421cdf33bfb9176431120f6537823b" + }, + "cargo/route-regressions-3/source-proof.json": { + "bytes": 598, + "sha256": "dce6830e0fa49bcbf4437d090ade5114b5a86d4a9fe6ad2015fc51fb1f63c54f" + }, + "cargo/route-regressions-3/started.json": { + "bytes": 1590, + "sha256": "93bbffadfaca7fac771f2f34822075415208d82119350021a4c097f29c69bf3e" + }, + "cargo/route-regressions-3/stderr.log": { + "bytes": 287, + "sha256": "d7ddcdea80dcdb2594a40a694ef81956d5f8a18fed026b6262a6fefe2966f012" + }, + "cargo/route-regressions-3/stdout.log": { + "bytes": 297050, + "sha256": "f7c21752b8d414e07e32c148b8aefa9977515fc8f1411fa59a9724d4ae092d6b" + }, + "comparators/7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a.py": { + "bytes": 10094, + "sha256": "7805832d5f563ab2d7a50dd3de700792b5d6f459c68f7b1d8bcfcc9800fa0c3a" + }, + "helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py": { + "bytes": 3827, + "sha256": "1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20" + }, + "helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py": { + "bytes": 1399, + "sha256": "58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119" + } + } +} diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/prepare.py b/harness/prerelease37-connection-evidence-20260924/route-checks/prepare.py new file mode 100644 index 00000000..18c3a5cc --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/prepare.py @@ -0,0 +1,110 @@ +"""Package explicitly selected closed gate captures without running Cargo.""" +from pathlib import Path +import argparse +import json +import zipfile +from verify import RAW_FILES, pin, parsed, need, run_name, verify_data, verify_package + +HERE = Path(__file__).resolve().parent + + +def collect(root, runs, helpers, comparators=()): + gates = root / ".local/prerelease37-gates" + candidates = [gates / name for name in ("gate.py", "source-proof.py")] + helpers + helper_bytes = [path.read_bytes() for path in candidates] + comparator_paths = [root / ".local/process-source-evidence-tools/verify.py", *comparators] + comparator_bytes = [path.read_bytes() for path in comparator_paths if path.is_file()] + payload, logical, specs = {}, {}, {} + def add(name, data): + stored = ("capsules/" + pin(data)["sha256"] + Path(name).suffix + if name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"} else name) + need(stored not in payload or payload[stored] == data, "deduplication collision") + payload[stored] = data + logical[name] = stored + helper_catalog = {} + for name, data in zip(("gate.py", "source-proof.py"), helper_bytes): + helper = "helpers/" + pin(data)["sha256"] + ".py" + add(helper, data) + helper_catalog[name] = helper + for run in runs: + folder = gates / run + need(folder.is_dir(), "run directory missing: " + run) + paths = list(folder.iterdir()) + names = {path.name for path in paths} + need(all(path.is_file() and not path.is_symlink() for path in paths) + and names in (RAW_FILES, RAW_FILES | {"source-proof.json"}), "exact closed raw files required: " + run) + raw = {path.name: path.read_bytes() for path in paths} + result = parsed(raw["result.json"]) + need("finish" in result and result["inputsUnchanged"] is True, "unfinished/changed run refused: " + run) + matches = [data for data in helper_bytes if pin(data) == result["helper"]] + need(bool(matches), "exact historical helper unavailable for " + run + "; supply --helper PATH") + helper = "helpers/" + result["helper"]["sha256"] + ".py" + add(helper, matches[0]) + for name, data in sorted(raw.items()): + add("cargo/" + run + "/" + name, data) + specs[run] = {key: result[key] for key in ("command", "head", "exitCode", "inputCount")} + specs[run]["helper"] = helper + if "source-proof.json" in raw: + proof = parsed(raw["source-proof.json"]) + matches = [data for data in comparator_bytes if pin(data) == proof["comparator"]] + need(bool(matches), "exact source comparator unavailable for " + run + "; supply --comparator PATH") + comparator = "comparators/" + proof["comparator"]["sha256"] + ".py" + add(comparator, matches[0]) + specs[run]["sourceProof"] = {"commit": proof["commit"], "pin": pin(raw["source-proof.json"]), "comparator": comparator} + manifest = {"schema": 1, "kind": "prerelease37-connection-admission-cargo-gates", "runs": specs, + "captureHelpers": helper_catalog, + "logicalFiles": dict(sorted(logical.items())), + "members": {name: pin(data) for name, data in sorted(payload.items())}} + summary = verify_data(manifest, payload.__getitem__) + return payload, manifest, summary + + +def write_json(path, value): + with path.open("xb") as output: + output.write((json.dumps(value, indent=2) + "\n").encode("utf-8")) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--root", type=Path, required=True, help="checkout holding .local/prerelease37-gates") + parser.add_argument("--runs", nargs="+", required=True, help="explicit run names, including failures to retain") + parser.add_argument("--helper", type=Path, action="append", default=[], help="additional exact historical helper (repeatable)") + parser.add_argument("--comparator", type=Path, action="append", default=[], help="additional exact historical source comparator (repeatable)") + parser.add_argument("--output", type=Path, help="fresh, nonexistent package directory (required unless --check-only)") + parser.add_argument("--check-only", action="store_true", help="validate raw captures in memory without creating an archive") + args = parser.parse_args() + need(all(run_name(run) for run in args.runs) and len(args.runs) == len(set(args.runs)), "unique safe run names required") + need(args.check_only or args.output is not None, "--output is required unless --check-only") + if not args.check_only: + need(not args.output.exists(), "output must be a fresh directory: " + str(args.output)) + payload, manifest, summary = collect(args.root.resolve(), args.runs, args.helper, args.comparator) + if args.check_only: + print("PASS raw consistency; no package written:", summary) + return + out = args.output.resolve() + out.mkdir(parents=True, exist_ok=False) + for name in ("evidence.zip", "manifest.json", "files.json"): + need(not (out / name).exists(), "existing package output refused: " + name) + for name in ("prepare.py", "verify.py", "README.md"): + data = (HERE / name).read_bytes() + destination = out / name + if destination.exists(): + need(destination.read_bytes() == data, "different existing package tool: " + name) + else: + with destination.open("xb") as output: + output.write(data) + with zipfile.ZipFile(out / "evidence.zip", "x", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as archive: + for name, data in sorted(payload.items()): + info = zipfile.ZipInfo(name, date_time=(2026, 9, 23, 0, 0, 0)) + info.compress_type = zipfile.ZIP_DEFLATED + info.external_attr = 0o100644 << 16 + archive.writestr(info, data) + write_json(out / "manifest.json", manifest) + names = ("prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip") + write_json(out / "files.json", {name: pin((out / name).read_bytes()) for name in names}) + need(verify_package(out) == summary, "written package differs from validated captures") + print("PASS package readback:", out, summary) + + +if __name__ == "__main__": + main() diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/selfcheck-final.txt b/harness/prerelease37-connection-evidence-20260924/route-checks/selfcheck-final.txt new file mode 100644 index 00000000..ca5ac13c --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/selfcheck-final.txt @@ -0,0 +1,37 @@ +Command: ['C:\\Users\\User\\.cache\\codex-runtimes\\codex-primary-runtime\\dependencies\\python\\python.exe', '-B', '.local/prerelease37-evidence-tools/selfcheck.py', '--root', 'C:/ar-multiselect-9e8r6t', '--runs', 'route-format-1', 'route-regressions-2', 'route-format-2', 'route-regressions-3', 'allocation-regressions-2', 'route-attachments-1', 'route-lint-1', '--output', '.local/prerelease37-evidence-tools/selfcheck-route-delivery'] +route-format-1 recorded exit 0 inputs 756 executable records 0 +route-regressions-2 recorded exit 101 inputs 756 executable records 0 +route-format-2 recorded exit 0 inputs 756 executable records 0 +route-regressions-3 recorded exit 0 inputs 756 executable records 1 +allocation-regressions-2 recorded exit 0 inputs 756 executable records 1 +route-attachments-1 recorded exit 0 inputs 756 executable records 1 +route-lint-1 recorded exit 0 inputs 756 executable records 0 +route-format-1 recorded exit 0 inputs 756 executable records 0 +route-regressions-2 recorded exit 101 inputs 756 executable records 0 +route-format-2 recorded exit 0 inputs 756 executable records 0 +route-regressions-3 recorded exit 0 inputs 756 executable records 1 +allocation-regressions-2 recorded exit 0 inputs 756 executable records 1 +route-attachments-1 recorded exit 0 inputs 756 executable records 1 +route-lint-1 recorded exit 0 inputs 756 executable records 0 +PASS package readback: C:\ar-multiselect-9e8r6t\.local\prerelease37-evidence-tools\selfcheck-route-delivery {'runs': 7, 'recordedFailures': 1, 'logicalFiles': 59, 'storedMembers': 49, 'sourceCapsulePairs': 2, 'captureHelpers': {'gate.py': 'helpers/1368375b1fba0dfc50b77ea4f406dba71960a78317ce8f259d4c4a0254863a20.py', 'source-proof.py': 'helpers/58597566ae1cb5c4021ddc7e86635b76d127bdb63b5d3026c427771aae7e2119.py'}, 'sourceProofs': 7} +route-format-1 recorded exit 0 inputs 756 executable records 0 +route-regressions-2 recorded exit 101 inputs 756 executable records 0 +route-format-2 recorded exit 0 inputs 756 executable records 0 +route-regressions-3 recorded exit 0 inputs 756 executable records 1 +allocation-regressions-2 recorded exit 0 inputs 756 executable records 1 +route-attachments-1 recorded exit 0 inputs 756 executable records 1 +route-lint-1 recorded exit 0 inputs 756 executable records 0 +route-format-1 recorded exit 0 inputs 756 executable records 0 +route-regressions-2 recorded exit 101 inputs 756 executable records 0 +route-format-2 recorded exit 0 inputs 756 executable records 0 +route-regressions-3 recorded exit 0 inputs 756 executable records 1 +allocation-regressions-2 recorded exit 0 inputs 756 executable records 1 +route-attachments-1 recorded exit 0 inputs 756 executable records 1 +route-lint-1 recorded exit 0 inputs 756 executable records 0 +PASS original raw/optional-proof/helper archive equality, existing-output refusal, and corruption rejection: ['raw stream/receipt mismatch', 'helper bytes/name mismatch', 'run/result exit mismatch', 'input archive mapping mismatch', 'missing closed receipt', 'source proof run relationship', 'source proof commit relationship', 'source proof result relationship', 'source proof inputCount relationship', 'missing declared optional source proof', 'source comparator bytes mismatch'] +Historical captured failures remain failures: 1 +No Cargo, archived code, or GUI executed. + +STDERR: + +Exit: 0 diff --git a/harness/prerelease37-connection-evidence-20260924/route-checks/verify.py b/harness/prerelease37-connection-evidence-20260924/route-checks/verify.py new file mode 100644 index 00000000..bfb11881 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/route-checks/verify.py @@ -0,0 +1,194 @@ +"""Offline consistency checks only; never execute or extract archived inputs.""" +from pathlib import Path, PurePosixPath +from datetime import datetime +import argparse +import hashlib +import io +import json +import math +import re +import stat +import zipfile + +RAW_FILES = {"started.json", "process.json", "result.json", "stdout.log", "stderr.log", "inputs.json", "inputs.zip"} +OUTER_FILES = {"prepare.py", "verify.py", "README.md", "manifest.json", "evidence.zip"} + + +def need(condition, message): + if not condition: + raise ValueError(message) + + +def pin(data): + return {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()} + + +def valid_pin(value): + return (isinstance(value, dict) and set(value) == {"bytes", "sha256"} + and type(value["bytes"]) is int and value["bytes"] >= 0 + and isinstance(value["sha256"], str) + and re.fullmatch(r"[0-9a-f]{64}", value["sha256"]) is not None) + + +def safe(name): + return (isinstance(name, str) and bool(name) and "\\" not in name and ":" not in name + and all(ord(char) >= 32 for char in name) + and not PurePosixPath(name).is_absolute() + and all(part not in ("", ".", "..") for part in name.split("/"))) + + +def run_name(name): + return isinstance(name, str) and re.fullmatch(r"[A-Za-z0-9][A-Za-z0-9._-]*", name) is not None + + +def parsed(data): + def pairs(items): + result = {} + for key, value in items: + need(key not in result, "duplicate JSON key: " + key) + result[key] = value + return result + def constant(value): + raise ValueError("nonfinite JSON constant: " + value) + return json.loads(data, object_pairs_hook=pairs, parse_constant=constant) + + +def inventory(archive, expected): + names = archive.namelist() + need(len(names) == len(set(names)) and set(names) == set(expected), "exact ZIP membership") + for entry in archive.infolist(): + need(safe(entry.filename) and not entry.is_dir(), "unsafe ZIP member: " + entry.filename) + need(not stat.S_ISLNK(entry.external_attr >> 16), "ZIP symlink: " + entry.filename) + need(valid_pin(expected[entry.filename]), "invalid member pin: " + entry.filename) + need(entry.file_size == expected[entry.filename]["bytes"], "ZIP recorded size: " + entry.filename) + + +def ordered_times(*values): + times = [datetime.fromisoformat(value) for value in values] + return all(value.utcoffset() is not None for value in times) and times == sorted(times) + + +def verify_data(manifest, read): + """Shared read-only verifier for packaged bytes or prepare's in-memory payload.""" + need(manifest["schema"] == 1 and manifest["kind"] == "prerelease37-connection-admission-cargo-gates", "manifest schema") + runs, logical, stored = manifest["runs"], manifest["logicalFiles"], manifest["members"] + helpers = manifest["captureHelpers"] + need(isinstance(helpers, dict) and set(helpers) == {"gate.py", "source-proof.py"}, "capture helper names") + need(all(isinstance(name, str) and re.fullmatch(r"helpers/[0-9a-f]{64}\.py", name) + for name in helpers.values()), "capture helper mapping") + need(isinstance(runs, dict) and bool(runs) and all(run_name(run) for run in runs), "explicit run inventory") + need(all(safe(name) for name in logical) and all(safe(name) for name in stored), "unsafe manifest path") + need(set(logical.values()) == set(stored), "unreferenced or absent stored members") + for name, expected in stored.items(): + need(valid_pin(expected) and pin(read(name)) == expected, "stored member hash: " + name) + expected_logical = {"cargo/" + run + "/" + name for run in runs for name in RAW_FILES} + expected_logical.update(spec["helper"] for spec in runs.values()) + expected_logical.update(helpers.values()) + for run, spec in runs.items(): + if "sourceProof" in spec: + proof_spec = spec["sourceProof"] + need(set(proof_spec) == {"commit", "pin", "comparator"}, run + ": exact source proof spec") + need(isinstance(proof_spec["commit"], str) and re.fullmatch(r"[0-9a-f]{40}", proof_spec["commit"]), run + ": named full source commit") + need(valid_pin(proof_spec["pin"]), run + ": source proof pin") + need(isinstance(proof_spec["comparator"], str) and re.fullmatch(r"comparators/[0-9a-f]{64}\.py", proof_spec["comparator"]), run + ": comparator path") + expected_logical.update({"cargo/" + run + "/source-proof.json", proof_spec["comparator"]}) + need(set(logical) == expected_logical, "exact logical raw/helper inventory") + for name, destination in logical.items(): + if name.startswith("cargo/") and name.rsplit("/", 1)[1] in {"inputs.json", "inputs.zip"}: + expected = "capsules/" + stored[destination]["sha256"] + PurePosixPath(name).suffix + need(destination == expected, "input capsule mapping: " + name) + else: + need(destination == name, "only input maps/archives may be deduplicated: " + name) + def raw(name): + return read(logical[name]) + for name, helper in helpers.items(): + need(helper == "helpers/" + pin(raw(helper))["sha256"] + ".py", "named helper hash: " + name) + seen_capsules = set() + for run, spec in runs.items(): + prefix = "cargo/" + run + "/" + start = parsed(raw(prefix + "started.json")) + process = parsed(raw(prefix + "process.json")) + result = parsed(raw(prefix + "result.json")) + required_start = {"start", "command", "cwd", "head", "scope", "inputs", "archive", + "inputCount", "environment", "helper", "cargo", "rustc"} + need(required_start <= start.keys(), run + ": incomplete start receipt") + need(all(result.get(key) == value for key, value in start.items()), run + ": start/result relationship") + command = result["command"] + need(isinstance(command, list) and command and command[0] == "cargo" + and all(isinstance(arg, str) for arg in command), run + ": Cargo command") + need(command == process["command"] == spec["command"], run + ": command relationship") + need(result["head"] == spec["head"] and re.fullmatch(r"(?:[0-9a-f]{40}|[0-9a-f]{64})", result["head"]), run + ": HEAD") + need(type(result["exitCode"]) is int and result["exitCode"] == spec["exitCode"], run + ": recorded exit") + need(result["inputsUnchanged"] is True, run + ": changed inputs refused") + need(type(result["seconds"]) in (int, float) and math.isfinite(result["seconds"]) + and result["seconds"] >= 0, run + ": duration") + need(type(process["pid"]) is int and process["pid"] > 0, run + ": process identity") + need(ordered_times(start["start"], process["observed"], result["finish"]), run + ": completed timestamp order") + for field, filename in [("inputs", "inputs.json"), ("archive", "inputs.zip"), ("stdout", "stdout.log"), ("stderr", "stderr.log")]: + need(result[field] == pin(raw(prefix + filename)), run + ": " + field + " pin") + need(valid_pin(result["helper"]) and result["helper"] == pin(raw(spec["helper"])), run + ": helper pin") + need(spec["helper"] == "helpers/" + result["helper"]["sha256"] + ".py", run + ": helper mapping") + inputs = parsed(raw(prefix + "inputs.json")) + need(isinstance(inputs, dict) and all(safe(name) for name in inputs), run + ": safe input inventory") + need(type(result["inputCount"]) is int and len(inputs) == result["inputCount"] == spec["inputCount"], run + ": input counts") + if "sourceProof" in spec: + proof_spec = spec["sourceProof"] + proof_bytes = raw(prefix + "source-proof.json") + proof = parsed(proof_bytes) + need(pin(proof_bytes) == proof_spec["pin"], run + ": source proof pinned bytes") + need(proof["run"] == run and proof["commit"] == proof_spec["commit"], run + ": proof run/commit identity") + need(proof["status"] == "PASS exact captured input inventory and Git blob bytes", run + ": source proof status") + need(proof["inputCount"] == len(inputs) and proof["inputMap"] == result["inputs"], run + ": proof input relationship") + need(proof["result"] == pin(raw(prefix + "result.json")), run + ": proof result relationship") + need(ordered_times(result["finish"], proof["verified"]), run + ": proof time after closed gate") + comparator = proof_spec["comparator"] + need(valid_pin(proof["comparator"]) and pin(raw(comparator)) == proof["comparator"], run + ": comparator bytes") + need(comparator == "comparators/" + proof["comparator"]["sha256"] + ".py", run + ": comparator identity") + need(sum(name.startswith("crates/vendor/iced_widget/") for name in inputs) == 71, run + ": vendor count") + capsule = (logical[prefix + "inputs.json"], logical[prefix + "inputs.zip"]) + if capsule not in seen_capsules: + with zipfile.ZipFile(io.BytesIO(raw(prefix + "inputs.zip"))) as source: + inventory(source, inputs) + for name, expected in inputs.items(): + need(pin(source.read(name)) == expected, run + ": source hash " + name) + seen_capsules.add(capsule) + artifacts = [] + for line in raw(prefix + "stdout.log").decode("utf-8", errors="replace").splitlines(): + try: + value = json.loads(line) + except json.JSONDecodeError: + continue + if isinstance(value, dict) and value.get("reason") == "compiler-artifact" and value.get("executable"): + artifacts.append(value) + need(isinstance(result["artifacts"], list), run + ": artifact records") + need(artifacts == [record["cargo"] for record in result["artifacts"]], run + ": Cargo JSON artifact relationship") + for record in result["artifacts"]: + need(set(record) == {"cargo", "readback"} + and (record["readback"] is None or valid_pin(record["readback"])), run + ": artifact readback pin") + print(run, "recorded exit", result["exitCode"], "inputs", len(inputs), "executable records", len(artifacts)) + return {"runs": len(runs), "recordedFailures": sum(spec["exitCode"] != 0 for spec in runs.values()), + "logicalFiles": len(logical), "storedMembers": len(stored), "sourceCapsulePairs": len(seen_capsules), + "captureHelpers": helpers, "sourceProofs": sum("sourceProof" in spec for spec in runs.values())} + + +def verify_package(root): + files = parsed((root / "files.json").read_bytes()) + need(set(files) == OUTER_FILES, "outer file inventory") + for name, expected in files.items(): + need(valid_pin(expected) and pin((root / name).read_bytes()) == expected, "outer hash: " + name) + manifest = parsed((root / "manifest.json").read_bytes()) + with zipfile.ZipFile(root / "evidence.zip") as archive: + inventory(archive, manifest["members"]) + return verify_data(manifest, archive.read) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("package", nargs="?", type=Path, default=Path(__file__).resolve().parent) + args = parser.parse_args() + print("PASS offline consistency:", verify_package(args.package)) + print("Historical receipts only; no source/binary execution or native acceptance claim.") + + +if __name__ == "__main__": + main() diff --git a/harness/prerelease37-connection-evidence-20260924/transport-readback.json b/harness/prerelease37-connection-evidence-20260924/transport-readback.json new file mode 100644 index 00000000..570258a2 --- /dev/null +++ b/harness/prerelease37-connection-evidence-20260924/transport-readback.json @@ -0,0 +1,7 @@ +{ + "url": "http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/raw/commit/c655c5eeaaa32c1c21074a7543844ae99a1d6fd5/harness/prerelease37-connection-evidence-20260924/checks/evidence.zip", + "bytes": 6087017, + "sha256": "30087db61aa4e045a522cf9db56d6b85b595012ebb6a1bb1d03bfb8bb213bd5c", + "seconds": 26.032, + "status": "PASS exact downloaded published artifact bytes" +}