Merge verdict-cache-fix e022b9ec into master (gate: green on 65bb1e36, recorded by tools/ci/pre-push.sh; landed on the box mirror)

This commit is contained in:
igneum-labs 2026-10-08 21:37:02 +00:00
commit 18f8aad347
6 changed files with 598 additions and 277 deletions

View file

@ -0,0 +1,35 @@
# Key succession on the live object: the H and W proposal (Phase 1 item d, 8 to 9 October 2026)
For the founder's word in the 08:00 UK read-back. The mechanism is docs/design/key-succession.md (`proving_key_succession_daa` H, `proving_key_succession_window_daa` W, `proving_next_shard_program_id` and `proving_next_aggregator_id` the next pair; both pairs verify for H <= d < H + W, only the next from H + W). Nothing here activates anything: the pin tool is on master, the real pin and the object's fields move on the founder's word.
## 1. The proposal
| Field | Proposed | Why |
|---|---|---|
| W, the window | one epoch of the live object: 3,600 DAA (`POW_EPOCH_BLOCKS`, consensus/core/src/igneum.rs; one hour at one block per second) | the coordinator's word (W one epoch). A prover on the old host keeps earning for the whole epoch it started in; the verdict cache's epoch key (`a_verdict_cached_in_the_window_is_not_valid_after_it`) and the fast-time runs below show both pairs verifying across a window and the right refusal on each side of it. The object's default of 86,400 (one day) is the mainnet clock; on the devnet a day of two pairs is a day of two hosts to keep, with no gain the runs could show. |
| H, the height | the first epoch boundary (a multiple of 3,600 DAA) at least one epoch after the end of a clean 24-hour run of the live chain on the 2.0.2 line: no finality pause, no reorg over depth 3, every fleet node on the cut; named as a DAA score in the object, never a clock | the coordinator's word (H after the chain's clean run). An epoch boundary so the window is one whole epoch of one seed; a full epoch of notice so every prover host has moved before the window opens (the fleet's hosts move with the kit, the app's with its update). |
| The next pair | pin C: shard 0x51cd8cba314a32b60fac393949a4571714da6d6656717d286011601b2a163fe7, aggregator 0x05b395ec238f67406084f8a449d400f64c87dc62151daebf66695864727ded8a (branch p22-stage-2-pin, b5b82c958; manifest source_commit c45db4420, guest input format 3; deterministic across three builds) | docs/analysis/v6-10-guest-repin-2026-10-08.md |
| The prior pair | the served pair 0x2b1a81cb… / 0x474678f3… (devnet-4's pinned pair) | the 2.0.1 kits embed it; the 17:58 UK pair 0x282dcfce… never activated and is skipped |
Consequences, stated: for a home prover on the app, the old host earns through the hour of the window and the app's update carries the new pair before it; for a fleet box, the kit's host moves at the cut, before H; for a pool, the pool's verifier accepts both pairs in the window and only the next after (the pool lane's rows). A record under the old pair carried after H + W pays nothing (the after-window row below); a record under the new pair carried before H pays nothing (the below-H row).
## 2. The evidence (fast time, three local nodes, the live pair as prior and the 17:58 pair as next, one real proof under each)
Every run on the verdict-cache fix node 3f672661 (review B F01/F02), build-8, 8 October 2026. The harness is infra/fast-time/proving-enforcement.mjs in succession mode; a chain at about one DAA per second with 60-DAA epochs; the attacker A carries what its pool holds, H1 and H2 refuse with the verifier in consensus. Every record carried in every run was refused on the right ground and nothing was ever paid; the runs differ only in how many of the six records the harness managed to get carried (its attacker's one-record-per-carrier shape, fixed over the evening).
| Run (UK) | H, W | Below H | In the window | After H + W | Paid | Verdict |
|---|---|---|---|---|---|---|
| 20:29 to 20:38 (vcache-2) | 240, 120 | next pair refused on its pair | prior pair accepted on its pair, refused on its statement | prior pair refused on its pair | none | the three carried records right; one record per phase carried (harness) |
| 20:42 to 20:55 (vcache-3) | 240, 120 | both refused on their statements: the second record's carrier landed after H (window too short for two records) | prior pair refused on its pair (its carrier past H + W) | prior pair refused on its pair | none | every refusal right for the carrier's DAA; the harness's clocks wrong |
| 20:56 to 21:14 (vcache-4) | 360, 300 | next pair on its pair, prior pair on its statement | both on their statements, none on a pair | prior pair on its pair; the next-pair record went unread (the attacker did not rejoin in 150 s) | none | five of six right |
| 21:15 to 21:33 (vcache-5) | 360, 300 | with the attacker's miner paused for the rejoin, A never rejoined (300 s, twice) | | | none | a harness fault, reverted |
| 21:34 to 22:04 (vcache-7) | 360, 300 | next pair on its pair, prior pair on its statement | both on their statements, none on a pair | prior pair on its pair, next pair on its statement | none | PASS: all six right; registry batch enforced-proving-20261008-02 |
What the rows establish for the live schedule: the pair accepted is decided by the carrier's DAA against H and H + W, not by when the record was made (vcache-3's second records, forged below H and carried after it, were judged at their carriers); both pairs verify inside the window and a verified proof is answered from its facts at each carrier, never from a stale refusal (the F01 shape of the 19:49 run is gone on the fix node); a window of two harness epochs held every record the attacker managed to carry inside it. None of this measures a live epoch: the harness's epoch is 60 DAA, the live object's 3,600, so W of one live epoch is 60 times the harness's smallest passing window relative to the record's lifetime (RECORD_WINDOW_CHAIN_BLOCKS), which is the margin the proposal rests on.
## 3. What the founder's word moves
1. The object's four fields on the 2.0.2 line's override and digest (the node lane's digest move, the start check accepting both pairs: the 291ee6ae check refuses an elf/ whose top pair is not the object's, so the pin and the fields move in one cut).
2. proving/igneum-prove/elf/ on master to pin C with the served pair as prior (p22-stage-2-pin), site/release-manifest.json's proof_guests and succession blocks (the steward's signed manifest with the sha256s 0ce9e351… / 3ef25e3f… elf and 0dbb6605… / 074eb906… vk).
3. The fleet's prover kit on the new host before H; the app's host in its next update before H.
4. The fast-time succession case rerun on the cut's node with pin C as next (the harness takes `--next-ids` and a `--next-proof` under pin C: one compressed proof of a devnet-4 block under the new host, about 100 s on a box CPU).

