Preserve combined peer strict lint and scoped core gate evidence
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
evidence.zip -text
|
||||
manifest.json -text
|
||||
verify.py -text
|
||||
README.md -text
|
||||
negative-controls-original.py -text
|
||||
negative-controls-result.json -text whitespace=cr-at-eol
|
||||
@@ -0,0 +1,99 @@
|
||||
# Combined peer candidate — partial Windows verification
|
||||
|
||||
This checkpoint records completed gates through strict workspace lint at source
|
||||
`f82e29d6b8ed2b5fd23ac806675d3eafe851d104`, published and ref-verified on
|
||||
`codex/peer-union-956atf-20260923`. It is not full workspace, desktop/native,
|
||||
public source8 or release acceptance. The live integration task is Gitea issue27;
|
||||
the source provenance and reviewed seams are in
|
||||
`f82e29d:harness/peer-union-20260923.md`.
|
||||
|
||||
## What ran
|
||||
|
||||
Windows Rust/Cargo 1.98.1 gnullvm, LLVM-MinGW 20260908 UCRT, offline locked
|
||||
dependencies, one compiler at a time. Each receipt records command, environment,
|
||||
source HEAD before/after, input hashes, original log and test executable hashes.
|
||||
The final strict gate uses `CARGO_BUILD_JOBS=1` and `CARGO_INCREMENTAL=0`.
|
||||
|
||||
| Source | Gate | Observed result | Captured inputs |
|
||||
| --- | --- | --- | --- |
|
||||
| `0b61771` | Core inventory / Scenario layout | 129 listed; 20 pass / 7 fail | 742 |
|
||||
| `2a0579d` | Core inventory / Scenario layout / source defaults | 129 listed; 27 / 22 pass | 742 |
|
||||
| `2a0579d` | Default omission integration target | 11 listed / 11 pass | 742 |
|
||||
| `015273a` | Combined core inventory / Scenario layout / source defaults | 129 listed; 27 / 22 pass | 758 |
|
||||
| `015273a` | Strict workspace all-target Clippy | Failed: example Diagram constructor missing layout | 758 |
|
||||
| `c489748` | Strict workspace all-target Clippy | Failed: missing attachment compile-time fixture | 758 |
|
||||
| `f82e29d` | Strict workspace all-target Clippy | Exit 0, no diagnostics | 760 |
|
||||
|
||||
These are 13 completed gate receipts. Passing scoped runs are matched to their
|
||||
actual same-source, same-executable inventories, with exact selected membership
|
||||
and outcomes. No historical counts are added into a combined total. The first
|
||||
seven failures are all source-lifecycle cases: parser field admission omitted
|
||||
`layout`. Fix `2a0579d` (combined cherry-pick `846cae8`) admits the field without
|
||||
adding synthetic layout-null editor defaults. Original failing logs remain.
|
||||
|
||||
The example fix `c4897485b7058570a563707c4f5840f500a6c265` adds only
|
||||
`layout: None` to `examples/release1/model.rs`. The fixture restoration
|
||||
`f82e29d6b8ed2b5fd23ac806675d3eafe851d104` imports exact peer `b8685416` bytes at
|
||||
`harness/experiments/edge-attachments-20260922/native-fixture.arcadia` (Git blob
|
||||
`f6419892143c9c08c22780de6060a7315be17930`). Neither changes crate implementation.
|
||||
An include-file audit also identified the existing textual-authoring
|
||||
`alarm-response.arcadia` fixture outside the previous manifest roots. The final
|
||||
760-input scope explicitly includes both compile-time fixtures; historical
|
||||
742/758-input receipts are not retrospectively expanded.
|
||||
|
||||
## Reproduce the evidence audit
|
||||
|
||||
Fetch the source commits named in `manifest.json`, then run from any directory:
|
||||
|
||||
```powershell
|
||||
python path/to/this/folder/verify.py --repo path/to/ARCADIA-Studio
|
||||
```
|
||||
|
||||
The standard-library verifier reads the ZIP in memory without extraction or
|
||||
executing archived code. It checks every payload hash, receipt/log/manifest
|
||||
binding, frozen source, unchanged inputs, recorded command/exit, exact test
|
||||
membership/outcomes (including the seven failures), helper hashes and 3,760
|
||||
distinct source-commit/input pairs against Git blobs. Executable bytes are not
|
||||
distributed in this archive; their recorded identity binds each scoped run to
|
||||
its listing but is not a substitute for rerunning the build.
|
||||
|
||||
The positive audit passes. Four falsification trials reject a corrupt payload,
|
||||
wrong outcome count, removed selected test outcome (with renewed wrapper hashes),
|
||||
and forged source input hash (also with renewed wrappers). The original local
|
||||
driver and hash-bound result are retained beside this report. The driver uses
|
||||
the original workspace paths; it is a record of these trials, not a second
|
||||
portable entrypoint.
|
||||
|
||||
To repeat the final strict gate from the identified source with the documented
|
||||
Windows toolchain and cached dependencies:
|
||||
|
||||
```powershell
|
||||
cargo clippy --locked --offline --workspace --all-targets -- -D warnings
|
||||
```
|
||||
|
||||
Focused test commands, filters and tool environment are preserved verbatim in
|
||||
the receipts. The archived launchers document capture behavior; they reference
|
||||
the original local layout and are evidence rather than portable build setup.
|
||||
|
||||
## Capture limits and pending acceptance
|
||||
|
||||
- Earlier helper `596dd821...` was reconstructed by reversing the known scope
|
||||
extension and package selection change; its exact hash matches the historical
|
||||
receipts. Helper `ddb37f5c...` was copied after its last run. Neither is claimed
|
||||
to be a launch-time copy. `launchers/capture-provenance.json` preserves this.
|
||||
Later gates retain immutable hash-keyed helper bytes before launch.
|
||||
- The final strict receipt's raw UTC span is 08:29:41–11:35:25, while Cargo reports
|
||||
5m42s. The clock discontinuity is retained; that span is not a duration claim.
|
||||
- The input inventory is a declared source scope, not a complete compiler file
|
||||
access trace. The discovered fixture omission and subsequent repair remain
|
||||
explicit. All recorded included inputs match their identified Git blobs.
|
||||
- Desktop discovery/execution, remaining integration targets, full workspace
|
||||
tests, matching GUI build and a combined native save/reopen workflow remain
|
||||
pending at this checkpoint. No running gate is included in the archive.
|
||||
- Public format adoption and normative Scenario language/API/OpenAPI coverage
|
||||
remain unresolved. The private analysis parser is a separate branch and is
|
||||
not part of this combined candidate. Linux remains user-deferred.
|
||||
|
||||
The source reviews retain their original pins and pre-execution dispositions.
|
||||
Passing these gates does not retroactively make a source review a runtime or
|
||||
native observation. Existing peer native evidence remains tied to its own source.
|
||||
Binary file not shown.
@@ -0,0 +1,512 @@
|
||||
{
|
||||
"archive_bytes": 580378,
|
||||
"archive_sha256": "4f4ef08a718296b7991908bfe7fd9ac02c0187eaeace0f2bdb77102d49eb9032",
|
||||
"payloads": {
|
||||
"gates/combined-core-defaults-1.admission.json": {
|
||||
"bytes": 2386,
|
||||
"sha256": "65bcad22c89ad57288d9dc350ecbfa8ee4eeb39cb9baa61255dc6cbac8872db5"
|
||||
},
|
||||
"gates/combined-core-defaults-1.inputs.json": {
|
||||
"bytes": 140816,
|
||||
"sha256": "418819b2c6e3032839cb70a8f8f49c7e8a7175a63be7463198f5be01be151e7f"
|
||||
},
|
||||
"gates/combined-core-defaults-1.log": {
|
||||
"bytes": 2402,
|
||||
"sha256": "ddd5f659e3dd728af38e317b5e893502cd43dc8e9520ce2be31ecf32f3243dd4"
|
||||
},
|
||||
"gates/combined-core-defaults-1.result.json": {
|
||||
"bytes": 1732,
|
||||
"sha256": "47768d9f82ce95596dc7ebc2517ab7120dace3a97f8153b393f267e70dc1c160"
|
||||
},
|
||||
"gates/combined-core-list-1.inputs.json": {
|
||||
"bytes": 140816,
|
||||
"sha256": "418819b2c6e3032839cb70a8f8f49c7e8a7175a63be7463198f5be01be151e7f"
|
||||
},
|
||||
"gates/combined-core-list-1.log": {
|
||||
"bytes": 13051,
|
||||
"sha256": "fd260e2847b22d569569828874849019579a06c66cea1197d8210ff1b2920030"
|
||||
},
|
||||
"gates/combined-core-list-1.result.json": {
|
||||
"bytes": 14548,
|
||||
"sha256": "a277ffe7c07c8897bb3d53d526e1d16d2b419f5d98037b8701d64b3d6f1cea6a"
|
||||
},
|
||||
"gates/combined-core-scenario-1.admission.json": {
|
||||
"bytes": 3369,
|
||||
"sha256": "b9669acff9abd0f129059aada8737c4c8f4ccc1ad7c92a5df10caa8110059ca2"
|
||||
},
|
||||
"gates/combined-core-scenario-1.inputs.json": {
|
||||
"bytes": 140816,
|
||||
"sha256": "418819b2c6e3032839cb70a8f8f49c7e8a7175a63be7463198f5be01be151e7f"
|
||||
},
|
||||
"gates/combined-core-scenario-1.log": {
|
||||
"bytes": 3405,
|
||||
"sha256": "1204984d0c27cfb2d4ebd950dd22a44b7d07e8244a486e034ae270050d86f640"
|
||||
},
|
||||
"gates/combined-core-scenario-1.result.json": {
|
||||
"bytes": 1732,
|
||||
"sha256": "bfe54a0f93444247a87ecdd0ffab722dec423daeb7f3e23bff9b4e92d00974ec"
|
||||
},
|
||||
"gates/combined-strict-1.inputs.json": {
|
||||
"bytes": 140816,
|
||||
"sha256": "418819b2c6e3032839cb70a8f8f49c7e8a7175a63be7463198f5be01be151e7f"
|
||||
},
|
||||
"gates/combined-strict-1.log": {
|
||||
"bytes": 1083,
|
||||
"sha256": "5e02d1cb074aad07aef432ec3c03628557152d4a9fb2b8dfb345515e0bdb75ee"
|
||||
},
|
||||
"gates/combined-strict-1.result.json": {
|
||||
"bytes": 1463,
|
||||
"sha256": "a76b065c39e89a88f23066d5a612c44561f36b648297058e53ef8319e0ccadaf"
|
||||
},
|
||||
"gates/combined-strict-2.inputs.json": {
|
||||
"bytes": 140816,
|
||||
"sha256": "2fde588400f967f7c5cef510cc38261fd1e5f46cba6e14915be83c9efe3a9654"
|
||||
},
|
||||
"gates/combined-strict-2.log": {
|
||||
"bytes": 633,
|
||||
"sha256": "c14924f72d19daa9cc50b1a73049bba93220354ab89da6c395071e7bc588adbf"
|
||||
},
|
||||
"gates/combined-strict-2.result.json": {
|
||||
"bytes": 1652,
|
||||
"sha256": "2fa1e8323385f45a796a1e07519b19980448e4cda065d0e92c0bfb795ca464ef"
|
||||
},
|
||||
"gates/combined-strict-3.inputs.json": {
|
||||
"bytes": 141223,
|
||||
"sha256": "91d917e0c329f74223eef11f02b25ecbd2b69ce7cc6482eede0a65548fd95255"
|
||||
},
|
||||
"gates/combined-strict-3.log": {
|
||||
"bytes": 265,
|
||||
"sha256": "b94556ab2b7c78e5375750201716449b58beb33782d470778d6eaf5789b9e909"
|
||||
},
|
||||
"gates/combined-strict-3.result.json": {
|
||||
"bytes": 1650,
|
||||
"sha256": "7e255308cc8f4fd077aada293d638badeef67faa1b7b56ecf597d2241193499c"
|
||||
},
|
||||
"gates/core-defaults-2.admission.json": {
|
||||
"bytes": 2368,
|
||||
"sha256": "750dc34cbfbc0f8ff2392f97de5161bf4216aa50a1c09c12b3ee5587c870d162"
|
||||
},
|
||||
"gates/core-defaults-2.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "8478620ab2deeef2625b9b3a485e2a2d39c9a958cbc8bbbcd1466e977aac57b7"
|
||||
},
|
||||
"gates/core-defaults-2.log": {
|
||||
"bytes": 2402,
|
||||
"sha256": "21c020d7a2131502c67c94db8781bb7905066661e6ee468112d138c1272ef026"
|
||||
},
|
||||
"gates/core-defaults-2.result.json": {
|
||||
"bytes": 1723,
|
||||
"sha256": "45f368f909bd94a0604cb51a7c13b752a72167d3ab779474ab87d7264ad9cd1d"
|
||||
},
|
||||
"gates/core-list-1.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "0bb00e62be1453a0a7cda619eae38d7014b95484f846e2242d36e940f9720a46"
|
||||
},
|
||||
"gates/core-list-1.log": {
|
||||
"bytes": 13051,
|
||||
"sha256": "0441f20249b8aa3a72a37e32fc692c4a132fc22847f4cdc5a4c5b34267f18c7d"
|
||||
},
|
||||
"gates/core-list-1.result.json": {
|
||||
"bytes": 14539,
|
||||
"sha256": "0a3697f101aeeb518381a885256df329471701fd5ab14a127324fe5e8e870e5a"
|
||||
},
|
||||
"gates/core-list-2.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "8478620ab2deeef2625b9b3a485e2a2d39c9a958cbc8bbbcd1466e977aac57b7"
|
||||
},
|
||||
"gates/core-list-2.log": {
|
||||
"bytes": 13051,
|
||||
"sha256": "74c0eebab60b4c832f402e5e7ddf9d71660f21153beb605b11b5c7baad2885de"
|
||||
},
|
||||
"gates/core-list-2.result.json": {
|
||||
"bytes": 14539,
|
||||
"sha256": "e12415ae2e5cf186990c977c933de7a35e7c7e9bf88e94980f089ef808d6c405"
|
||||
},
|
||||
"gates/core-scenario-1.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "0bb00e62be1453a0a7cda619eae38d7014b95484f846e2242d36e940f9720a46"
|
||||
},
|
||||
"gates/core-scenario-1.log": {
|
||||
"bytes": 9188,
|
||||
"sha256": "f91242c9be5b54163bb6b6f91d6057d9f525e8b21554c1e4ee782f67dc7eb3df"
|
||||
},
|
||||
"gates/core-scenario-1.result.json": {
|
||||
"bytes": 1725,
|
||||
"sha256": "60801831493c6dd1b714b3ed34b10a51b17e74e18489fa9270c4da8492d429d3"
|
||||
},
|
||||
"gates/core-scenario-2.admission.json": {
|
||||
"bytes": 3351,
|
||||
"sha256": "99c7636e643fb751f9655538f7320bd2f29e545127add3a7d60bf3bedb08f66c"
|
||||
},
|
||||
"gates/core-scenario-2.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "8478620ab2deeef2625b9b3a485e2a2d39c9a958cbc8bbbcd1466e977aac57b7"
|
||||
},
|
||||
"gates/core-scenario-2.log": {
|
||||
"bytes": 3405,
|
||||
"sha256": "3c9431f0eb0e156f227302012a4fd563378100615b192a84dd2ceedb41773d40"
|
||||
},
|
||||
"gates/core-scenario-2.result.json": {
|
||||
"bytes": 1723,
|
||||
"sha256": "c325748e5bf63ec4715f11e42135b20c9676884d9d310970dbde684ae52f183d"
|
||||
},
|
||||
"gates/defaults-list-2.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "8478620ab2deeef2625b9b3a485e2a2d39c9a958cbc8bbbcd1466e977aac57b7"
|
||||
},
|
||||
"gates/defaults-list-2.log": {
|
||||
"bytes": 1049,
|
||||
"sha256": "26f07434fce51f6607aef43832345c0be7dd28c173d7efccae8b0e981d99ea09"
|
||||
},
|
||||
"gates/defaults-list-2.result.json": {
|
||||
"bytes": 2447,
|
||||
"sha256": "1f7617e6cea7e89be6db15b59f66a18d5f5f9b1764a4e947a4294204915b6057"
|
||||
},
|
||||
"gates/defaults-run-2.admission.json": {
|
||||
"bytes": 1080,
|
||||
"sha256": "4b9b7924b93fedce7dbea9fac55bfc9a3c51cdb8237192c13f4733eb1b6e0326"
|
||||
},
|
||||
"gates/defaults-run-2.inputs.json": {
|
||||
"bytes": 137890,
|
||||
"sha256": "8478620ab2deeef2625b9b3a485e2a2d39c9a958cbc8bbbcd1466e977aac57b7"
|
||||
},
|
||||
"gates/defaults-run-2.log": {
|
||||
"bytes": 1102,
|
||||
"sha256": "fd14010517c7af06147efac854d888272021590fa49e7510ab510eb16b31417e"
|
||||
},
|
||||
"gates/defaults-run-2.result.json": {
|
||||
"bytes": 1748,
|
||||
"sha256": "e529b4bcd8aecbcbb1100c90a91777ea306b1813bf180d8ad3647d706d6e912d"
|
||||
},
|
||||
"launchers/0b14e2e80e4c02ecd31f6dfa5fdfaf1594a6bc3ac319530eca1a3c81505a478e.py": {
|
||||
"bytes": 7475,
|
||||
"sha256": "0b14e2e80e4c02ecd31f6dfa5fdfaf1594a6bc3ac319530eca1a3c81505a478e"
|
||||
},
|
||||
"launchers/596dd8212886096eb629cc690efa788ed72a1c2b44e40f8a0c2b691a1c13f7b5.py": {
|
||||
"bytes": 6532,
|
||||
"sha256": "596dd8212886096eb629cc690efa788ed72a1c2b44e40f8a0c2b691a1c13f7b5"
|
||||
},
|
||||
"launchers/capture-provenance.json": {
|
||||
"bytes": 966,
|
||||
"sha256": "a13d0b82f3b78604fa2a086cb16a7ae7df05592ed4dc3d4e0d0e6dd06d341936"
|
||||
},
|
||||
"launchers/ddb37f5c1ac03403b1f4d01fd04e1207e6f718c5b02401b885d78db7e1a89b20.py": {
|
||||
"bytes": 6802,
|
||||
"sha256": "ddb37f5c1ac03403b1f4d01fd04e1207e6f718c5b02401b885d78db7e1a89b20"
|
||||
},
|
||||
"launchers/df812935028c17145a72650c5e083c8609398e903139907d5d76db817b1524f6.py": {
|
||||
"bytes": 7314,
|
||||
"sha256": "df812935028c17145a72650c5e083c8609398e903139907d5d76db817b1524f6"
|
||||
},
|
||||
"reviews/composition-review.md": {
|
||||
"bytes": 13847,
|
||||
"sha256": "cb2391e8d4d84690b2852cca83f8c14aceb155ad363a257295063038a3e68d50"
|
||||
},
|
||||
"tools/admit-scenario-union-gate.py": {
|
||||
"bytes": 2887,
|
||||
"sha256": "15b248da53caadc3961650d5855d557dd41e72f35f055c323059684faf138816"
|
||||
}
|
||||
},
|
||||
"gates": [
|
||||
{
|
||||
"source": "015273ac8a7ce97d4aee678d653256abde222695",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"source_defaults",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "core",
|
||||
"name": "combined-core-defaults-1",
|
||||
"inputs": 758,
|
||||
"listing": "combined-core-list-1",
|
||||
"outcomes": [
|
||||
22,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
},
|
||||
{
|
||||
"source": "015273ac8a7ce97d4aee678d653256abde222695",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"--",
|
||||
"--list"
|
||||
],
|
||||
"mode": "list",
|
||||
"scope": "core",
|
||||
"name": "combined-core-list-1",
|
||||
"inputs": 758,
|
||||
"listed": 129
|
||||
},
|
||||
{
|
||||
"source": "015273ac8a7ce97d4aee678d653256abde222695",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"scenario_layout",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "core",
|
||||
"name": "combined-core-scenario-1",
|
||||
"inputs": 758,
|
||||
"listing": "combined-core-list-1",
|
||||
"outcomes": [
|
||||
27,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
},
|
||||
{
|
||||
"source": "015273ac8a7ce97d4aee678d653256abde222695",
|
||||
"exit": 101,
|
||||
"command": [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"--workspace",
|
||||
"--all-targets",
|
||||
"--",
|
||||
"-D",
|
||||
"warnings"
|
||||
],
|
||||
"mode": "clippy",
|
||||
"scope": "workspace",
|
||||
"name": "combined-strict-1",
|
||||
"inputs": 758
|
||||
},
|
||||
{
|
||||
"source": "c4897485b7058570a563707c4f5840f500a6c265",
|
||||
"exit": 101,
|
||||
"command": [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"--workspace",
|
||||
"--all-targets",
|
||||
"--",
|
||||
"-D",
|
||||
"warnings"
|
||||
],
|
||||
"mode": "clippy",
|
||||
"scope": "workspace",
|
||||
"name": "combined-strict-2",
|
||||
"inputs": 758
|
||||
},
|
||||
{
|
||||
"source": "f82e29d6b8ed2b5fd23ac806675d3eafe851d104",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"clippy",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"--workspace",
|
||||
"--all-targets",
|
||||
"--",
|
||||
"-D",
|
||||
"warnings"
|
||||
],
|
||||
"mode": "clippy",
|
||||
"scope": "workspace",
|
||||
"name": "combined-strict-3",
|
||||
"inputs": 760
|
||||
},
|
||||
{
|
||||
"source": "2a0579daafb89994730284c108f460782e5e6650",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"source_defaults",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "core",
|
||||
"name": "core-defaults-2",
|
||||
"inputs": 742,
|
||||
"listing": "core-list-2",
|
||||
"outcomes": [
|
||||
22,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
},
|
||||
{
|
||||
"source": "0b61771d079cae4a513958fad04e6c3e785d458f",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"--",
|
||||
"--list"
|
||||
],
|
||||
"mode": "list",
|
||||
"scope": "core",
|
||||
"name": "core-list-1",
|
||||
"inputs": 742,
|
||||
"listed": 129
|
||||
},
|
||||
{
|
||||
"source": "2a0579daafb89994730284c108f460782e5e6650",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"--",
|
||||
"--list"
|
||||
],
|
||||
"mode": "list",
|
||||
"scope": "core",
|
||||
"name": "core-list-2",
|
||||
"inputs": 742,
|
||||
"listed": 129
|
||||
},
|
||||
{
|
||||
"source": "0b61771d079cae4a513958fad04e6c3e785d458f",
|
||||
"exit": 101,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"scenario_layout",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "core",
|
||||
"name": "core-scenario-1",
|
||||
"inputs": 742,
|
||||
"listing": "core-list-1",
|
||||
"outcomes": [
|
||||
20,
|
||||
7,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
},
|
||||
{
|
||||
"source": "2a0579daafb89994730284c108f460782e5e6650",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--lib",
|
||||
"scenario_layout",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "core",
|
||||
"name": "core-scenario-2",
|
||||
"inputs": 742,
|
||||
"listing": "core-list-2",
|
||||
"outcomes": [
|
||||
27,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
},
|
||||
{
|
||||
"source": "2a0579daafb89994730284c108f460782e5e6650",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--test",
|
||||
"default_omission_preservation",
|
||||
"--",
|
||||
"--list"
|
||||
],
|
||||
"mode": "list",
|
||||
"scope": "defaults",
|
||||
"name": "defaults-list-2",
|
||||
"inputs": 742,
|
||||
"listed": 11
|
||||
},
|
||||
{
|
||||
"source": "2a0579daafb89994730284c108f460782e5e6650",
|
||||
"exit": 0,
|
||||
"command": [
|
||||
"cargo",
|
||||
"test",
|
||||
"--locked",
|
||||
"--offline",
|
||||
"-p",
|
||||
"oa-core",
|
||||
"--test",
|
||||
"default_omission_preservation",
|
||||
"--",
|
||||
"--test-threads=1"
|
||||
],
|
||||
"mode": "test",
|
||||
"scope": "defaults",
|
||||
"name": "defaults-run-2",
|
||||
"inputs": 742,
|
||||
"listing": "defaults-list-2",
|
||||
"outcomes": [
|
||||
11,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"ignored": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
from pathlib import Path
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
import zipfile
|
||||
|
||||
root = Path(__file__).resolve().parent.parent
|
||||
original = root / 'harness/experiments/peer-union-windows-20260923'
|
||||
scratch = root / '.local/peer-union-verifier-controls-20260923'
|
||||
scratch.mkdir(exist_ok=True)
|
||||
spec = importlib.util.spec_from_file_location('peer_verify', original / 'verify.py')
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
manifest = json.loads((original / 'manifest.json').read_bytes())
|
||||
with zipfile.ZipFile(original / 'evidence.zip') as z:
|
||||
data = {name: z.read(name) for name in z.namelist()}
|
||||
|
||||
|
||||
def sha(raw):
|
||||
return hashlib.sha256(raw).hexdigest()
|
||||
|
||||
|
||||
def refresh(payloads, claim, name, raw):
|
||||
payloads[name] = raw
|
||||
claim['payloads'][name] = {'bytes': len(raw), 'sha256': sha(raw)}
|
||||
|
||||
|
||||
reports = []
|
||||
for case in ('payload-corruption', 'outcome-count', 'missing-selected-outcome', 'git-input-binding'):
|
||||
payloads, claim = dict(data), copy.deepcopy(manifest)
|
||||
folder = scratch / case
|
||||
folder.mkdir(exist_ok=True)
|
||||
if case == 'payload-corruption':
|
||||
payloads['gates/combined-strict-3.log'] += b'corruption'
|
||||
elif case == 'outcome-count':
|
||||
next(g for g in claim['gates'] if g['name'] == 'combined-core-scenario-1')['outcomes'] = [26, 0, 0]
|
||||
elif case == 'missing-selected-outcome':
|
||||
name = 'gates/combined-core-scenario-1.log'
|
||||
lines = payloads[name].splitlines(keepends=True)
|
||||
removed = next(i for i, line in enumerate(lines) if line.startswith(b'test ') and b' ... ok' in line)
|
||||
del lines[removed]
|
||||
changed = b''.join(lines)
|
||||
refresh(payloads, claim, name, changed)
|
||||
receipt_name = 'gates/combined-core-scenario-1.result.json'
|
||||
receipt = json.loads(payloads[receipt_name])
|
||||
receipt['log_sha256'] = sha(changed)
|
||||
refresh(payloads, claim, receipt_name, json.dumps(receipt).encode())
|
||||
else:
|
||||
input_name = 'gates/combined-strict-3.inputs.json'
|
||||
inputs = json.loads(payloads[input_name])
|
||||
inputs['inputs'][0]['sha256'] = '0' * 64
|
||||
changed = json.dumps(inputs).encode()
|
||||
refresh(payloads, claim, input_name, changed)
|
||||
receipt_name = 'gates/combined-strict-3.result.json'
|
||||
receipt = json.loads(payloads[receipt_name])
|
||||
receipt['inputs_sha256'] = sha(changed)
|
||||
refresh(payloads, claim, receipt_name, json.dumps(receipt).encode())
|
||||
with zipfile.ZipFile(folder / 'evidence.zip', 'w', compression=zipfile.ZIP_DEFLATED) as z:
|
||||
for name, raw in payloads.items():
|
||||
z.writestr(name, raw)
|
||||
archive = (folder / 'evidence.zip').read_bytes()
|
||||
claim['archive_bytes'], claim['archive_sha256'] = len(archive), sha(archive)
|
||||
(folder / 'manifest.json').write_text(json.dumps(claim), encoding='utf-8')
|
||||
try:
|
||||
module.verify(folder, root)
|
||||
except AssertionError:
|
||||
reports.append({'case': case, 'result': 'REJECTED_AS_EXPECTED'})
|
||||
else:
|
||||
raise AssertionError('Corrupted evidence accepted: ' + case)
|
||||
report = {'source_archive_sha256': manifest['archive_sha256'], 'verifier_sha256': sha((original / 'verify.py').read_bytes()), 'controls': reports}
|
||||
(scratch / 'result.json').write_text(json.dumps(report, indent=2), encoding='utf-8')
|
||||
print(json.dumps(report, indent=2))
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"source_archive_sha256": "4f4ef08a718296b7991908bfe7fd9ac02c0187eaeace0f2bdb77102d49eb9032",
|
||||
"verifier_sha256": "d0d85cef3beaa41b1e03110d566043f1dee91d82d27fe6075f776a612962cab6",
|
||||
"controls": [
|
||||
{
|
||||
"case": "payload-corruption",
|
||||
"result": "REJECTED_AS_EXPECTED"
|
||||
},
|
||||
{
|
||||
"case": "outcome-count",
|
||||
"result": "REJECTED_AS_EXPECTED"
|
||||
},
|
||||
{
|
||||
"case": "missing-selected-outcome",
|
||||
"result": "REJECTED_AS_EXPECTED"
|
||||
},
|
||||
{
|
||||
"case": "git-input-binding",
|
||||
"result": "REJECTED_AS_EXPECTED"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
"""Audit the accompanying frozen-source gate archive without running its commands."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import zipfile
|
||||
|
||||
|
||||
def sha(raw):
|
||||
return hashlib.sha256(raw).hexdigest()
|
||||
|
||||
|
||||
def verify(folder, repo):
|
||||
manifest = json.loads((folder / 'manifest.json').read_bytes())
|
||||
archive = (folder / 'evidence.zip').read_bytes()
|
||||
assert len(archive) == manifest['archive_bytes']
|
||||
assert sha(archive) == manifest['archive_sha256']
|
||||
with zipfile.ZipFile(folder / 'evidence.zip') as z:
|
||||
assert len(z.namelist()) == len(set(z.namelist()))
|
||||
assert set(z.namelist()) == set(manifest['payloads'])
|
||||
data = {name: z.read(name) for name in z.namelist()}
|
||||
for name, raw in data.items():
|
||||
expected = manifest['payloads'][name]
|
||||
assert len(raw) == expected['bytes'] and sha(raw) == expected['sha256'], name
|
||||
|
||||
source_inputs = {}
|
||||
gates = {}
|
||||
for claim in manifest['gates']:
|
||||
name = claim['name']
|
||||
r = json.loads(data[f'gates/{name}.result.json'])
|
||||
raw = data[f'gates/{name}.log']
|
||||
input_raw = data['gates/' + r['inputs']]
|
||||
inputs = json.loads(input_raw)
|
||||
assert sha(raw) == r['log_sha256']
|
||||
assert sha(input_raw) == r['inputs_sha256']
|
||||
assert r['source'] == r['head_after'] == claim['source'] == inputs['source']
|
||||
assert r['changed_inputs'] == []
|
||||
assert r['exit'] == claim['exit']
|
||||
assert r['command'] == claim['command']
|
||||
assert r['mode'] == claim['mode'] and r['scope'] == claim['scope']
|
||||
assert r['launcher_sha256'] == r['launcher_sha256_after']
|
||||
launcher = data['launchers/' + r['launcher_sha256'] + '.py']
|
||||
assert sha(launcher) == r['launcher_sha256']
|
||||
assert len(inputs['inputs']) == claim['inputs']
|
||||
paths = [item['path'] for item in inputs['inputs']]
|
||||
assert len(paths) == len(set(paths))
|
||||
for item in inputs['inputs']:
|
||||
key = (r['source'], item['path'])
|
||||
assert key not in source_inputs or source_inputs[key] == item
|
||||
source_inputs[key] = item
|
||||
output = raw.decode('utf-8', errors='strict')
|
||||
if r['mode'] == 'list' and r['exit'] == 0:
|
||||
names = re.findall(r'^([^\r\n]+): test\r?$', output, re.M)
|
||||
assert names and len(names) == len(set(names))
|
||||
assert names == r['listing_members']
|
||||
assert len(names) == r['listing_count'] == claim['listed']
|
||||
assert len(r['artifacts']) == 1
|
||||
if r['mode'] == 'clippy' and r['exit'] == 0:
|
||||
assert re.search(r'Finished `dev` profile', output)
|
||||
assert not re.search(r'^error(?:\[|:)', output, re.M)
|
||||
gates[name] = (r, output, input_raw)
|
||||
|
||||
tests = []
|
||||
for claim in manifest['gates']:
|
||||
if 'listing' not in claim:
|
||||
continue
|
||||
r, output, input_raw = gates[claim['name']]
|
||||
listing, _, listed_inputs = gates[claim['listing']]
|
||||
assert r['mode'] == 'test' and listing['mode'] == 'list'
|
||||
assert r['source'] == listing['source'] and r['scope'] == listing['scope']
|
||||
assert input_raw == listed_inputs and r['artifacts'] == listing['artifacts']
|
||||
selected = {name for name in listing['listing_members'] if r['filter'] in name}
|
||||
assert selected
|
||||
outcomes = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)(?:, ([^\r\n]*))?\r?$', output, re.M)
|
||||
assert len(outcomes) == len({name for name, _, _ in outcomes}) == len(selected)
|
||||
assert {name for name, _, _ in outcomes} == selected
|
||||
counts = [sum(status == wanted for _, status, _ in outcomes) for wanted in ('ok', 'FAILED', 'ignored')]
|
||||
assert counts == claim['outcomes']
|
||||
summaries = re.findall(r'^test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored; (\d+) measured; (\d+) filtered out;', output, re.M)
|
||||
assert summaries == [tuple(map(str, [*counts, 0, len(listing['listing_members']) - len(selected)]))]
|
||||
ignores = [{'name': name, 'reason': reason} for name, status, reason in outcomes if status == 'ignored']
|
||||
assert ignores == claim.get('ignored', [])
|
||||
tests.append({'name': claim['name'], 'outcomes': counts, 'selected': len(selected)})
|
||||
|
||||
keys = sorted(source_inputs)
|
||||
run = subprocess.run(['git', 'cat-file', '--batch'], cwd=repo,
|
||||
input=''.join(f'{commit}:{path}\n' for commit, path in keys).encode(),
|
||||
capture_output=True, check=True)
|
||||
offset = 0
|
||||
for key in keys:
|
||||
end = run.stdout.index(b'\n', offset)
|
||||
fields = run.stdout[offset:end].split()
|
||||
assert len(fields) == 3 and fields[1] == b'blob', key
|
||||
size = int(fields[2])
|
||||
blob = run.stdout[end + 1:end + 1 + size]
|
||||
expected = source_inputs[key]
|
||||
assert size == expected['bytes'] and sha(blob) == expected['sha256'], key
|
||||
offset = end + 2 + size
|
||||
assert offset == len(run.stdout)
|
||||
return {'payloads': len(data), 'gates': len(gates), 'source_inputs': len(keys), 'tests': tests,
|
||||
'status': 'ARCHIVE_AND_RECORDED_SCOPE_VERIFIED',
|
||||
'limitation': 'Does not rerun commands, reconstruct executable bytes, establish native behavior, or accept a release. Historical failures and launcher-capture limits remain in README.'}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if not __debug__:
|
||||
raise SystemExit('Optimized Python is not supported')
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--repo', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
print(json.dumps(verify(Path(__file__).resolve().parent, args.repo), indent=2))
|
||||
Reference in New Issue
Block a user