Merge same-work-harness d4718b2d into master (gate: green on d4718b2d, recorded by tools/ci/pre-push.sh; landed on the box mirror under the exception declared by main: main's ruling, 7 Oct 2026 19:5x UK: the GitHub account is suspended, lanes land on the box mirror's master, the box gate stamp is the verdict; GitHub gets the fast-forward when it answers)

This commit is contained in:
igneum-labs 2026-10-08 21:59:19 +00:00
commit 73b8a91709
7 changed files with 106 additions and 72 deletions

View file

@ -55,8 +55,8 @@
"readers": {
"cpu_reference": "the reference files themselves (igneum-pow hash-bound, build-4)",
"cuda": "the kit worker igneum-worker-cuda gen 6 (sha256 804a6f7f...) --serve on packs.D, driven by the driver (prepare of packs.D1 before phase 2)",
"opencl": "igneum-worker-opencl --serve, PC 1 RX 7600, the morning (08:30 UK)",
"metal": "the mini's worker, the morning (08:30 UK)",
"opencl": "igneum-worker-opencl --serve, the project's first rig (RX 7600), the morning (08:30 UK)",
"metal": "the project's macOS machine's worker, the morning (08:30 UK)",
"node": "igneum-miner --recheck-vectors on a branch off class-v6-node-review e8773ff5 (IgneumEngine::epoch_for then hash_bound per nonce)",
"pool": "igneum-pool recheck --job-context (the member-side share verifier); on the 2.0.2 kit BLOCKED by its V5 pins, the D1 pairing against class-v6-node-review e8773ff5 a separate labelled row"
},

View file

@ -55,8 +55,8 @@
"readers": {
"cpu_reference": "the reference files themselves (igneum-pow hash-bound, build-4)",
"cuda": "the kit worker igneum-worker-cuda gen 6 (sha256 804a6f7f...) --serve on packs.D, driven by the driver (prepare of packs.D1 before phase 2)",
"opencl": "igneum-worker-opencl --serve, PC 1 RX 7600, the morning (08:30 UK)",
"metal": "the mini's worker, the morning (08:30 UK)",
"opencl": "igneum-worker-opencl --serve, the project's first rig (RX 7600), the morning (08:30 UK)",
"metal": "the project's macOS machine's worker, the morning (08:30 UK)",
"node": "igneum-miner --recheck-vectors on a branch off class-v6-node-review e8773ff5 (IgneumEngine::epoch_for then hash_bound per nonce)",
"pool": "igneum-pool recheck --job-context (the member-side share verifier); on the 2.0.2 kit BLOCKED by its V5 pins, the D1 pairing against class-v6-node-review e8773ff5 a separate labelled row"
},

View file