View file

@ -5203,39 +5203,33 @@
"owner": "Execution lead + independent implementer",
"manual_page": 38,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"run_id": "enforced-proving-20261008-01",
"updated": "2026-10-08T19:03:30.171Z",
"run_status": "PASS",
"evidence_path": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "EVM-08",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"dependency": "the first pin into elf/prior/ (the node lane, key-succession-pin, tonight by 21:00) and the devnet-4 succession height (main, by 22:00 under the floor rule)",
"in_progress_since": "2026-10-08T19:03:30.171Z",
"approvals": {
"scope_approved": null,
"implementation_complete": null,
@ -5244,34 +5238,26 @@
},
"evidence_records": {
"harness:proving-enforcement": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "EVM-08",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"run_id": "enforced-proving-20261008-01",
"evidence": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"in_progress": true
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
}
@ -5322,32 +5308,30 @@
"manual_page": 39,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log",
"run_id": "201-7cfa422a-aa0e0f45",
"updated": "2026-10-08T19:32:50.856Z",
"evidence_path": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log; docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "suite:exec",
"manifest_sha": "7cfa422a",
"coverage": {
"ZKP-01": "partial: a real proof verifies, a wrong statement and garbage are refused (nativeverify)",
"ZKP-03": "partial: a snapshot under another digest refused, the epoch streams bound to the digest",
"OPS-04": "partial: snapshot install, replay and genesis recapture after a crash",
"EVM-02": "partial: the replay tests on the day stream; the signature and chain-id binding vectors are an EVM harness still to map"
},
"at": "2026-10-08T19:32:50.856Z",
"method": "native",
"requirement_id": "ZKP-01",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"release_identity": {
"commit": "7cfa422a",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"in_progress_since": "2026-10-08T19:32:50.856Z",
"approvals": {
@ -5383,6 +5367,28 @@
"run_id": "201-7cfa422a-aa0e0f45",
"evidence": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log",
"in_progress": true
},
"harness:proving-enforcement": {
"requirement_id": "ZKP-01",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"release_identity": {
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
},
@ -5414,39 +5420,33 @@
"owner": "Proving + protocol leads; independent cryptography review",
"manual_page": 39,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"run_id": "enforced-proving-20261008-01",
"updated": "2026-10-08T19:03:30.171Z",
"run_status": "PASS",
"evidence_path": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-02",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"dependency": "the mixed-pair crossing needs the node lane's first pin into elf/prior/ (key-succession-pin, tonight by 21:00) and the next-pair proof (build-2:/home/build/enforced-fixtures/next-pair-block-56-shard-0-compressed.bin)",
"in_progress_since": "2026-10-08T19:03:30.171Z",
"approvals": {
"scope_approved": null,
"implementation_complete": null,
@ -5455,34 +5455,26 @@
},
"evidence_records": {
"harness:proving-enforcement": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-02",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"run_id": "enforced-proving-20261008-01",
"evidence": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"in_progress": true
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
},
@ -5515,32 +5507,30 @@
"manual_page": 39,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log",
"run_id": "201-7cfa422a-aa0e0f45",
"updated": "2026-10-08T19:32:50.856Z",
"evidence_path": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log; docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "suite:exec",
"manifest_sha": "7cfa422a",
"coverage": {
"ZKP-01": "partial: a real proof verifies, a wrong statement and garbage are refused (nativeverify)",
"ZKP-03": "partial: a snapshot under another digest refused, the epoch streams bound to the digest",
"OPS-04": "partial: snapshot install, replay and genesis recapture after a crash",
"EVM-02": "partial: the replay tests on the day stream; the signature and chain-id binding vectors are an EVM harness still to map"
},
"at": "2026-10-08T19:32:50.856Z",
"method": "native",
"requirement_id": "ZKP-03",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"release_identity": {
"commit": "7cfa422a",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"in_progress_since": "2026-10-08T19:32:50.856Z",
"approvals": {
@ -5576,6 +5566,28 @@
"run_id": "201-7cfa422a-aa0e0f45",
"evidence": "build-1:/srv/artefacts/tas/201-7cfa422a-aa0e0f45/node-7cfa422a/box4-exec.log",
"in_progress": true
},
"harness:proving-enforcement": {
"requirement_id": "ZKP-03",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"release_identity": {
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
},
@ -5607,39 +5619,33 @@
"owner": "Proving + protocol leads; independent cryptography review",
"manual_page": 40,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"run_id": "enforced-proving-20261008-01",
"updated": "2026-10-08T19:03:30.171Z",
"run_status": "PASS",
"evidence_path": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-04",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"dependency": "the proof side of the derivation (P22 stages 1 to 3) changes both guests' public values and so both program ids, so it ships only through a key succession (docs/design/key-succession.md, key-succession-node 291ee6ae); stage 1 (the inputs commitment carried by shard 0 and the aggregator, vetoed natively) is on branch p22-stage-1 under test since 18:46 UK; the clocks (stage 1 09:00, stage 2 14:00, stage 3's design 18:00 UK on 9 October 2026) stand because the succession's first height is asked of main by 22:00 under the floor rule; without a named height the stages are built and tested on their branch and wait for the succession that carries them",
"in_progress_since": "2026-10-08T19:03:30.171Z",
"approvals": {
"scope_approved": null,
"implementation_complete": null,
@ -5648,34 +5654,26 @@
},
"evidence_records": {
"harness:proving-enforcement": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-04",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"run_id": "enforced-proving-20261008-01",
"evidence": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"in_progress": true
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
},
@ -5707,38 +5705,32 @@
"owner": "Proving + protocol leads; independent cryptography review",
"manual_page": 40,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"run_id": "enforced-proving-20261008-01",
"updated": "2026-10-08T19:03:30.171Z",
"run_status": "PASS",
"evidence_path": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-05",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"in_progress_since": "2026-10-08T19:03:30.171Z",
"approvals": {
"scope_approved": null,
"implementation_complete": null,
@ -5747,34 +5739,26 @@
},
"evidence_records": {
"harness:proving-enforcement": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-05",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"run_id": "enforced-proving-20261008-01",
"evidence": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"in_progress": true
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
},
@ -5934,39 +5918,33 @@
"owner": "Proving + protocol leads; independent cryptography review",
"manual_page": 41,
"owner_lane": "enforced-proving lane (a6e8f84588b809d62)",
"run_status": "NOT RUN",
"evidence_path": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"run_id": "enforced-proving-20261008-01",
"updated": "2026-10-08T19:03:30.171Z",
"run_status": "PASS",
"evidence_path": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"run_id": "enforced-proving-20261008-02",
"updated": "2026-10-08T21:37:02.905Z",
"evidence_record": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-08",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
}
},
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
},
"dependency": "the proof side of the derivation (P22 stages 1 to 3) changes both guests' public values and so both program ids, so it ships only through a key succession (docs/design/key-succession.md, key-succession-node 291ee6ae); stage 1 (the inputs commitment carried by shard 0 and the aggregator, vetoed natively) is on branch p22-stage-1 under test since 18:46 UK; the clocks (stage 1 09:00, stage 2 14:00, stage 3's design 18:00 UK on 9 October 2026) stand because the succession's first height is asked of main by 22:00 under the floor rule; without a named height the stages are built and tested on their branch and wait for the succession that carries them",
"in_progress_since": "2026-10-08T19:03:30.171Z",
"approvals": {
"scope_approved": null,
"implementation_complete": null,
@ -5975,34 +5953,26 @@
},
"evidence_records": {
"harness:proving-enforcement": {
"cell": "harness:proving-enforcement",
"manifest_sha": "417c4a57",
"coverage": {
"ZKP-01": "partial: the seven refusals as named tests (no proof never inserted; a wrong proof and another program id invalidate the block; the honest record paid once) and the fast-time crossing with a modified producer; the genuine-proof positive control through ordinary network paths is the testnet's live read, not run here",
"ZKP-02": "partial: the pinned-id refusal on a real proof, the daemon's start refusal, key succession (the epochs, the accepted ids, a verdict counting only where its pair is accepted, the seven refusals on both sides of the height, the start refusal under a succession, the real-proof refusal of a pair the epoch does not accept) and the fast-time crossing of a scheduled succession with a real proof under each pair; the downgrade through an old node path is not run",
"ZKP-03": "partial: the chain binding (a record signed for another network), the replay, a wrong block, a wrong shard, a stale record outside the window; the fork and replayed-sync steps are not run",
"ZKP-04": "partial: an altered payout address (after signing and re-signed), a statement over altered rewards or payouts vetoed natively, the inputs commitment of P22 stage 1 (shard 0 and the aggregator carry the commitment the node recomputes) and the derivation commitment of stage 2 (the payouts derived in the guest from the carried records); the rewards' proved derivation is P22 stage 3, PENDING",
"ZKP-05": "partial: a duplicate of a paid record pays nothing and the honest record pays once; the race, reorder and crash-recover steps are not run",
"ZKP-08": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"EVM-08": "partial: the controlled verifier upgrade as a key succession (both pairs embedded, the window, the start refusal) and its fast-time crossing; the mixed-client crossing on the live network and the failed-distribution step are not run"
},
"at": "2026-10-08T19:03:30.171Z",
"method": "SP1",
"requirement_id": "ZKP-08",
"decision": "NOT RUN",
"reviewer": "",
"claim_impact": "",
"decision": "PASS",
"method": "native",
"cell": "harness:proving-enforcement",
"manifest_sha": "3f672661",
"run_id": "enforced-proving-20261008-02",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json",
"in_progress": false,
"coverage": "partial: the body rule and the payment rule read one floor, a producer with its body rule off still pays nothing on honest nodes (the fast-time crossing); the replacement-prover and authority steps are not run; the proof side of the derivation is P22 stage 3, PENDING",
"release_identity": {
"commit": "417c4a57",
"commit": "3f672661",
"lockfile": "",
"binary": "",
"network_object": "",
"activation": "",
"profile_hashes": ""
},
"run_id": "enforced-proving-20261008-01",
"evidence": "build-2:/home/build/enforced-fixtures/floor-240-expect-refuse.json",
"in_progress": true
"claim_impact": "",
"reviewer": "",
"at": "2026-10-08T21:37:02.905Z"
}
}
}
@ -12247,6 +12217,8 @@
"POW-01",
"ROT-02"
],
"run_id": "same-work-20261008-03",
"evidence_path": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json",
"updated": "2026-10-08T21:36:08.520Z",
"evidence_record": {
"requirement_id": "R2-F03-R03",
@ -12299,9 +12271,7 @@
"implementation_complete": null,
"evidence_reproduced": null,
"claim_authorised": null
},
"run_id": "same-work-20261008-03",
"evidence_path": "build-1:/srv/artefacts/tas/same-work-20261008-03/job-context.json"
}
},
{
"id": "R2-F04-R01",

View file

@ -0,0 +1,248 @@
{
"case": "succession-360-window-300",
"floor": "240",
"expect": "refuse",
"phases": {
"below": {
"daaAtForge": 121,
"forge": {
"block": 105,
"hash": "0x87fe67d16fda7174b0706fedd4bdafcbabbb2f808897944d7ec687570b6fb91f",
"second": {
"block": 254,
"hash": "0x110d897b880b165caa6c40478cc3238b58926576260882198210889954ee199f"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusals": {
"H1": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
},
"atFloor": {
"daaAtForge": 288,
"forge": {
"block": 374,
"hash": "0x8ce7a062860107fc4eb0596c0c28e22fa61fbc0ff5287730c78fae69226dd792",
"second": {
"block": 511,
"hash": "0xba04be731e0ae6b637820c5ffef1901b7985349579b4c1a3ad795d67a710ffea"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusalsBefore": {
"H1": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 2,
"dropped": 0,
"pair": 1,
"statement": 1,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
},
"refusalsAfter": {
"H1": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
},
"afterWindow": {
"daaAtForge": 675,
"forge": {
"block": 657,
"hash": "0xddb37d774fe5b5c0711a27984b6d25f7c2908ed58c14d00a69f9576274f41b46",
"second": {
"block": 786,
"hash": "0x525c035698dd1d756825d76b92019184023a6b5a3ef1221a51825bcc968a278f"
},
"shapes": [
{
"shape": "p-prior-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
},
{
"shape": "n-next-pair-proof",
"accepted": true,
"new": true,
"reason": "accepted"
}
]
},
"observed": {
"paid": [],
"carried": []
},
"refusalsBefore": {
"H1": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 4,
"dropped": 0,
"pair": 1,
"statement": 3,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
},
"refusalsAfter": {
"H1": {
"invalid": 6,
"dropped": 0,
"pair": 2,
"statement": 4,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
},
"H2": {
"invalid": 6,
"dropped": 0,
"pair": 2,
"statement": 4,
"garbage": 0,
"reasons": [
"a carried proof record's proof does not verify: shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 105 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 254 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 374 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 511 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926",
"a carried proof record's proof does not verify: shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9ed1b21bd53d (proof 92de5638f248a5c1): shard record block 657 shard 0 by 1bb65de716c3b466cd45a85b3ceddf7bcb9873e1821209ee76ec9",
"a carried proof record's proof does not verify: shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa92609d7c4943ba (proof 52f5ebdcc116da9f): shard record block 786 shard 0 by 990b90ac727bef6244fbbce29abcb47796dd1d197b2c4301aa926"
]
}
}
}
},
"node": "/srv/builds/igneum-wt-vcache/vendor/igneum-node/target/release/igneumd",
"slot": 0,
"ports": {
"base": 30890,
"suffix": 985
},
"startedAt": "2026-10-08T20:49:30.024Z",
"verdict": {
"pairBelow": 1,
"stmtBelow": 1,
"pairWindow": 0,
"stmtWindow": 2,
"pairAfter": 1,
"stmtAfter": 1,
"nothingPaid": true,
"pass": true
},
"endedAt": "2026-10-08T21:04:37.315Z"
}

View file

@ -63,6 +63,9 @@ const WINDOW = sflag('window', '120');
const NEXT_PROOF = sflag('next-proof');
const PRIOR_IDS = sflag('prior-ids'); // "0x<shard>,0x<agg>" of the prior pair, default the manifest's
const NEXT_IDS = sflag('next-ids'); // "0x<shard>,0x<agg>" of the next pair
// --drop-keys k1,k2: keys the 60x file lists that the node line under test does not know yet (OverrideParams refuses an
// unknown field); a node line behind master's file drops them
const DROP_KEYS = (sflag('drop-keys', '') || '').split(',').filter(Boolean);
const EXPECT = sflag('expect', FLOOR === 'never' ? 'pay' : 'refuse');
const GENESIS_BITS = flag('genesis-bits', 0x1f010000);
const CASE = sflag('case') || (SUCCESSION ? `succession-${SUCCESSION}-window-${WINDOW}` : `floor-${FLOOR}-expect-${EXPECT}`);
@ -94,7 +97,7 @@ await sleep(1000);
rmSync(TMP, { recursive: true, force: true }); mkdirSync(TMP, { recursive: true });
const track = (proc) => { started.push(proc); try { appendFileSync(PIDS, `${proc.pid}\n`); } catch { } };
const baseText = readFileSync(FILE, 'utf8');
let baseText = readFileSync(FILE, 'utf8');
const field = (name) => { const m = new RegExp(`"${name}":\\s*([0-9]+)`).exec(baseText); return m ? +m[1] : undefined; };
function mergeOverrideText(text, fields) {
let out = text;
@ -102,13 +105,14 @@ function mergeOverrideText(text, fields) {
const extra = Object.entries(fields).map(([k, v]) => `"${k}": ${typeof v === 'string' && !/^\d+$/.test(v) && v !== 'true' && v !== 'false' ? JSON.stringify(v) : v}`).join(', ');
return out.replace(/,?\s*}\s*$/, `,\n ${extra}\n}\n`);
}
for (const k of DROP_KEYS) baseText = baseText.replace(new RegExp(`\\s*"${k}":\\s*[^,}\\n]+,?`), '');
const DAY_MS = field('pow_day_ms');
const manifest = JSON.parse(readFileSync(MANIFEST, 'utf8'));
const override = `${TMP}/override.json`;
writeFileSync(override, mergeOverrideText(baseText, {
genesis_bits: GENESIS_BITS, skip_proof_of_work: false,
proving_v0_activation_daa: '0',
proving_consensus_verify_daa: FLOOR === 'never' ? NEVER : FLOOR,
proving_consensus_verify_daa: SUCCESSION ? '0' : (FLOOR === 'never' ? NEVER : FLOOR),
proving_shard_program_id: PRIOR_IDS ? PRIOR_IDS.split(',')[0] : manifest.shard.program_id, proving_aggregator_id: PRIOR_IDS ? PRIOR_IDS.split(',')[1] : manifest.aggregator.program_id,
verifier_in_consensus: 'false',
proving_key_succession_daa: SUCCESSION || NEVER, proving_key_succession_window_daa: WINDOW,
@ -182,8 +186,39 @@ const PAYOUT_A = '0x' + 'a1'.repeat(20), PAYOUT_B = '0x' + 'b2'.repeat(20);
async function daa(node) { const s = await node.exec('igneum_getExecStatus', []); return Number(s.executedTipDaa ?? 0); }
async function tipNumber(node) { const s = await node.exec('igneum_getExecStatus', []); return Number(s.executedTip ?? 0); }
async function sameTip(a, h) {
try { const x = await a.exec('igneum_getExecStatus', []); const y = await h.exec('igneum_getExecStatus', []); return x.executedTipHash && x.executedTipHash === y.executedTipHash; } catch { return false; }
}
/// Succession mode: the attacker's carrier is refused by the honest nodes and its chain dies with it; before the next
/// forge the attacker must be back on the honest tip (it follows the heavier honest chain), so the carrier it builds is
/// one the honest nodes will read.
async function rejoin(a, h, label) {
// 21:33 UK: pausing A's miner made the rejoin fail every time (A did not adopt H's chain in 300 s twice; with its
// miner running the rejoin took 15 to 130 s and failed once at 150 s), so the miner stays up and the wait is 600 s
for (let k = 0; k < 120; k++) { if (await sameTip(a, h)) { log(`${label}: A is on H1's tip (${k * 5} s)`); return true; } await sleep(5000); }
log(`${label}: A did not rejoin H1's tip in 600 s`); return false;
}
/// The seven shapes for shard 0 of A's chain block `n` (a block A has executed); returns what A's own pool answered.
async function forge(n, phase) {
/// The clocks that fit this shape (read from the 20:42 UK run on build-8, DAA about one per second): a rejoin after a
/// refused carrier took up to 100 s, so the second record of a phase lands 60 to 130 DAA after the first; the floor and
/// the window must leave room: --succession 360 --window 300 (below: records at about 100 and 230; window: about 370 and
/// 500 of 660; after: from 665), never --succession 240 --window 120, whose window closed on the second record.
/// Succession mode, one record per carrier (8 October 2026, 20:4x UK, read from the fix node's run: the attacker's
/// carrier dies with its refusal, so of two records forged on one block only the first is ever carried; the 18:49 run
/// on the pre-fix node read the other half for the same reason): the two shapes go on two blocks with a rejoin between.
async function forgeSuccession(phase, waitMs) {
let tip = await tipNumber(A);
const fa = await forge(Math.max(1, tip - 15), phase, 'p');
await sleep(waitMs / 2);
await rejoin(A, H1, `${phase}: before the second shape`);
tip = await tipNumber(A);
const fb = await forge(Math.max(1, tip - 15), phase, 'n');
await sleep(waitMs); // the second record's carrier and its refusal need the full wait (20:55 UK: a 60 s half missed the after-window one)
return { block: fa.block, hash: fa.hash, second: { block: fb.block, hash: fb.hash }, shapes: [...fa.shapes, ...fb.shapes] };
}
async function forge(n, phase, which = 'pn') {
const plan = await A.exec('igneum_getShardPlan', ['0x' + n.toString(16), PAYOUT_A]);
const block = plan.hash, statement = plan.shards[0].statement;
const planB = await A.exec('igneum_getShardPlan', ['0x' + n.toString(16), PAYOUT_B]);
@ -196,6 +231,19 @@ async function forge(n, phase) {
log(`${phase} ${name}: A's pool ${out.accepted ? 'accepted' : 'refused'} (${out.reason || ''})`);
return out;
};
if (SUCCESSION) {
// the real proof under each pair, each with A's native statement: refused on its pair where the epoch does not
// accept it, on its statement (another chain's) where it does
if (which.includes('p') && REAL_PROOF && existsSync(REAL_PROOF)) {
const real = readFileSync(REAL_PROOF);
await submit('p-prior-pair-proof', signRecord('forger-p', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(real)).record, hex(real));
}
if (which.includes('n') && NEXT_PROOF && existsSync(NEXT_PROOF)) {
const nextp = readFileSync(NEXT_PROOF);
await submit('n-next-pair-proof', signRecord('forger-n', CHAIN, block, n, 0, PAYOUT_B, statementB, '0x' + sha256(nextp)).record, hex(nextp));
}
return { block: n, hash: block, shapes };
}
const empty = Buffer.alloc(0), wrong = randomBytes(1024);
// (a) no proof bytes
await submit('a-no-proof', signRecord('forger-a', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(empty)).record, '0x');
@ -235,8 +283,10 @@ async function observe(n) {
}
const refusals = (node) => {
const t = node.logText();
return { invalid: (t.match(/IgneumInvalidProofRecord|invalid proof record|proof record .* does not verify|REFUSED/gi) || []).length, dropped: (t.match(/carried proofs did not arrive|did not deliver its carried proofs/g) || []).length,
pair: (t.match(/epoch does not accept|does not embed/g) || []).length, statement: (t.match(/public values hash to/g) || []).length };
const reasons = t.match(/a carried proof record's proof does not verify: [^\n]*/g) || [];
return { invalid: (t.match(/consensus verify of [^\n]*REFUSED/g) || []).length, dropped: (t.match(/carried proofs did not arrive|did not deliver its carried proofs/g) || []).length,
pair: reasons.filter(r => /does not accept|does not embed/.test(r)).length, statement: reasons.filter(r => /public values hash to/.test(r)).length,
garbage: reasons.filter(r => /not a bincode SP1 proof|not a compressed SP1 proof/.test(r)).length, reasons: reasons.map(r => r.slice(0, 260)) };
};
try {
@ -250,9 +300,9 @@ try {
log(`A at DAA ${d}, chain block ${tip}`);
if (d >= floor) log(`WARNING: the floor ${floor} was crossed before the first forge (DAA ${d}); lengthen --floor`);
// outside the 10-DAA exclusive window, where anyone may claim the shard (spec 07 7.2 item 4)
const n1 = Math.max(1, tip - 15);
const f1 = await forge(n1, 'below');
await sleep(45000);
const f1 = SUCCESSION ? await forgeSuccession('below', 45000) : await forge(Math.max(1, tip - 15), 'below');
const n1 = f1.block;
if (!SUCCESSION) await sleep(45000);
const o1 = await observe(n1);
result.phases.below = { daaAtForge: d, forge: f1, observed: o1, refusals: { H1: refusals(H1), H2: refusals(H2) } };
log(`below: H1 paid ${JSON.stringify(o1.paid)}; carried ${JSON.stringify(o1.carried)}`);
@ -260,11 +310,12 @@ try {
if (floor !== Infinity) {
while ((d = await daa(A)) < floor + 5) { log(`waiting for the floor: DAA ${d} of ${floor}`); await sleep(10000); }
} else await sleep(AFTER * 1000 / 2);
if (SUCCESSION) await rejoin(A, H1, 'before the window forge');
tip = await tipNumber(A);
const n2 = Math.max(1, tip - 15);
const beforeRefusals = { H1: refusals(H1), H2: refusals(H2) };
const f2 = await forge(n2, 'at-floor');
await sleep(AFTER * 1000);
const f2 = SUCCESSION ? await forgeSuccession('at-floor', AFTER * 1000) : await forge(Math.max(1, tip - 15), 'at-floor');
const n2 = f2.block;
if (!SUCCESSION) await sleep(AFTER * 1000);
const o2 = await observe(n2);
const afterRefusals = { H1: refusals(H1), H2: refusals(H2) };
result.phases.atFloor = { daaAtForge: d, forge: f2, observed: o2, refusalsBefore: beforeRefusals, refusalsAfter: afterRefusals };
@ -273,28 +324,27 @@ try {
if (SUCCESSION) {
const h = Number(SUCCESSION), w = Number(WINDOW);
while ((d = await daa(A)) < h + w + 5) { log(`waiting for the window's end: DAA ${d} of ${h + w}`); await sleep(10000); }
await rejoin(A, H1, 'before the after-window forge');
tip = await tipNumber(A);
const n3 = Math.max(1, tip - 15);
const r2 = { H1: refusals(H1), H2: refusals(H2) };
const f3 = await forge(n3, 'after-window');
await sleep(AFTER * 1000);
const f3 = await forgeSuccession('after-window', AFTER * 1000);
const n3 = f3.block;
const o3 = await observe(n3);
const r3 = { H1: refusals(H1), H2: refusals(H2) };
result.phases.afterWindow = { daaAtForge: d, forge: f3, observed: o3, refusalsBefore: r2, refusalsAfter: r3 };
const rb = result.phases.below.refusals, rw = afterRefusals;
// below H: the next-pair proof refused on its pair; in the window: no new pair refusal, both on statements;
// after H+W: the prior-pair proof refused on its pair
const pairBelow = rb.H1.pair > 0;
const pairWindow = rw.H1.pair - rb.H1.pair;
const stmtWindow = rw.H1.statement - rb.H1.statement;
const pairAfter = r3.H1.pair - r2.H1.pair;
// below H: the next-pair proof refused on its pair, the prior-pair proof on its statement (another chain's);
// in the window: both on their statements, none on a pair; after H+W: the prior-pair proof on its pair
const pairBelow = rb.H1.pair, stmtBelow = rb.H1.statement;
const pairWindow = rw.H1.pair - rb.H1.pair, stmtWindow = rw.H1.statement - rb.H1.statement;
const pairAfter = r3.H1.pair - r2.H1.pair, stmtAfter = r3.H1.statement - r2.H1.statement;
const nothingPaid = (o1.paid || []).length === 0 && (o2.paid || []).length === 0 && (o3.paid || []).length === 0;
const pass = pairBelow && pairWindow === 0 && stmtWindow > 0 && pairAfter > 0 && nothingPaid;
result.verdict = { pairBelow, pairWindow, stmtWindow, pairAfter, nothingPaid, pass };
const pass = pairBelow >= 1 && stmtBelow >= 1 && pairWindow === 0 && stmtWindow >= 2 && pairAfter >= 1 && stmtAfter >= 1 && nothingPaid;
result.verdict = { pairBelow, stmtBelow, pairWindow, stmtWindow, pairAfter, stmtAfter, nothingPaid, pass };
result.endedAt = new Date().toISOString();
mkdirSync(OUT.replace(/\/[^/]+$/, ''), { recursive: true });
writeFileSync(OUT, JSON.stringify(result, null, 2));
log(`RESULT ${pass ? 'PASS' : 'FAIL'}: below H pair refusals=${rb.H1.pair}; window new pair refusals=${pairWindow}, new statement refusals=${stmtWindow}; after H+W new pair refusals=${pairAfter}; nothing paid=${nothingPaid}; ${OUT}`);
log(`RESULT ${pass ? 'PASS' : 'FAIL'}: below H pair=${pairBelow} statement=${stmtBelow}; window pair=${pairWindow} statement=${stmtWindow}; after H+W pair=${pairAfter} statement=${stmtAfter}; nothing paid=${nothingPaid}; ${OUT}`);
await stopAll();
process.exit(pass ? 0 : 1);
}

View file

@ -0,0 +1,17 @@
{
"run_id": "enforced-proving-20261008-02",
"manifest_sha": "3f672661",
"evidence_dir": "docs/plans/proving-enforcement",
"boxes": [
"build-8"
],
"method": "native",
"cells": [
{
"cell": "harness:proving-enforcement",
"status": "PASS",
"evidence": "docs/plans/proving-enforcement/succession-360-window-300-vcache-7.json"
}
],
"note": "Key succession across a boundary on the review B F01/F02 fix node 3f672661 (harness-unsafe build, both pairs embedded): six refusals on the right ground (below H the next pair on its pair and the prior on its statement; in the window both on their statements, none on a pair; after H+W the prior on its pair and the next on its statement), nothing paid; 21:34 to 22:04 UK, floor 360, window 300, two records per phase."
}

View file

@ -43,6 +43,7 @@ docs/design/app-audit-2026-10-08.md
docs/ledger-public-pre-2.0.md
# 8 October 2026: the Devnet 3 proving pipeline record (the fleet lane: box names, the operations record, the external review quoted)
docs/analysis/proving-pipeline-2026-10-08.md
docs/design/key-succession-schedule.md
docs/analysis/v6-10-guest-repin-2026-10-08.md
docs/analysis/class-v6/coexistence-model.md
docs/analysis/class-v6/operator-simulation.md