@ -9,7 +9,7 @@
"era_widths": 4,
"generator_tree": "release-2.0.1 c30ab32c (igneum-pow at the class v5 freeze 1c420786, fingerprint cbc5bd0a), built on build-4 at /srv/builds/igneum-wt-same-work-v5/igneum-pow",
"state_stream": {
"path": "state-epoch2.igsd1 (beside this file; from build-1's seed EVM RPC 127.0.0.1:27810 igneum_getPowStateLeaves for the seed block; the hand 26870 answered \"no published state stream\" for it at 22:18 UK)",
"path": "state-epoch2.igsd1 (beside this file; from build-1's seed EVM Rthe project's first rig27.0.0.1:27810 igneum_getPowStateLeaves for the seed block; the hand port 26870 answered \"no published state stream\" for it at 22:18 UK)",
"chain_block": 3423,
"block_hash": "3c3fab434f7fd894ce6db0b09f298c3865726253e4fc68fd77acd163ccea8221",
"root": "0xf798d1d89ee4de62...",
@ -56,8 +56,8 @@
"readers": {
"cpu_reference": "the reference files themselves (igneum-pow hash-bound, build-4)",
"cuda": "the kit worker igneum-worker-cuda 9bfcf728 (generation 5) --serve on packs.D, driven by the driver (prepare of packs.D1 before phase 2)",
"opencl": "igneum-worker-opencl --serve, PC 1 RX 7600, the morning (08:30 UK)",
"metal": "the mini's worker, the morning (08:30 UK)",
"opencl": "igneum-worker-opencl --serve, the project's first rig (RX 7600), the morning (08:30 UK)",
"metal": "the project's macOS machine's worker, the morning (08:30 UK)",
"node": "igneum-miner --recheck-vectors on the release line's engine (class v5 by construction); until the subcommand is on a release-line branch the row reads from same-work-node cc23f9bd labelled as such",
"pool": "igneum-pool recheck on the 2.0.2 kit as pinned (class v5 is nameable by its node)"
},

View file

@ -12100,30 +12100,30 @@
"POW-01",
"ROT-02"
],
"run_id": "same-work-20261008-02",
"evidence_path": "docs/design/class-v5-stored-state.md; build-1:/srv/artefacts/packs/packs-class-v6-20261008T202808Z.zip; build-1:/srv/builds/_log/v5-class/kits-20261008T202808Z/emu-check.log; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-3.json",
"updated": "2026-10-08T21:49:20.041Z",
"run_id": "same-work-20261008-03",
"evidence_path": "docs/design/class-v5-stored-state.md; build-1:/srv/artefacts/packs/packs-class-v6-20261008T202808Z.zip; build-1:/srv/builds/_log/v5-class/kits-20261008T202808Z/emu-check.log; build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-03/state-epoch2.igsd1",
"updated": "2026-10-08T21:59:18.945Z",
"evidence_record": {
"requirement_id": "R2-F03-R02",
"decision": "NOT RUN",
"method": "GPU",
"cell": "harness:same-work",
"manifest_sha": "c30ab32c",
"run_id": "same-work-20261008-02",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-3.json",
"run_id": "same-work-20261008-03",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-03/state-epoch2.igsd1",
"in_progress": false,
"coverage": "partial until every reader has run: bit-for-bit agreement per nonce across node, CPU reference, CUDA, OpenCL, Metal and pool on one job context",
"release_identity": {
"commit": "c30ab32c (packaging/release-manifest.json on release-2.0.1; node 7cfa422a); the readers: node same-work-node cc23f9bd (igneum-node, off class-v6-node-review e8773ff5, paired with class-v6 1a938abe4), CPU reference class-v6 1a938abe4, CUDA the kit's gen 6 worker 804a6f7f, pool pool-recheck-202 00c7e1db over class-v6-node-review e8773ff5",
"commit": "c30ab32c (release-2.0.1; the class v5 freeze 1c420786, fingerprint cbc5bd0a); the CUDA reader the kit's gen 5 worker 9bfcf728",
"lockfile": "",
"binary": "igneum-miner recheck-vectors sha256 9d563c41...; igneum-pow sha256 0d3f3fca...; igneum-worker-cuda sha256 804a6f7f...; igneum-pool sha256 b9fb3a60... (D1 pairing) and 2f6378e4... (kit)",
"network_object": "the chain-seed class v6 object: epoch seed af89be5d... (the node1 state stream's block 159357, root 1c583d35..., stream sha256 abb58003...) with the genesis era seed edc4fa84..., generator 6, id 0x2a1d6caab4c24564 (the hash lane's 22:00 UK ruling; their independent export hl-v6-all-cs a4742bfe... equals packs/chain-seed-d20730 file by file)",
"binary": "igneum-pow sha256 7ba781db... (release-2.0.1 c30ab32c, built on build-4); igneum-worker-cuda gen 5 sha256 9bfcf728...",
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC port 27810",
"activation": "none (a re-check of hashes against one job context, no chain state changes)",
"profile_hashes": ""
},
"claim_impact": "R2-F03-R02 and R03 on one job context (the chain-seed class v6 object) across the readers that can run it tonight: node, CPU reference, CUDA and pool on three phases with the dataset-day switch at nonce 1572864; PASS only when every reader agrees bit for bit on every nonce; Metal and OpenCL are the morning's",
"claim_impact": "the same-work test's live-chain half (the coordinator's third row, 22:1x UK): the readers on the chain's own class v5 object at epoch 2 across the day switch 20734 to 20735; the node and pool readers run it on their release-line engines, the row those two can PASS without the class v6 branch",
"reviewer": "",
"at": "2026-10-08T21:49:20.041Z",
"at": "2026-10-08T21:59:18.945Z",
"network_label": "on an island, not a network"
},
"evidence_records": {
@ -12155,21 +12155,21 @@
"method": "GPU",
"cell": "harness:same-work",
"manifest_sha": "c30ab32c",
"run_id": "same-work-20261008-02",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-3.json",
"run_id": "same-work-20261008-03",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-03/state-epoch2.igsd1",
"in_progress": false,
"coverage": "partial until every reader has run: bit-for-bit agreement per nonce across node, CPU reference, CUDA, OpenCL, Metal and pool on one job context",
"release_identity": {
"commit": "c30ab32c (packaging/release-manifest.json on release-2.0.1; node 7cfa422a); the readers: node same-work-node cc23f9bd (igneum-node, off class-v6-node-review e8773ff5, paired with class-v6 1a938abe4), CPU reference class-v6 1a938abe4, CUDA the kit's gen 6 worker 804a6f7f, pool pool-recheck-202 00c7e1db over class-v6-node-review e8773ff5",
"commit": "c30ab32c (release-2.0.1; the class v5 freeze 1c420786, fingerprint cbc5bd0a); the CUDA reader the kit's gen 5 worker 9bfcf728",
"lockfile": "",
"binary": "igneum-miner recheck-vectors sha256 9d563c41...; igneum-pow sha256 0d3f3fca...; igneum-worker-cuda sha256 804a6f7f...; igneum-pool sha256 b9fb3a60... (D1 pairing) and 2f6378e4... (kit)",
"network_object": "the chain-seed class v6 object: epoch seed af89be5d... (the node1 state stream's block 159357, root 1c583d35..., stream sha256 abb58003...) with the genesis era seed edc4fa84..., generator 6, id 0x2a1d6caab4c24564 (the hash lane's 22:00 UK ruling; their independent export hl-v6-all-cs a4742bfe... equals packs/chain-seed-d20730 file by file)",
"binary": "igneum-pow sha256 7ba781db... (release-2.0.1 c30ab32c, built on build-4); igneum-worker-cuda gen 5 sha256 9bfcf728...",
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC port 27810",
"activation": "none (a re-check of hashes against one job context, no chain state changes)",
"profile_hashes": ""
},
"claim_impact": "R2-F03-R02 and R03 on one job context (the chain-seed class v6 object) across the readers that can run it tonight: node, CPU reference, CUDA and pool on three phases with the dataset-day switch at nonce 1572864; PASS only when every reader agrees bit for bit on every nonce; Metal and OpenCL are the morning's",
"claim_impact": "the same-work test's live-chain half (the coordinator's third row, 22:1x UK): the readers on the chain's own class v5 object at epoch 2 across the day switch 20734 to 20735; the node and pool readers run it on their release-line engines, the row those two can PASS without the class v6 branch",
"reviewer": "",
"at": "2026-10-08T21:49:20.041Z",
"at": "2026-10-08T21:59:18.945Z",
"network_label": "on an island, not a network"
}
},
@ -12212,30 +12212,30 @@
"POW-01",
"ROT-02"
],
"run_id": "same-work-20261008-02",
"evidence_path": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json",
"updated": "2026-10-08T21:49:20.041Z",
"run_id": "same-work-20261008-03",
"evidence_path": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json",
"updated": "2026-10-08T21:59:18.945Z",
"evidence_record": {
"requirement_id": "R2-F03-R03",
"decision": "NOT RUN",
"method": "GPU",
"cell": "harness:same-work",
"manifest_sha": "c30ab32c",
"run_id": "same-work-20261008-02",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json",
"run_id": "same-work-20261008-03",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json",
"in_progress": false,
"coverage": "partial: the day-boundary transition in phase 2 (the one transition every live network crosses hourly at 60x); a class rotation is the same test on a research object until a v6 floor is set",
"release_identity": {
"commit": "c30ab32c (packaging/release-manifest.json on release-2.0.1; node 7cfa422a); the readers: node same-work-node cc23f9bd (igneum-node, off class-v6-node-review e8773ff5, paired with class-v6 1a938abe4), CPU reference class-v6 1a938abe4, CUDA the kit's gen 6 worker 804a6f7f, pool pool-recheck-202 00c7e1db over class-v6-node-review e8773ff5",
"commit": "c30ab32c (release-2.0.1; the class v5 freeze 1c420786, fingerprint cbc5bd0a); the CUDA reader the kit's gen 5 worker 9bfcf728",
"lockfile": "",
"binary": "igneum-miner recheck-vectors sha256 9d563c41...; igneum-pow sha256 0d3f3fca...; igneum-worker-cuda sha256 804a6f7f...; igneum-pool sha256 b9fb3a60... (D1 pairing) and 2f6378e4... (kit)",
"network_object": "the chain-seed class v6 object: epoch seed af89be5d... (the node1 state stream's block 159357, root 1c583d35..., stream sha256 abb58003...) with the genesis era seed edc4fa84..., generator 6, id 0x2a1d6caab4c24564 (the hash lane's 22:00 UK ruling; their independent export hl-v6-all-cs a4742bfe... equals packs/chain-seed-d20730 file by file)",
"binary": "igneum-pow sha256 7ba781db... (release-2.0.1 c30ab32c, built on build-4); igneum-worker-cuda gen 5 sha256 9bfcf728...",
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC port 27810",
"activation": "none (a re-check of hashes against one job context, no chain state changes)",
"profile_hashes": ""
},
"claim_impact": "R2-F03-R02 and R03 on one job context (the chain-seed class v6 object) across the readers that can run it tonight: node, CPU reference, CUDA and pool on three phases with the dataset-day switch at nonce 1572864; PASS only when every reader agrees bit for bit on every nonce; Metal and OpenCL are the morning's",
"claim_impact": "the same-work test's live-chain half (the coordinator's third row, 22:1x UK): the readers on the chain's own class v5 object at epoch 2 across the day switch 20734 to 20735; the node and pool readers run it on their release-line engines, the row those two can PASS without the class v6 branch",
"reviewer": "",
"at": "2026-10-08T21:49:20.041Z",
"at": "2026-10-08T21:59:18.945Z",
"network_label": "on an island, not a network"
},
"evidence_records": {
@ -12245,21 +12245,21 @@
"method": "GPU",
"cell": "harness:same-work",
"manifest_sha": "c30ab32c",
"run_id": "same-work-20261008-02",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json",
"run_id": "same-work-20261008-03",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json",
"in_progress": false,
"coverage": "partial: the day-boundary transition in phase 2 (the one transition every live network crosses hourly at 60x); a class rotation is the same test on a research object until a v6 floor is set",
"release_identity": {
"commit": "c30ab32c (packaging/release-manifest.json on release-2.0.1; node 7cfa422a); the readers: node same-work-node cc23f9bd (igneum-node, off class-v6-node-review e8773ff5, paired with class-v6 1a938abe4), CPU reference class-v6 1a938abe4, CUDA the kit's gen 6 worker 804a6f7f, pool pool-recheck-202 00c7e1db over class-v6-node-review e8773ff5",
"commit": "c30ab32c (release-2.0.1; the class v5 freeze 1c420786, fingerprint cbc5bd0a); the CUDA reader the kit's gen 5 worker 9bfcf728",
"lockfile": "",
"binary": "igneum-miner recheck-vectors sha256 9d563c41...; igneum-pow sha256 0d3f3fca...; igneum-worker-cuda sha256 804a6f7f...; igneum-pool sha256 b9fb3a60... (D1 pairing) and 2f6378e4... (kit)",
"network_object": "the chain-seed class v6 object: epoch seed af89be5d... (the node1 state stream's block 159357, root 1c583d35..., stream sha256 abb58003...) with the genesis era seed edc4fa84..., generator 6, id 0x2a1d6caab4c24564 (the hash lane's 22:00 UK ruling; their independent export hl-v6-all-cs a4742bfe... equals packs/chain-seed-d20730 file by file)",
"binary": "igneum-pow sha256 7ba781db... (release-2.0.1 c30ab32c, built on build-4); igneum-worker-cuda gen 5 sha256 9bfcf728...",
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC port 27810",
"activation": "none (a re-check of hashes against one job context, no chain state changes)",
"profile_hashes": ""
},
"claim_impact": "R2-F03-R02 and R03 on one job context (the chain-seed class v6 object) across the readers that can run it tonight: node, CPU reference, CUDA and pool on three phases with the dataset-day switch at nonce 1572864; PASS only when every reader agrees bit for bit on every nonce; Metal and OpenCL are the morning's",
"claim_impact": "the same-work test's live-chain half (the coordinator's third row, 22:1x UK): the readers on the chain's own class v5 object at epoch 2 across the day switch 20734 to 20735; the node and pool readers run it on their release-line engines, the row those two can PASS without the class v6 branch",
"reviewer": "",
"at": "2026-10-08T21:49:20.041Z",
"at": "2026-10-08T21:59:18.945Z",
"network_label": "on an island, not a network"
}
},

View file

@ -20,7 +20,7 @@
},
"claim_impact": "R2-F03-R02 and R03 on one job context (the chain-seed class v6 object) across the readers that can run it tonight: node, CPU reference, CUDA and pool on three phases with the dataset-day switch at nonce 1572864; PASS only when every reader agrees bit for bit on every nonce; Metal and OpenCL are the morning's",
"network_label": "on an island, not a network",
"note": "The same-work run (the coordinator's ruling 22:0x UK: six readers on one context; the frozen-object context 01 is the CUDA and CPU-only row). The node1 state stream (block af89be5d..., written on build-4 at 15:34 UK, before the 20:00 UK split) keys every item; every cell carries the island label by main's 22:2x UK rule. Day D = 20730 (bytes ...2ffa50), D+1 = 20731 (...2ffb50); phase 2 switches at 1572864 (the midpoint, 32-aligned); genesis day index 20730 and dataset 2^28 words for the engine's growth rule (doublings 0 on both days). CPU reference: igneum-pow hash-bound (class-v6 1a938abe4, binary 0d3f3fca...) on build-4, 21:48 to 21:57 UK, ref-D 7c7be9b5... over [0, 1572864), ref-D1 cad7849f... over [1572864, 3145728); the hash lane's independent million-nonce reference hl-v6-all-cs.txt (b77c61d8..., 22:03 UK) equals ref-D's first million lines byte for byte. Node reader: PASS on all three phases (22:17, 22:21, 22:25 UK; 1,048,576 agree each, 0 disagree, 0 missing; the boundary switched: d28fcfd70ba70a64 before, 45905ff3d608dc12 after, both equal to the reference; the program id unchanged across the day). Reader faults recorded, not disagreements: the node reader's first phase 1 at 22:10 UK read FAIL on every nonce with the program id equal because the standalone engine held the genesis day at 0 and the growth rule doubled the cache fourteen times (fixed at cc23f9bd: install_pow_genesis from the context and the pack, the live miner's own call); the pool lane's D1-pairing run at 22:17 UK hit the same class (its nonce 0 and 1 hashes equal the pre-fix node hashes byte for byte), fix sent 22:18 UK, rerun pending. The pool on the 2.0.2 kit as pinned (release-2.0.2 00c7e1db, node 7cfa422a) is BLOCKED: its node's ProgramClass enum ends at V5, so a class=v6 job line is unnameable (pool/kit-row/pool-{1,2,3}.json carry that refusal in the driver's shape). CUDA: the 5090's phase 1 PASS at 22:00 and 22:24 UK (gen 6 worker 804a6f7f, 47.6 s); phases 2 and 3 running at the time of this record (the fleet lane's runner restarted at 22:22 UK for the three-context file; its stray phase 2 and 3 lines at 22:23 were the restart's artefact, overwritten by the clean sequence). Rule 24 on same-work-node cc23f9bd on build-2: crate check rc 0, igneum-miner suite 30 passed 0 failed. (served-page words scrubbed at 22:4x UK, the steward's identity landing.)",
"note": "The same-work run (the coordinator's ruling 22:0x UK: six readers on one context; the frozen-object context 01 is the CUDA and CPU-only row). The node1 state stream (block af89be5d..., written on build-4 at 15:34 UK, before the 20:00 UK split) keys every item; every cell carries the island label by main's 22:2x UK rule. Day D = 20730 (bytes ...2ffa50), D+1 = 20731 (...2ffb50); phase 2 switches at 1572864 (the midpoint, 32-aligned); genesis day index 20730 and dataset 2^28 words for the engine's growth rule (doublings 0 on both days). CPU reference: igneum-pow hash-bound (class-v6 1a938abe4, binary 0d3f3fca...) on build-4, 21:48 to 21:57 UK, ref-D 7c7be9b5... over [0, 1572864), ref-D1 cad7849f... over [1572864, 3145728); the hash lane's independent million-nonce reference hl-v6-all-cs.txt (b77c61d8..., 22:03 UK) equals ref-D's first million lines byte for byte. Node reader: PASS on all three phases (22:17, 22:21, 22:25 UK; 1,048,576 agree each, 0 disagree, 0 missing; the boundary switched: d28fcfd70ba70a64 before, 45905ff3d608dc12 after, both equal to the reference; the program id unchanged across the day). Reader faults recorded, not disagreements (the coordinator's ruling 22:1x UK): the node reader's first phase 1 at 22:10 UK read FAIL on every nonce with the program id equal because the standalone engine held the genesis day at 0 and the growth rule doubled the cache fourteen times (fixed at cc23f9bd: install_pow_genesis from the context and the pack, the live miner's own call); the pool lane's D1-pairing run at 22:17 UK hit the same class (its nonce 0 and 1 hashes equal the pre-fix node hashes byte for byte), fix sent 22:18 UK; the rerun on the fixed reader (pool-recheck-202 909ae65b, binary 10425cc9... on build-4, the pack geometry installed) reads PASS on every phase at 22:32, 22:38 and 22:44 UK: 1,048,576 agree each, 0 disagree, 0 missing, the boundary switched at 1572864 with one program id on both segments, 64, 128 and 64 of the sampled shares accepted through verify::check; every nonce of 3,145,728 agrees with the reference (pool/d1-pairing/pool-{1,2,3}.json, sha256 d6d6105f..., 611c7e75..., 44820ff8..., read back on build-1 at 22:45 UK; the README keeps the first run's FAIL and its cause). The pool on the 2.0.2 kit as pinned (release-2.0.2 00c7e1db, node 7cfa422a) is BLOCKED: its node's ProgramClass enum ends at V5, so a class=v6 job line is unnameable (pool/kit-row/pool-{1,2,3}.json carry that refusal in the driver's shape). CUDA: the 5090's phase 1 PASS at 22:00 and 22:24 UK (gen 6 worker 804a6f7f, 47.6 s); phases 2 and 3 running at the time of this record (the fleet lane's runner restarted at 22:22 UK for the three-context file; its stray phase 2 and 3 lines at 22:23 were the restart's artefact, overwritten by the clean sequence). Rule 24 on same-work-node cc23f9bd on build-2: crate check rc 0, igneum-miner suite 30 passed 0 failed.",
"cells": [
{
"cell": "harness:same-work",
@ -29,8 +29,8 @@
],
"status": "NOT RUN",
"method": "GPU",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-3.json",
"note": "node PASS x3, CPU reference written and cross-checked, CUDA 5090 phase 1 PASS and phases 2 and 3 running, pool D1 pairing rerun pending after the install fix, pool kit row BLOCKED by its V5 pins, Metal and OpenCL NOT RUN until the morning (Metal 08:30 UK on the mini, OpenCL 08:30 UK on the project's first rig); the case stays NOT RUN in progress until every reader has read",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/kit-row/pool-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/d1-pairing/pool-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/d1-pairing/pool-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/d1-pairing/pool-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/d1-pairing/README.json; build-1:/srv/artefacts/tas/same-work-20261008-02/cuda-5090-1.json",
"note": "node PASS x3; pool D1 pairing PASS x3 (every nonce, the share verifier's own path, the day switch seen); CPU reference written and cross-checked twice; CUDA 5090 phase 1 PASS, phases 2 and 3 running; pool kit row BLOCKED by its V5 pins; OpenCL queued on the project's first rig (08:30 UK at the latest, the job run-ca3-pc1-samework-opencl-7600-20261008, its report staged as opencl-rx7600.report.txt); Metal NOT RUN, 08:30 UK on the project's macOS machine if a serve worker exists by 08:00 UK; the case stays NOT RUN in progress until every reader has read",
"network_label": "on an island, not a network",
"in_progress": true
},
@ -41,10 +41,10 @@
],
"status": "NOT RUN",
"method": "GPU",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json",
"note": "the dataset-day transition in phase 2: the node reader switched program and dataset at nonce 1572864 with the program id unchanged and both boundary hashes equal to the reference; the CUDA and pool phase 2 reads are pending; in progress",
"evidence": "build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-1.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-2.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node-3.json; build-1:/srv/artefacts/tas/same-work-20261008-02/node/node.log; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/references/ref-D1.txt; build-1:/srv/artefacts/tas/same-work-20261008-02/job-context.json; build-1:/srv/artefacts/tas/same-work-20261008-02/pool/d1-pairing/pool-2.json",
"note": "the dataset-day transition in phase 2: the node reader and the pool reader each switched program and dataset at nonce 1572864 with the program id unchanged and both boundary hashes equal to the reference; the CUDA phase 2 read is pending; in progress",
"network_label": "on an island, not a network",
"in_progress": true
}
]
}
}

View file

@ -16,11 +16,11 @@
"profile_hashes": "",
"commit": "c30ab32c (release-2.0.1; the class v5 freeze 1c420786, fingerprint cbc5bd0a); the CUDA reader the kit's gen 5 worker 9bfcf728",
"binary": "igneum-pow sha256 7ba781db... (release-2.0.1 c30ab32c, built on build-4); igneum-worker-cuda gen 5 sha256 9bfcf728...",
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC 27810"
"network_object": "igneum-devnet-4's class v5 object at epoch 2: id 0x81fbfa3aa413173f, epoch seed 3c3fab43... (the epoch-2 seed block, chain block 3423, common to every chain tonight: the split came after it), day 20734, era 0 seed 7c36b833... (class v5 reads no era; the id is the same under era zero), state stream state-epoch2.igsd1 (sha256 f36e6bba..., 21,132 bytes, 224 records, root 0xf798d1d8...) pulled at 22:18 UK from build-1's seed EVM RPC port 27810"
},
"claim_impact": "the same-work test's live-chain half (the coordinator's third row, 22:1x UK): the readers on the chain's own class v5 object at epoch 2 across the day switch 20734 to 20735; the node and pool readers run it on their release-line engines, the row those two can PASS without the class v6 branch",
"network_label": "on an island, not a network",
"note": "On an island, not a network: build-1's seed is one of devnet-4's islands since the epoch-3 cut (21:34 UK), its stream pulled at 22:18 UK; epoch 2's object predates the split. Context 03 at build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json (sha256 53837a96...). The witness for the id: igneum-miner program-id reads class v5 attempt 0 id 81fbfa3aa413173f under era 7c36b833... and era 00..00 alike, from the miner at same-work-node cc23f9bd on build-2 (the class v5 engine path; the 2.0.1 pair's miner ef0f2ed8 on build-1 has no program-id subcommand), and the node lane's placed (c) read gave the same id; the hand's RPC 26870 answered no published state stream for the block at 22:18 UK. Packs v5-epoch2-d20734 and d20735 (both id 0x81fbfa3aa413173f) exported from release-2.0.1's igneum-pow on build-4 at 22:19 UK; the CPU references run on build-4 under watchers from 22:20 UK (about 300 nonces a second a run); CUDA follows on the pods after contexts 02 and 01. Node and pool: the recheck subcommand is not on a release-line branch tonight, so those cells read NOT RUN with the 08:30 UK clock as the coordinator set; a labelled extra row from cc23f9bd's miner runs beside them when the references land.",
"note": "On an island, not a network: build-1's seed is one of devnet-4's islands since the epoch-3 cut (21:34 UK), its stream pulled at 22:18 UK; epoch 2's object predates the split. Context 03 at build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json (sha256 53837a96...). The witness for the id: igneum-miner program-id reads class v5 attempt 0 id 81fbfa3aa413173f under era 7c36b833... and era 00..00 alike, from the miner at same-work-node cc23f9bd on build-2 (the class v5 engine path; the 2.0.1 pair's miner ef0f2ed8 on build-1 has no program-id subcommand), and the node lane's placed (c) read gave the same id; the hand's RPC port port 26870 answered no published state stream for the block at 22:18 UK. Packs v5-epoch2-d20734 and d20735 (both id 0x81fbfa3aa413173f) exported from release-2.0.1's igneum-pow on build-4 at 22:19 UK; the CPU references run on build-4 under watchers from 22:20 UK (about 300 nonces a second a run); CUDA follows on the pods after contexts 02 and 01. Node and pool: the recheck subcommand is not on a release-line branch tonight, so those cells read NOT RUN with the 08:30 UK clock as the coordinator set; a labelled extra row from cc23f9bd's miner runs beside them when the references land.",
"cells": [
{
"cell": "harness:same-work",

View file

@ -12,6 +12,8 @@ the worker never answered.
(a worker argument that itself starts with "--" must be given as --worker-arg=--serve; argparse reads "--worker-arg --serve" as two options)
[--start 0] [--job-nonces 1048576] [--prehash <64 hex>] [--manifest <sha>] --out <evidence.json>
tools/ci/p01-vectors.py --worker <bin> [--worker-arg X ...] --job-context <job-context.json> --phase 1|2|3 --out <evidence.json>
tools/ci/p01-vectors.py --worker <bin> --worker-arg=--serve --job-context <file> --phase N --prepare-first --out <evidence.json>
(a worker with no --pack flag, the Metal worker: its first pack goes by a prepare line before any job)
tools/ci/p01-vectors.py --self-test
The job context (the same-work test, docs/plans/igneum-2.0-same-work-test.md) names two packs and two references (day D and
day D+1), the prehash, the range width (range_log2, 20) and the boundary nonce; phase N runs nonces [(N-1)*2^w, N*2^w): phase 1
@ -19,8 +21,9 @@ under day D, phase 3 under day D+1, phase 2 under day D up to the boundary nonce
boundary, and the evidence carries the boundary block (the nonce, the program id and day bytes on each side, the two hashes
either side) that the readers are compared on. A worker holds one (epoch, day) pair, so before any job the driver sends the
worker `prepare <seed bytes> <day D+1 bytes> <pack dir of day D+1>` and waits for its `prepared` line (a `prepare-failed` line or
a ready line saying `prepare 0` is an error: the day switch cannot be driven); the first job on day D+1 then switches the pair,
as the miner does at a real day switch.
a ready line saying `prepare 0` is an error: the day switch cannot be driven), keeps feeding day D jobs meanwhile (the worker loads
and reports the pair only between stdin lines, so a silent wait deadlocks: the 22:26 to 22:47 UK hang on the 5090), polls it with
a line a second when day D is spent, and sends the first day D+1 job only after `prepared`, as the miner does at a real day switch.
The job line is pool.rs's: `job <seq> <prehash hex> <share_target64 hex16> <start nonce> <nonces> <epoch seed bytes hex> <day bytes hex> class=<c> era=<era hex>`.
"""
import argparse, json, os, subprocess, sys, tempfile, time
@ -76,24 +79,34 @@ def run(a):
if line.startswith('ready'): ready = line.strip(); break
if time.time() - t0 > 120: break
if not ready: p.kill(); return {'error': 'the worker never said ready'}, 2
prepared = None
if len(seg_fields) > 1:
# the second segment's pair (day D+1) is prepared before any job: the worker builds it in the background and the first
# job on that day switches to it; a worker without prepare support cannot be driven across the boundary
if ' prepare 0' in ready: p.kill(); return {'error': f'the worker has no prepare support (ready line: {ready}); phase 2 needs it for the day switch'}, 2
ss2, se2, (sb2, db2, _c2, _er2, _pid2, _gen2) = seg_fields[1]
p.stdin.write(f"prepare {sb2} {db2} {segs[1][2]}\n"); p.stdin.flush()
t1 = time.time()
for line in p.stdout:
if line.startswith('prepared '): prepared = line.strip(); break
if line.startswith('prepare-failed'): p.kill(); return {'error': f'the worker refused the day D+1 pair: {line.strip()[:300]}'}, 2
if time.time() - t1 > 900: break
if not prepared: p.kill(); return {'error': 'the worker never said prepared for the day D+1 pair (900 s)'}, 2
# which segments the worker holds: a worker started on its --pack holds segment 1; a worker with no --pack flag (the Metal
# worker) takes its first pack by a prepare line (--prepare-first); the day D+1 segment always comes by prepare. The worker
# builds a pair in a background thread and loads and reports it only between stdin lines (proto-cuda/host.cu: "a finished
# nvcc step is loaded here, between lines"), as the miner's steady stream of jobs gives it; so the driver keeps feeding the
# jobs it can, never sends a job on a segment before that segment's prepared line, and when it has nothing to send it polls
# the worker with a line a second (the worker answers "info ignored", or the prepared line first). One prepare is in flight at
# a time (the worker refuses a second while one runs). A worker without prepare support cannot be driven across a boundary.
held = {i: (i == 0 and not a.prepare_first) for i in range(len(seg_fields))}
to_prepare = [i for i in range(len(seg_fields)) if not held[i]]; in_flight = None; prepare_sent = None; prepare_lines = []
if to_prepare and ' prepare 0' in ready: p.kill(); return {'error': f'the worker has no prepare support (ready line: {ready}); a pack by prepare or a day switch needs it'}, 2
def send_prepare():
nonlocal in_flight, prepare_sent
if in_flight is None and to_prepare:
i = to_prepare.pop(0); sb, db, c, er, _pid, _gen = seg_fields[i][2]
p.stdin.write(f"prepare {sb} {db} {segs[i][2]} class={c} era={er}\n"); p.stdin.flush(); in_flight = i; prepare_sent = time.time()
send_prepare()
got = {}; agree = 0; disagree = []; seq = 0; start = a.start; end = a.start + a.count; pending = set()
def feed():
nonlocal seq, start
while start < end and len(pending) < 4:
ss, se, (sb, db, c, er, _pid, _gen) = fields_at(start)
idx = next(i for i, (s1, e1, _f) in enumerate(seg_fields) if s1 <= start < e1)
if not held[idx]:
# no job on a segment before the worker says prepared for it; with nothing pending, poll the worker
if not pending:
if time.time() - prepare_sent > 900: p.kill(); raise SystemExit(f'p01-vectors: the worker never said prepared for segment {idx + 1} (900 s)')
time.sleep(1); p.stdin.write("ping\n"); p.stdin.flush()
return
n = min(a.job_nonces, end - start, se - start); seq += 1 # a job never crosses a segment edge (the day boundary)
p.stdin.write(f"job {seq} {a.prehash} {'f'*16} {start} {n} {sb} {db} class={c} era={er}\n"); p.stdin.flush()
pending.add(seq); start += n
@ -108,6 +121,15 @@ def run(a):
else:
if len(disagree) < 10: disagree.append({'nonce': n, 'gpu': h, 'cpu': r})
disagree_count[0] += 1
elif it[0] == 'prepared' and len(it) >= 3:
prepare_lines.append(line.strip())
for i, (_s1, _e1, f) in enumerate(seg_fields):
if f[1] == it[2] and f[0] == it[1]: held[i] = True
in_flight = None; send_prepare(); feed()
elif it[0] == 'prepare-failed':
p.kill(); return {'error': f'the worker refused a pair: {line.strip()[:300]}'}, 2
elif it[0] == 'info' and 'ignored' in line and not pending and start < end and not held[next(i for i, (s1, e1, _f) in enumerate(seg_fields) if s1 <= start < e1)]:
feed() # the poll's answer: ask again after a second
elif it[0] in ('done', 'error') and len(it) >= 2:
try: pending.discard(int(it[1]))
except ValueError: pass
@ -126,7 +148,7 @@ def run(a):
if jc is not None:
ev['job_context'] = os.path.abspath(a.job_context); ev['phase'] = int(a.phase); ev['object'] = jc.get('object')
ev['segments'] = [{'start': ss, 'end': se, 'program_id': f[4], 'day_bytes': f[1], 'class': f[2], 'pack': os.path.basename(os.path.abspath(sg[2]))} for (ss, se, f), sg in zip(seg_fields, segs)]
if prepared: ev['prepare_line'] = prepared
if prepare_lines: ev['prepare_lines'] = prepare_lines; ev['prepare_line'] = prepare_lines[-1]
if len(seg_fields) == 2:
b = seg_fields[1][0]; fb, fa = seg_fields[0][2], seg_fields[1][2]
ev['boundary'] = {'nonce': b, 'program_id_before': fb[4], 'program_id_after': fa[4], 'day_bytes_before': fb[1], 'day_bytes_after': fa[1],
@ -145,12 +167,17 @@ def self_test():
w = os.path.join(d, 'worker.py')
open(w, 'w').write('''import sys, os
print("ready fake-gpu 0 prepare " + ("0" if os.environ.get("NOPREPARE") == "1" else "1"), flush=True)
pending_prepare = None; prep_lines_left = 0
resident = {os.environ.get("RESIDENT", "cc" * 19)} # the pack's day (the real worker starts on its --pack); another day needs prepare first, as the real worker (day seed mismatch otherwise)
for line in sys.stdin:
p = line.split()
if p[0] == "prepare":
if os.environ.get("PREPFAIL") == "1": print(f"prepare-failed {p[1]} {p[2]} nvcc exit 1", flush=True); continue
resident.add(p[2]); print(f"prepared {p[1]} {p[2]} 12.0 nvcc 10.0 cache 1.0 dataset 1.0 resident 2 programs 2 datasets", flush=True); continue
if pending_prepare and prep_lines_left > 0: prep_lines_left -= 1 # PREPSLOW=n: the nvcc step takes n more lines (the driver must poll)
elif pending_prepare: # as the real worker: a finished prepare is loaded and reported between lines, on the next line of any kind
q = pending_prepare; pending_prepare = None
if os.environ.get("PREPFAIL") == "1": print(f"prepare-failed {q[0]} {q[1]} nvcc exit 1", flush=True)
else: resident.add(q[1]); print(f"prepared {q[0]} {q[1]} 12.0 nvcc 10.0 cache 1.0 dataset 1.0 resident 2 programs 2 datasets", flush=True)
if p[0] == "prepare": pending_prepare = (p[1], p[2]); prep_lines_left = int(os.environ.get("PREPSLOW", "0")); print("info prepare started", flush=True); continue
if p[0] == "ping": print("info ignored: ping", flush=True); continue
if p[0] != "job": continue
seq, start, n = int(p[1]), int(p[4]), int(p[5])
if p[7] not in resident: print(f"error {seq} day seed mismatch: the job's day seed {p[7]} is not resident", flush=True); print(f"done {seq} 0 0", flush=True); continue
@ -166,7 +193,7 @@ for line in sys.stdin:
base = ['--worker', sys.executable, '--worker-arg', w, '--pack', pack, '--reference', ref, '--count', '20', '--job-nonces', '8', '--manifest', 'deadbeef']
def go(env, tag):
out = os.path.join(d, f'{tag}.json'); e = dict(os.environ); e.update(env)
r = subprocess.run([sys.executable, __file__] + base + ['--out', out], env=e, capture_output=True, text=True); return r.returncode, json.load(open(out)) if os.path.exists(out) else {}
r = subprocess.run([sys.executable, __file__] + base + ['--out', out], env=e, capture_output=True, text=True, timeout=120); return r.returncode, json.load(open(out)) if os.path.exists(out) else {}
rc, ev = go({}, 'ok')
if not (rc == 0 and ev.get('verdict') == 'PASS' and ev['agree'] == 20 and ev['disagree'] == 0 and ev['missing'] == 0): print(f"self-test failed: a clean run was not PASS: rc={rc} {ev}"); fails = 1
rc, ev = go({'WRONG': '1'}, 'wrong')
@ -180,11 +207,11 @@ for line in sys.stdin:
refD1 = os.path.join(d, 'refD1.txt'); open(refD1, 'w').write(''.join(f"{k} {((k * 0x9e3779b97f4a7c15) % (1 << 64)) ^ 0xdd00dd00dd00dd00:016x}\n" for k in range(0, 48)))
jc = os.path.join(d, 'job-context.json')
json.dump({'object': 'fake', 'prehash': '00' * 31 + '01', 'range_log2': 4, 'boundary_nonce': 24, 'manifest': 'deadbeef', 'packs': {'D': pack, 'D1': pack2}, 'references': {'D': refD, 'D1': refD1}}, open(jc, 'w'))
def gojc(phase, tag, boundary=None, env=None):
def gojc(phase, tag, boundary=None, env=None, extra=()):
if boundary is not None:
j = json.load(open(jc)); j['boundary_nonce'] = boundary; json.dump(j, open(jc, 'w'))
out = os.path.join(d, f'{tag}.json'); e = dict(os.environ); e.update(env or {})
r = subprocess.run([sys.executable, __file__, '--worker', sys.executable, '--worker-arg', w, '--job-context', jc, '--phase', str(phase), '--job-nonces', '8', '--out', out], capture_output=True, text=True, env=e)
r = subprocess.run([sys.executable, __file__, '--worker', sys.executable, '--worker-arg', w, '--job-context', jc, '--phase', str(phase), '--job-nonces', '8', '--out', out] + list(extra), capture_output=True, text=True, env=e, timeout=120)
return r.returncode, (json.load(open(out)) if os.path.exists(out) else {}), r.stdout + r.stderr
for ph, s0, pid in ((1, 0, '0x1'), (3, 32, '0x2')):
rc, ev, o = gojc(ph, f'jc{ph}', env={'RESIDENT': 'dd' * 19} if ph == 3 else None) # phase 3's worker starts on the day D+1 pack
@ -193,10 +220,16 @@ for line in sys.stdin:
b = ev.get('boundary', {})
if not (rc == 0 and ev.get('verdict') == 'PASS' and ev['nonces'] == {'start': 16, 'count': 16} and b.get('nonce') == 24 and b.get('program_id_before') == '0x1' and b.get('program_id_after') == '0x2' and b.get('switched') is True and len(ev['segments']) == 2): print(f"self-test failed: phase 2 did not switch pack at the boundary nonce 24 with the boundary block: rc={rc} {b} {o[-200:]}"); fails = 1
if not (b.get('switched') is True and str(ev.get('prepare_line', '')).startswith('prepared ' + 'aa' * 32 + ' ' + 'dd' * 19) and ev['segments'][1]['pack'] == 'pack2'): print(f"self-test failed: phase 2 did not prepare the day D+1 pair before the first job on it: {ev.get('prepare_line')} {ev.get('segments')}"); fails = 1
rc, ev, o = gojc(2, 'jc2slow', env={'PREPSLOW': '3'})
b = ev.get('boundary', {})
if not (rc == 0 and ev.get('verdict') == 'PASS' and b.get('switched') is True and str(ev.get('prepare_line', '')).startswith('prepared ')): print(f"self-test failed: a worker whose prepare finishes three lines later (the driver must poll it) was not driven across the boundary: rc={rc} {b} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2first', env={'RESIDENT': 'none', 'PREPSLOW': '2'}, extra=['--prepare-first'])
b = ev.get('boundary', {})
if not (rc == 0 and ev.get('verdict') == 'PASS' and b.get('switched') is True and len(ev.get('prepare_lines', [])) == 2 and ev['prepare_lines'][0].split()[2] == 'cc' * 19): print(f"self-test failed: --prepare-first (a worker with no pack at start) did not prepare day D before the first job and day D+1 before the boundary: rc={rc} {ev.get('prepare_lines')} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2noprep', env={'NOPREPARE': '1'})
if rc != 2 or 'no prepare support' not in o: print(f"self-test failed: a worker without prepare support was not refused for phase 2: rc={rc} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2prepfail', env={'PREPFAIL': '1'})
if rc != 2 or 'refused the day D+1 pair' not in o: print(f"self-test failed: a prepare-failed line was not an error: rc={rc} {o[-200:]}"); fails = 1
if rc != 2 or 'refused a pair' not in o: print(f"self-test failed: a prepare-failed line was not an error: rc={rc} {o[-200:]}"); fails = 1
rc, ev, o = gojc(2, 'jc2bad', boundary=40)
if rc == 0 or 'not inside phase 2' not in o: print(f"self-test failed: a boundary outside phase 2 was not refused: rc={rc} {o[-200:]}"); fails = 1
if not fails: print('self-test passed: a clean million-shape run is PASS with the counts; one wrong hash is FAIL naming the nonce, the gpu and cpu hashes; an unanswered nonce is FAIL naming it; the job-context form runs each phase on its range and pack, splits phase 2 at the boundary nonce with the boundary block, and refuses a boundary outside phase 2; the job lines carry the pack fields and the all-pass target')
@ -208,6 +241,7 @@ if __name__ == '__main__':
ap.add_argument('--reference', default=''); ap.add_argument('--count', type=int, default=1_000_000); ap.add_argument('--start', type=int, default=0); ap.add_argument('--job-nonces', type=int, default=1 << 20)
ap.add_argument('--prehash', default='00' * 31 + '01'); ap.add_argument('--manifest', default=''); ap.add_argument('--out', required=True)
ap.add_argument('--job-context', default=''); ap.add_argument('--phase', type=int, default=0)
ap.add_argument('--prepare-first', action='store_true', help='the worker holds no pack at start (no --pack flag, the Metal worker): the first pack goes by a prepare line before any job')
a = ap.parse_args()
if a.job_context and not a.phase: ap.error('--job-context needs --phase 1|2|3')
if not a.job_context and not (a.pack and a.reference): ap.error('--pack and --reference, or --job-context with --phase')