From 0bc4df3fa874594737f29c57df61abdb6902ecfe Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 00:31:21 +0000 Subject: [PATCH] Ledger close round 3: the rebase onto 0.3.11 recorded on P23, M28, X20, X19, P15, M25, X22, P17; bench-log entry Status lines carry the branch ledger-fixes-0311 and its tip fbb0082a (the round-1 and round-2 commits named as rebased); P23 moves from Open to Fixed on a branch, pending merge, with the two unit tests and the conformance run as evidence. One round-3 paragraph per entry: the merge and its three conflicts, the X22 Option decision, the M28 stamp inside write_pack_checked and the end-to-end emu run on a miner-exported pack, the X19 fast-time file coupling, the Mac suite counts with the one 0.3.11-owned failure named. No "Count by status" section touched; no ledger text deleted. Co-Authored-By: Claude Fable 5.1 --- docs/bench-log.md | 35 +++++++++++++++++++++++++++++++++++ docs/fud-ledger.md | 30 ++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/docs/bench-log.md b/docs/bench-log.md index 446e7c340..05f19eb53 100644 --- a/docs/bench-log.md +++ b/docs/bench-log.md @@ -1861,3 +1861,38 @@ Owner: the ledger-pc2 agent. Fork branch `ledger-fixes-2` (worktree `vendor/igne Two artefacts of the fast profile worth one sentence each. The flag flickers to `paused` for 0.6 s at every checkpoint determination (00:26:19.5 determined, 00:26:20.1 locked: with presence window 1 the test `latest lock + window >= next index` fails for the gap), which showed on tx1 at 197.7 as a one-pass `finality paused`; at mainnet's window of 240 the gap is invisible. The 1-block selected-chain reorg is routine at 1 block/s with 50 ms links (20 on n0 in 7 minutes), so `reorged out` is a transient of about 2 s whenever the unwound block is merged again by the next chain block; a wallet treats it as final only after the merge depth, as design 2.3 says. Consequences. For a wallet or exchange: the one word is now in the RPC and `finalized` never names the tip; the pause shows as "finality not active" with the certificate still binding. For the pool: a reorged-out transaction is dropped from the node's view and must be resent (the pool owns no reorg hook; an item for the execution engineer, not changed here). Owed: the `proven` transition on a network with the proving loop; the phone app and the explorer still show the three words of phone-app 3 and 9 and need the `state` field (ledger X-side, not this round). + +## 6 October 2026 (night), ledger close round 3: the fork rebase onto 0.3.11, P23 the pool reorg hook, M28 end to end + +Machine: the Mac (M5 Max), every build under `tools/lock/with-lock.sh build` at `nice -n 19`, 4 cargo jobs, `cargo 1.99.0` from `~/.cargo/bin`; the fast-time network under `with-lock.sh run`. PC 2 was not used: the job "ledger-fixes-0311 suites" (target 1ccfe586, `--no-app`, seven suites) is publish-ready and queued last in the Counter ASIC 2.0 coordinator's PC 2 chain; no "go PC 2" came inside 30 minutes of the 23:45Z request, so the suites ran here and are labelled a Mac run. Docs branch `ledger-rebase` (from `fud-close` d16bc3b); fork worktree `igneum-wt-ledger-rebase/vendor/igneum-node-ledger0311`, branch `ledger-fixes-0311`. + +The rebase. `git merge --ff-only ledger-fixes-2` (b1e98b79), then `git merge 89dfcb95` (the 0.3.11 fork tip, Counter ASIC 2.0 on 21d4c73c). Three files conflicted, not the two the round-2 sizing counted: `protocol/flows/src/ibd/proof.rs` (two test hunks, 89dfcb95's tuple shape taken), `igneum/exec/src/service.rs` (one hunk, a union of P17's fields and proving v1's `paid_segments`), `igneum/miner/src/main.rs` (seven hunks: 89dfcb95's structure kept, M28's stamp moved inside `write_pack_checked`, X22's `Option` returns kept because 89dfcb95's `seeds_for` still carries `expect("dag info")`, M25's `pow_day_ms()` kept in `next_pair`). Merge 99ea7d97. The first build failed in `kaspa-pow` with 9 errors (`ProgramClass`, `Epoch::chain_program`, `Epoch::chain_dataset_day`, `verify::days_since_genesis` missing): the fork resolves `../../../../igneum-pow` from the checkout its worktree sits under, and neither master nor fud-close carries the Counter ASIC 2.0 crate. Fix: `ledger-rebase` takes `igneum-pow` as release-0.3.11 ships it (42be745, 11 files) and the fork worktree moved under `igneum-wt-ledger-rebase/vendor/` (`git worktree move`). Then: `cargo build --release -j 4 -p kaspad -p igneum-miner --features kaspad/igneum-pow` with `CARGO_TARGET_DIR` inside the worktree, seeded by an APFS clone (`cp -Rc`) of `vendor/igneum-node-ledger/target` (22 GB) and every tracked source re-stamped with `touch` (the copied-tree rule): 4 min 09 s. Test-only fallout from the merge, 7d4c8b3c: two `ChainBlockRecord` initializers without `carried_segments` (P15's and P17's tests), one `EpochSeeds` without `class` and `era` (X22's restart test). + +P23 (fbb0082a). `ExecState::truncate_to` collects the transactions a popped record held and no other chain block holds, with their raw bytes, in chain order, into `ExecState::unwound`; `ExecService::requeue_unwound` runs at the end of every follower pass, drops the ones the new chain executed in the meantime, and hands the rest to `EvmPool::on_chain_removed`, which runs each through `add` (the admission checks of a fresh submission against the current tip). Two unit tests (pool and state level). `cargo test --release -p igneum-exec -p igneum-miner`: igneum-exec 23 of 23, igneum-miner 20 of 20; the rebuild with P23 2 min 30 s. Conformance: `P17_BASE=30010 P17_SUFFIX=2010 IGNEUM_FIN_TMP=/tmp/igneum-p17-r3 IGNEUM_FORK_BIN=/target/release node tools/p17-conformance/run.mjs` (the driver's port base and suffix now come from the environment, 67990d0; 29990 was the plan, but another agent's Python held 29999 and the port gate gave up at 60 s), 23:59:43Z to 00:06:33Z. + +| Step | Round 2 (`ledger-fixes-2`, no hook) | Round 3 (`ledger-fixes-0311`, P23) | +|---|---|---| +| tx3 executed alone on the cut-off n2 | chain block 183 | chain block 0xed (237) at 281.7 s | +| Link healed, the heavier chain wins on n2 | 11 reorg lines; `unknown` with failure `reorged out` | 16 reorg lines; `pending` with failure `reorged out` from 0xed at 334.0 s | +| The pool | nothing (`on_chain_block` only) | n2 log 00:05:17.6Z: `reorg: 1 unwound transactions handed back to the pool as pending, 0 refused` | +| tx3 after the reorg | `unknown` for the 60 s the driver waited; a resend needed | `executed` in chain block 0x117 (279) at 336.4 s on n2, 337.4 s on n0; no resend (the driver has none) | +| Run | PASSED, 437.5 s | PASSED, 409.9 s | + +M28 end to end. `igneum-miner export-pack grpc://127.0.0.1:30010 ` against the run's node 0: epoch 0, day 1,243,919, class v2 (generator 2), attempt 0, 6 stamped files, `stamped .../program.json with kernel_sha256 over 6 files`, `checked`. `proto-cuda/nvrtc/emu/test.sh ` (build slot, 00:00:10Z to 00:01:09Z, 59 s; the test keeps a miner-written stamp now, 67990d0; `igneum-pow` built from `ledger-rebase`, 11 s): pack A `check PASS` in 2,216 ms with the miner's stamp (self-test PASS, 96 of 96 vector lanes), pack T refused before anything compiled (`kernel_bound.cu does not hash to the value the miner derived from the seed`), the annotation rule flagged as NVRTC does, the serve round PASS (64 + 64 + 32 found on A, prepared B with self-test PASS, swapped, 32 found on B, job 5 refused), 15 sampled hashes equal to `igneum-pow hash-bound`, 4 source-check PASS lines in `--serve` and 2 in `--check`. The worker half on fud-close therefore reads a 0.3.11 miner pack. + +Suites (Mac run). `cargo test --release -j 4 --no-fail-fast -p kaspad -p kaspa-consensus -p kaspa-consensus-core -p kaspa-mining -p kaspa-p2p-flows -p igneum-exec -p igneum-miner -p kaspa-pow --features kaspad/igneum-pow`, 00:07Z to 00:27Z: + +| Crate | Passed | Failed | Ignored | Note | +|---|---|---|---|---| +| kaspa-consensus | 99 | 1 | 4 | `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`: 0.3.11's own (the era-0 stand-in at `pruning_proof/igneum_pow.rs:114` is the genesis, the test expects `EpochSeeds::v2`'s zero era; both from 89dfcb95, nothing under `pruning_proof/` changed on the ledger branches; fails alone and single-threaded); reported to the Counter ASIC 2.0 coordinator, who owns it | +| kaspa-consensus-core | 108 | 0 | 2 | first run 107 and 1 failed: `fast_time_60x_file_is_the_devnet_at_60x` wanted 0.3.11's six fields in `infra/fast-time/override-60x.json`; fixed in `ledger-rebase` 2bbc12f (the dead `timestamp_deviation_tolerance` kept out, X19); db_compat 7 of 7 | +| kaspa-mining | 52 | 0 | 0 | | +| kaspa-p2p-flows | 36 | 0 | 0 | | +| kaspa-pow | 14 | 0 | 0 | | +| kaspad | 2 | 0 | 0 | | +| igneum-exec | 23 | 0 | 0 | 16 in round 2 | +| igneum-miner | 20 | 0 | 0 | 17 in round 1 | + +Commits. Fork `ledger-fixes-0311`: 99ea7d97 (merge), 7d4c8b3c (test fallout), fbb0082a (P23, the tip). Docs `ledger-rebase`: 42be745 (igneum-pow at release-0.3.11), 67990d0 (driver ports, emu test keeps the stamp), 2bbc12f (fast-time file), then the ledger and this entry. + +Consequences. For the next cut: fud-close now needs three things from this branch beside the fork tip, the `igneum-pow` crate at release-0.3.11, the fast-time file of 2bbc12f (0.3.11's copy is refused by X19's node), and the M28 worker halves, which this run shows accept a 0.3.11 miner pack; without the fork's miner commit every worker refuses every pack, as the closer's note says. For a miner on any card or platform: a transaction unwound by a reorg comes back by itself within a few blocks, and a pack the miner writes is accepted by the one-click workers; nothing to do. For a wallet: `reorged out` is now a transient of a few seconds on a node that keeps the transaction, not a prompt to resend. Still owed: the PC 2 run of these suites (the slot stands), the tampered pack on PC 2's RTX 5090, 0.3.11's M20 era test (the coordinator's), the restart timing of X22 and the clock-offset run of X19. diff --git a/docs/fud-ledger.md b/docs/fud-ledger.md index 7a2f6bea4..ac74ba01d 100644 --- a/docs/fud-ledger.md +++ b/docs/fud-ledger.md @@ -1353,7 +1353,7 @@ Evidence: spec 5.1; `docs/design/execution-layer.md` 4.1, 4.3, 9.1. Review id R3 ### P15. RPC blocks are segments, so `gasUsed` can exceed `gasLimit` "A segment holds up to 180 blocks and your RPC block is the segment. Indexers assert `gasUsed <= gasLimit`." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` b6f381e2, suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor, extends R10. Sweep (5 October 2026): confirmed in code on the `proving` branch (`igneum/exec/src/rpc.rs:355-356`: `gasLimit` is the single-block `BLOCK_EXECUTION_GAS_LIMIT` while `gasUsed` is the segment record's total). Not exercised: a segment over the limit needs about 1,400 transfers inside 180 blocks. Fix row in section 2.5. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (b6f381e2 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor, extends R10. Sweep (5 October 2026): confirmed in code on the `proving` branch (`igneum/exec/src/rpc.rs:355-356`: `gasLimit` is the single-block `BLOCK_EXECUTION_GAS_LIMIT` while `gasUsed` is the segment record's total). Not exercised: a segment over the limit needs about 1,400 transfers inside 180 blocks. Fix row in section 2.5. Answer: Correct; spec 7.1 states that a segment's total can exceed `gaslimit`. Fix: report the segment's limit as `k x B_e` in the RPC block, or document the invariant break for Blockscout (R10). @@ -1361,6 +1361,8 @@ Evidence: spec 7.1; `docs/design/execution-layer.md` 8.2. Review id R3.12. Fix (5 October 2026, night): `igneum/exec/src/rpc.rs` reports `gasLimit` as k x `BLOCK_EXECUTION_GAS_LIMIT` for a k-block segment (k = the record's mergeset length, at least 1), beside the segment's `gasUsed`, so `gasUsed <= gasLimit` holds for an indexer; the per-block limit and k sit under `igneum.blockGasLimit` and `igneum.segmentBlocks`. Unit test `rpc_block_gas_limit_is_the_segment_limit` (a three-block segment with `gasUsed` over one block's limit). Fork commit b6f381e2. +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). `igneum/exec/src/rpc.rs` merged without conflict; the `rpc_block_gas_limit_is_the_segment_limit` test's record initializer gained 0.3.11's `carried_segments` field (7d4c8b3c, test code only, no behaviour change). Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. + ### E9. The specification's year is 365 days; the code's is 365.25 "Spec 2.5: 31,536,000 DAA seconds a year, halving every 63,072,000, about 31.7098 IGN a second. `igneum.rs`: 31,557,600, 63,115,200, 31.688 IGN. Which one is the money?" @@ -1508,7 +1510,7 @@ Round 2 (5 October 2026, night): status made terminal-explicit. Blocker: no 12 G ### P17. Interfaces must show four states, and the design shows three "Included, executed, proven, finalised are four different facts. Your status call returns executed, proven, locked and a list of blocks. A wallet that shows a balance at 'included' is lying by omission." -Status: Fixed on a branch, pending merge (6 October 2026, night, ledger close round 2): fork `ledger-fixes-2` b1e98b79, suite igneum-exec 16 of 16 on the Mac (labelled a Mac run), the O-7.2 conformance run PASSED on a fast-time 3-node network (bench-log "ledger close round 2: P17"). Was: Answered with evidence for what the RPC returns today (5 October 2026, night, ledger close round 1: report only, no code change); the four-state word in the response and the conformance run (O-7.2) are round 2. Was: Open, rule written (3 October 2026, night) in `docs/design/execution-layer.md` 2.4; experiment scheduled (O-7.2). Sweep (5 October 2026): the conformance set is devnet work; not run. +Status: Fixed on a branch, pending merge (6 October 2026, night, ledger close round 2): fork `ledger-fixes-0311` fbb0082a (b1e98b79 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3), suite igneum-exec 16 of 16 on the Mac (labelled a Mac run), the O-7.2 conformance run PASSED on a fast-time 3-node network (bench-log "ledger close round 2: P17"). Was: Answered with evidence for what the RPC returns today (5 October 2026, night, ledger close round 1: report only, no code change); the four-state word in the response and the conformance run (O-7.2) are round 2. Was: Open, rule written (3 October 2026, night) in `docs/design/execution-layer.md` 2.4; experiment scheduled (O-7.2). Sweep (5 October 2026): the conformance set is devnet work; not run. Answer: Correct. Design 2.3 defines executed, proven and locked; `igneum_getTransactionStatus` carries `included_in` as a list and never as a state; the phone app (phone-app 3 and 9) shows three words. A transaction in a block not yet on a selected chain, or in a merged block waiting its turn in the sequence, is included and nothing more, and on a DAG that gap is routine. The rule now in 2.4: every RPC, wallet, explorer and app reports exactly one of included, executed, proven, finalised (the user-facing word for locked), never a stronger word than the chain's own state, and shows "finality not active" in place of finalised while `finality_active` is false (3.9). Proven says nothing about availability: full blocks are what every full node holds (F13) and a light client takes data from nodes under spec 10.1. Test: a wallet and RPC conformance set on the devnet, one transaction through each state and the three failure paths (skipped, reorged out, finality paused). @@ -1518,6 +1520,8 @@ Run (5 October 2026, night, report only, no bench-log entry because nothing ran) Round 2 (6 October 2026, night): implemented on the fork branch `ledger-fixes-2` (b1e98b79, from `ledger-fixes` bd1b676a). `igneum_getTransactionStatus` now carries one `state` word, exactly one of `included`, `executed`, `proven`, `finalised`, with `finality not active` in place of finalised while `finality_active` is false (design 2.4; `pending` for a mempool-only transaction, `unknown` when no block and no mempool holds it), and a `failure` field naming the path: `skipped` (every copy skipped by rule), `reorged out` (unwound by a selected-chain reorg, `reorgedFrom` the height; a bounded memory of 10,000 unwound hashes, cleared on re-inclusion), `finality paused` (executed, no lock covers it, the flag false). `proven` is true when the shard holding the executed copy has a paid proof record carried by a chain block (the first true value this call has ever returned; it was a constant). The `finalized` and `safe` block tags resolve through one rule (`finalized_height`): the latest locked checkpoint's chain block when the executor holds it (a certificate stays binding through a pause, spec 3.9), else the fallback spec 3.9 gives for `finality_active` false, the highest chain block at least the consensus finality depth (spec 02 section 2.1, 43,200 DAA s on mainnet, 720 blocks on the fast-time profile) below the tip, genesis while the chain is younger; never the tip, and `finalizedSource` says which. A new `igneum_getFinalityView` reports the flag, its reason, the latest lock and what the tag resolves to; the chain follower reads the node's finality report after every pass, so the RPC never touches consensus. Unit tests (3 new, 16 of 16 in the crate on the Mac under the build lock, labelled a Mac run because PC 2 was queued behind the 0.3.11 rollout). Conformance (O-7.2, `tools/p17-conformance/run.mjs`, 3 nodes at 1 block/s behind 50 ms proxies, three voters, 437.5 s, PASSED): before the first lock the tag resolved to genesis by the depth rule while `latest` was 8; the first lock at 168.9 s (index 5, chain block 129) moved the tag to 129 against tip 146; one transfer went pending, executed (147), through a routine 1-block reorg (`reorged out` for about 2 s, then executed again in 149) to finalised at 198.3 s with the tag at 153 under a tip of 173; two copies of one nonce sent to two nodes in one instant gave one `executed` and one `included` with failure `skipped` (NonceTooLow); a node cut off alone executed a transfer in its own chain block 183, and when the link healed and the heavier 2/3 chain won (11 reorg lines) the transfer reported `unknown` with failure `reorged out` from 183; 2/3 of the weight silenced paused finality at 399 s (reason `paused`), the finalised transfer flipped to `finality not active` with `lockedCovered` true, a fresh transfer executed with failure `finality paused` and the tag held at the last lock (294) against tip 339, and both reached `finalised` within 25 s of the voters signing again. Not exercised: `proven` on the network (no shard is proved on it; the unit test covers the paid-shard rule). Findings beside the fix: (1) an unwound transaction does not return to the EVM mempool (the pool has `on_chain_block` and no reorg hook), so after a reorg it must be resent; the RPC says `reorged out` and a wallet knows to resend, but the pool half is the execution engineer's (not changed here); (2) with the fast profile's presence window of 1 the flag flickers to `paused` for 0.6 s at every checkpoint determination (240 on mainnet hides it); (3) the phone app and the explorer still show three words and need the `state` field (phone-app 3 and 9; a text-and-app item for the next round). Design 8.2's RPC row updated on `ledger-pc2`. +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). `igneum/exec/src/service.rs` conflicted once: a union, the finality view, the finality depth and the 10,000-hash reorged memory beside proving v1's `paid_segments`; the p17 test record helper gained `carried_segments` (7d4c8b3c). The O-7.2 conformance run again on the rebased binaries (`tools/p17-conformance/run.mjs`, 3 nodes at 1 block/s behind 50 ms proxies, ports 30010 and up because another agent's process held 29999, network igneum-devnet-2010, under the run lock): PASSED in 409.9 s; before the first lock the tag resolved to genesis by the depth rule, the happy path, the skipped copy and the pause-and-resume as in round 2. The `reorged out` case now ends in `executed` without a resend (P23): tx3, executed alone on n2 in chain block 0xed at 281.7 s, reported `pending` with failure `reorged out` from 0xed at 334.0 s when the healed link brought the heavier chain, n2's log at the same second says `reorg: 1 unwound transactions handed back to the pool as pending, 0 refused`, and the transaction was `executed` again in chain block 0x117 at 336.4 s on n2 and 337.4 s on n0 (the driver never resends; round 2 saw it stay `unknown` for 60 s). One line for the record: during the heal n2's flag read `paused` for a pass, the fast profile's presence-window flicker of round 2's finding (2). Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. Owed, unchanged: `proven` on a network with the proving loop; the phone app and the explorer still need the `state` field. + ### E12. Selfish operators under a price shock "Outside proving pays ten times more and IGN halves in a week. Every rational operator leaves hashing for jobs. Do your internal proofs go unproven, do queues grow, does anything bring them back? Assume nobody runs your client's scheduler." @@ -1929,7 +1933,7 @@ Evidence: the first run's `/tmp/igneum-redteam-fin/n0/node.log` parse line (kept ### X19. Operational knobs and silences in the shipped node "A slow-clock node disconnects every peer on every relayed block and never says why; the handshake's `time_offset` is computed and unused; `IGNEUM_ATTACK_TS_OFFSET_MS` and `IGNEUM_POW_STRIKES` are compiled into the live binary; `timestamp_deviation_tolerance` is dead and still accepted." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` fc0cb938, suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): the app half is done (bench-log, "a node 60 s behind the clock is silently dead": the node card shows the skew with a Sync clock button, Start is blocked past 10 s, checked with `IGNEUM_APP_FAKE_SKEW=-60`); the node's one WARN line is filed in `docs/plans/node-changes.md` section 1 and not written; `faketime` is not installed on this Mac, so the node experiment was not run. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (fc0cb938 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): the app half is done (bench-log, "a node 60 s behind the clock is silently dead": the node card shows the skew with a Sync clock button, Start is blocked past 10 s, checked with `IGNEUM_APP_FAKE_SKEW=-60`); the node's one WARN line is filed in `docs/plans/node-changes.md` section 1 and not written; `faketime` is not installed on this Mac, so the node experiment was not run. Answer: Correct. `blockrelay/flow.rs:201`, `router.rs:215-224`, `flow_context.rs:819`, `peer.rs:13`; `virtual_processor/processor.rs:1663-1670` (merged in `baa8bc8a`); `pow_guard.rs:28`. The 10 s bound itself is right in shape (two constants, both directions, not overridable). Fix: one WARN from `time_offset` at handshake, the attack switches behind a feature flag, the dead field refused. Review ids R4.1.6 to R4.1.8. @@ -1937,10 +1941,12 @@ Evidence: the files above. Experiment: `igneumd` under `faketime -60s` logs one Fix (5 October 2026, night), the node half, fork commit fc0cb938. (a) `protocol/flows/src/flowcontext/clock_skew.rs`: the relay path (`charge_pow_strikes`, which sees every block result) keeps the (header timestamp minus local now) of the headers refused as `TimeTooFarIntoTheFuture` over the last minute and logs ONE WARN per minute, `clock skew: local time is N s behind the median peer block time (blocks are being refused; set the clock)`, with the count refused and the tolerance; the per-block error text is unchanged, so the app's parser keeps working (`docs/plans/node-changes.md` section 1). The mirror case (local clock ahead) is refused on the peers and not visible here; not written. (b) `IGNEUM_ATTACK_TS_OFFSET_MS` (both template-time sites) and `IGNEUM_POW_STRIKES` (the PoW guard) are read only under the new cargo feature `attack-switches` (`kaspad` forwards it to `kaspa-consensus`, `kaspa-mining`, `kaspa-p2p-flows`); a release build returns the clock's time and the default strike limit and never reads the environment. (c) `OverrideParams` refuses a file that carries `timestamp_deviation_tolerance` at load, with a message naming the field, and never writes it; `infra/fast-time/override-60x.json` on branch `ledger-fork` no longer carries it (a node from this line refuses the master copy of that file until the two merge together). Tests: `clock_skew` unit tests (a 60 s skew gives one line, nothing more inside the minute, the median after it), `release_build_ignores_the_strike_env` (compiled only without the feature), the override refusal in `params.rs`. The two-node fast-time run with one node's clock offset was not run (the offset needs an `attack-switches` build of the node, a second build); the WARN path is covered by the unit test on the monitor and by review of the hook, which runs on every relayed block result. +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). `clock_skew.rs`, the `attack-switches` feature and the `timestamp_deviation_tolerance` refusal merged without conflict. One coupling surfaced by the suites: kaspa-consensus-core's `fast_time_60x_file_is_the_devnet_at_60x` reads `infra/fast-time/override-60x.json` from the checkout beside the fork and requires every `OverrideParams` field; release-0.3.11's copy still carries `timestamp_deviation_tolerance: 132` (a node from this line refuses it at load) and fud-close's copy lacked 0.3.11's six fields (`program_class_v3_activation_daa`, `pow_genesis_dataset_log2`, `proving_v1_activation_daa`, `proving_v1_segment_blocks`, `proving_v1_unproven_daa`, `proving_v1_aggregator_share_bps`). `ledger-rebase` 2bbc12f adds the six with release-0.3.11's values and keeps the dead field out; the test passed on it (kaspa-consensus-core 108 of 108). The cut that merges fud-close with release-0.3.11 must take this copy of the file, not 0.3.11's. Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. The two-node run with one clock offset is still owed (needs an `attack-switches` build). + ### X20. Cold-sync checkpoint determination is indices times chain length "A fresh node starts `next_index` at 0 and walks the selected chain from the sink for every index. At mainnet length it never finishes its first resolution." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` 9e109c65, suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor now (4 October 2026). Sweep (5 October 2026): unchanged on `finality-fixes` (`processes/finality.rs:204` starts `next_index` at 1 and walks the chain per index). A 10^6-block simnet is 11.6 days of chain at 1 block/s and was not built. Fix row in section 2.5. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (9e109c65 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor now (4 October 2026). Sweep (5 October 2026): unchanged on `finality-fixes` (`processes/finality.rs:204` starts `next_index` at 1 and walks the chain per index). A 10^6-block simnet is 11.6 days of chain at 1 block/s and was not built. Fix row in section 2.5. Answer: Correct. `processes/finality.rs:413-421`. About 3 x 10^12 store reads at a 10^7-block chain, approximate. Fix: start from the last certified index carried in headers, walk once. Review id R4.1.10. @@ -1948,10 +1954,12 @@ Evidence: the file above. Experiment: a fresh node against a 10^6-block simnet c Fix (5 October 2026, night): `consensus/src/processes/finality.rs` `on_virtual_changed` resolves every index the sink can determine in ONE descending walk of the selected chain (`chain_blocks_at`, targets highest first), where it walked from the sink once per index. Cost per cold sync from indices x chain length store reads to one pass over the chain. Locked indices above the next one (F24) are passed over as before. On this line headers carry no certified index (certificates ride in coinbase payloads and are ingested as blocks arrive), so the walk starts at `next_index`; the ledger's "start from the last certified index carried in headers" has no field to start from and is noted here, not built. Unit test `cold_sync_determines_every_index_in_one_walk`: 150-block chain, interval 5, depth 2, 29 indices; the one walk takes at most 150 steps against a per-index sum over 10 times larger, and names the same block as `chain_block_at` for every index. The fast-time simnet timing was not run: a simnet chain is a few hundred blocks, where the two walks differ by milliseconds; the 10^6-block chain of the experiment line is still owed. Fork commit 9e109c65. +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). `consensus/src/processes/finality.rs` merged without conflict; the one-walk determination and its unit test `cold_sync_determines_every_index_in_one_walk` are unchanged on the rebased line. Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. The 10^6-block chain of the experiment line is still owed. + ### M25. The miner takes the day length from its environment, and the schedule global can tear "The template carries epoch and lead but not the day; the miner reads `IGNEUM_POW_DAY_MS` from its environment. And `install_pow_schedule` stores day, lead, epoch while `pow_schedule` loads epoch, lead, so a miner switched between schedules can wrap `pow_epoch_seed_score`." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` 3d4ec451 and fc0cb938, suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): the schedule now rides in the override file as consensus params (`a5ef8b07`, in `devnet-v4`); the mismatch run was done (5 October 2026, 01:05 UTC, `scratchpad/runs/batch3.sh` under the run lock: one `finality-fixes` node with real PoW at genesis bits 2^16 on ports 29410 to 29412, `pow_day_ms` 86,400,000 in its override file; a control miner, then a miner started with `IGNEUM_POW_DAY_MS=1440000`, 2 CPU threads, 60 s each). Confirmed: the miner still takes the day from its environment (it built its cache for day 1,243,862 while the node and the control miner were on day 20,731); control 7 blocks accepted, 0 rejected; mismatched 0 accepted, 4 rejected, each as `Reject(BlockInvalid)` on the miner and `block has invalid proof-of-work` on the node, so the miner says that it is rejected and not why. Fix row 127: the day length in the template beside the epoch and lead, and a rejection reason that names the day. The environment fallback is G12, owned by the fud-consensus branch. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (3d4ec451 and fc0cb938 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): the schedule now rides in the override file as consensus params (`a5ef8b07`, in `devnet-v4`); the mismatch run was done (5 October 2026, 01:05 UTC, `scratchpad/runs/batch3.sh` under the run lock: one `finality-fixes` node with real PoW at genesis bits 2^16 on ports 29410 to 29412, `pow_day_ms` 86,400,000 in its override file; a control miner, then a miner started with `IGNEUM_POW_DAY_MS=1440000`, 2 CPU threads, 60 s each). Confirmed: the miner still takes the day from its environment (it built its cache for day 1,243,862 while the node and the control miner were on day 20,731); control 7 blocks accepted, 0 rejected; mismatched 0 accepted, 4 rejected, each as `Reject(BlockInvalid)` on the miner and `block has invalid proof-of-work` on the node, so the miner says that it is rejected and not why. Fix row 127: the day length in the template beside the epoch and lead, and a rejection reason that names the day. The environment fallback is G12, owned by the fud-consensus branch. Answer: Correct. `igneum/miner/src/main.rs:590-596`; `consensus/core/src/igneum.rs:156-172, 198-204`. Fix: the day length in the template; one atomic struct swap. Review id R4.1.9. @@ -1959,6 +1967,8 @@ Evidence: the files above. Experiment: `igneum-miner` with `IGNEUM_POW_DAY_MS=14 Fix (5 October 2026, night). Read on `release-0.3.6` first: the template already carries `day_ms`, `day_index` and `next_day_index` beside the epoch fields (`RpcPowEpochInfo`, G12 merged into 0.3.6), the miner installs the node's three values from every template and never reads `IGNEUM_POW_DAY_MS` (only the node does, on devnet and simnet). Two gaps remained and are closed: `next_pair` in `igneum/miner/src/main.rs` took the devnet constant `DAY_MS` for the day-change lead instead of the live `pow_day_ms()` (wrong on any non-default day length, fork commit 3d4ec451); and the node's rejection named nothing (`PoW rejected ... (daa, nonce)`, `RuleError::InvalidPoW` bare). Now `RuleError::InvalidPoW { header_day, engine_day, day_ms }` reads `block has invalid proof-of-work (header day D from its timestamp at M ms per day, engine day E; a miner on another day length or epoch seed computes another dataset)` and the log line adds the epoch seed (fork commit fc0cb938). Mismatch re-run (the batch3 recipe: one `ledger-fixes` node with real PoW at genesis bits 0x1f010000 on ports 29410 to 29412, `pow_day_ms` 86,400,000, a control miner then a miner started with `IGNEUM_POW_DAY_MS=1440000`, 2 CPU threads, 60 s each, under the run lock): the miner started with `IGNEUM_POW_DAY_MS=1440000` installed the node's schedule from the first template (`node PoW schedule: 60 DAA per epoch, lead 10, day 86400000 ms`), built its cache for day 20,731 like the node and the control, and was accepted: control 65 found, 0 rejected; mismatched 65 found, 0 rejected; node 130 `PoW accepted`, 0 `PoW rejected` (19:07 to 19:09 UTC). The environment is ignored, so the rejection path was not exercised live; its text is the unit-level evidence (`RuleError` message and the log line). Bench-log, "5 October 2026 (night), ledger close round 1". +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). In `next_pair` the live day length (`pow_day_ms()`, never the devnet constant) stays, with 89dfcb95's carry of the class and the era seed into the next pair (`..*seeds` for the day change, `info.next_class()` and the same era for the epoch change); the `RuleError::InvalidPoW { header_day, engine_day, day_ms }` text merged without conflict. Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. + ### M26. The interval fault guard freezes its baseline and loops "On a trip you skip the STATUS print, so the baseline it would have updated stays frozen, and you roll the counters back to it. Any healthy rate over ten times a slow first interval trips again every interval, forever, with no STATUS line and no `faults=` for the app to read." @@ -1984,7 +1994,7 @@ Evidence: the files above. Experiment: a fast-time simnet node patched to flip ` ### M28. The kernel text is bound only to its own directory "The worker compiles whatever `kernel_bound.cu` it finds in a directory whose `seeds.txt` matches; the self-test checks the GPU against a `vectors.h` from the same directory. Nothing commits the text to what the generator would emit for the seed. 'Source check PASS' is a prefix equality." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` 3d4ec451 (miner) and branch `ledger-fork` (workers), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor (4 October 2026). The writer is the local miner and the directory is the user's own, so no privilege boundary is crossed. Sweep (5 October 2026): no kernel hash in `program.json` on any branch (`git grep -i 'kernel_hash|program_hash'` on `miner-reliability` finds nothing); the tampered-pack test needs a GPU worker. Fix row in section 2.5. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (miner; 3d4ec451 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3) and branch `ledger-fork` (workers), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor (4 October 2026). The writer is the local miner and the directory is the user's own, so no privilege boundary is crossed. Sweep (5 October 2026): no kernel hash in `program.json` on any branch (`git grep -i 'kernel_hash|program_hash'` on `miner-reliability` finds nothing); the tampered-pack test needs a GPU worker. Fix row in section 2.5. Answer: Correct. `packfile.h:~262-283, 306-345`; `worker.cpp:414-416, 596-620`; `emu/test.sh:57-66`. The CPU re-check (`main.rs:1250-1256`) stops a wrong program from earning, not from running. Fix: a hash of the emitted kernel in `program.json`, derived from the seed by the miner and checked by both workers; one sentence in the docs that the chain commits to the seed, not the text. Review id R4.2.4. @@ -1994,6 +2004,8 @@ Fix (5 October 2026, night). The miner stamps `program.json` with `kernel_sha256 Closer's note (5 October 2026, 23:10 UTC): the worker half of this fix (`proto-cuda/nvrtc/packfile.h`, `proto-opencl/host.c`, on `fud-close`) refuses any pack whose `program.json` carries no `kernel_sha256`, and only the miner commit on the fork branch `ledger-fixes` (3d4ec451) stamps it. The two halves ship in the same cut or the worker half is held back; the 0.3.11 cut closed at 23bc2b2 without either, so `fud-close` heads the next cut with `ledger-fixes` rebased onto the 0.3.11 fork tip 89dfcb95 (two conflicting files, `igneum/miner/src/main.rs` and `protocol/flows/src/ibd/proof.rs`, rebase owed). +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). The rebase moved the stamp to where 0.3.11 writes every pack: `stamp_kernel_hashes` runs inside `write_pack_checked` (after the kernel files and `seeds.txt`, before the pack is read back and checked against the seeds), and `verify_kernel_hashes` reads the stamp back after that check, so the prepare path, the rebuild after a refused pack and `export-pack` all leave `kernel_sha256` in `program.json`; `export-pack` prints `stamped .../program.json with kernel_sha256 over 6 files`. End to end on the rebased miner: `igneum-miner export-pack grpc://127.0.0.1:30010 ` against node 0 of the round-3 fast-time network (epoch 0, day 1,243,919, class v2, generator 2, attempt 0, `checked`) wrote 6 stamped files; `proto-cuda/nvrtc/emu/test.sh ` on the Mac (build slot, 59 s), with the test now keeping a miner-written stamp instead of re-stamping (ledger-rebase 67990d0): pack A `check PASS` with the miner's own stamp (2 `source check PASS` lines, self-test PASS, 96 of 96 vector lanes), pack T (one line appended to `kernel_bound.cu` after the stamp) refused with `kernel_bound.cu does not hash to the value the miner derived from the seed` and no `source check PASS` line, the serve round PASS (64 + 64 + 32 found on A, prepared B, 32 found on B, job 5 refused), 15 sampled hashes equal to `igneum-pow hash-bound`. So the fud-close worker half accepts a pack from the 0.3.11 miner and refuses the tampered one. Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. Owed, unchanged: the tampered pack against the real worker on PC 2's RTX 5090; the PC 2 run of these suites. Coupling for the closer: the cut that carries fud-close needs `igneum-pow` at release-0.3.11 and the fast-time file of 2bbc12f (X19). + ### X21. A wrong program burns power with a green rate "The CPU re-check counts mismatches and does nothing: no threshold, no stop. The app reads `hash`, `now`, `template_age` and `synced` from STATUS and nothing else, so `mismatched=` and `WORKER FAULT` never reach the card." @@ -2007,7 +2019,7 @@ Evidence: the files above. Experiment: one constant edited in `kernel_bound.cu` ### X22. Worker restart paths, minor "Two miners truncate the same `packs\devnet` while workers read it; every restart begins on the stale first pack; the restart loop has no cap; the 60 s stall guard wraps the self-heal build; a node can crash the miner through an `expect`; a worker without prepare support loops on export during IBD." -Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes` 3d4ec451 (miner) and branch `ledger-fork` (app), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is bd1b676a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): two of the six fixed on `miner-reliability` (`501363e0`: a dead worker's stdin no longer spins the fill loop; `945153ab`: a silent worker still runs the guards and STATUS); the shared `packs\devnet` truncation, the stale first pack, the `expect` crash and the IBD export loop remain; restart timing needs the PCs. +Status: Fixed on a branch, pending merge (5 October 2026, night): fork branch `ledger-fixes-0311` fbb0082a (miner; 3d4ec451 rebased onto the 0.3.11 fork tip 89dfcb95 in round 3) and branch `ledger-fork` (app), suites PC 2 jobs `build-20261005-200049` (kaspa-consensus 95 passed, 0 failed, 3 ignored) and `build-20261005-200606` (kaspa-consensus-core 101/0, kaspa-mining 52/0, igneum-exec 13/0, igneum-miner 17/0, kaspa-p2p-flows 32 passed 1 failed: the new clock-skew test's own arithmetic, corrected in bd1b676a and 33/0 on the Mac), both on 815c7d64; the tip is fbb0082a. Was: Open, minor (4 October 2026). Sweep (5 October 2026): two of the six fixed on `miner-reliability` (`501363e0`: a dead worker's stdin no longer spins the fill loop; `945153ab`: a silent worker still runs the guards and STATUS); the shared `packs\devnet` truncation, the stale first pack, the `expect` crash and the IBD export loop remain; restart timing needs the PCs. Answer: Correct on each: `engine.rs:~2047-2055` and `emit.rs:1156-1163`; `main.rs:1206-1228`; `worker.cpp:684-703`; `main.rs:~581, 893`; `main.rs:1373-1380` with `engine.rs:~1405-1411` (the 14:20 export during IBD, bench-log). Each costs a restart, none loses the run. Review ids R4.2.5 to R4.2.10. @@ -2015,6 +2027,8 @@ Evidence: the files above. Experiment: time from worker restart to first accepte Fix (5 October 2026, night), the four remaining paths. (1) The shared `packs\devnet` truncation: the app exports one pack directory per card, `packs\devnet-` (`pack_dir_name`, `export_pack`, `build_worker_from_source`, `miner_args` in `app/igneum-app/src/engine.rs`), so an export for one card never truncates what another card's worker is reading; app test `pack_directories_are_per_card` (passed on the Mac, 1 of 1). (2) The stale first pack: a restarted worker is spawned with `--pack` pointing at the pack of the CURRENT seeds under `--prepare-packs` when the miner wrote one (`worker_args_with_pack`, `pack_dir_for`), not at the launcher's first pack, which cost a build of the old program and then a foreground self-heal build of the current one; unit test `restart_worker_args_take_the_current_pack`. (3) The `expect` crash: `template()` skips a template whose block does not convert and the legacy seed walk returns `None` on any RPC error or missing verbose data (the three call paths skip the template, the two one-shot commands exit with a message); no `expect` on the node's answers remains in the mining loops (the ones left are on the user's own address and on process start). (4) The IBD export loop: a worker without prepare support no longer makes the miner exit 42 on a seed change while the template is not synced (the change is printed once, `last_seeds` keeps the worker's pair, so the first change after the sync completes still exits 42 once); the app waits 60 s before restarting a miner that exited 42 while the node is not synced. Fork commit 3d4ec451 (miner), branch `ledger-fork` (app). The restart timing on both PCs is still owed (hardware). +Round 3 (6 October 2026, night): the fork branches `ledger-fixes` (bd1b676a) and `ledger-fixes-2` (b1e98b79) merged onto the 0.3.11 fork tip 89dfcb95 as `ledger-fixes-0311` (merge 99ea7d97, fallout 7d4c8b3c, P23 fbb0082a, the tip), built on the Mac against `igneum-pow` as release-0.3.11 ships it (the fork resolves `../../../../igneum-pow` from the checkout it sits under; `ledger-rebase` carries that crate at 42be745 and the fork worktree moved under it). `igneum/miner/src/main.rs` conflicted in seven hunks; 89dfcb95's structure was kept (`EpochSeeds` with `class` and `era`, `seeds_from_info`, `write_pack_checked`) and path (3), the `expect` crash, was reconciled by reading both sides: 89dfcb95's `seeds_for` still panics on `getBlockDagInfo` (`expect("dag info")`) and its `template_seeds` returns a value; the ledger side returns `None` on an RPC error or a block without verbose data, and the three mining loops and the two one-shot commands already skip the template or exit with a message on `None` (callers outside the conflict). The path that cannot panic on a node answer is the `Option` one, so `template_seeds` returns `Option` and wraps `seeds_from_info`, `seeds_for` fills 89dfcb95's `class` (from `program_class_for_epoch`) and `era` (the genesis stand-in) in both returns, and `mine_cpu_legacy` skips the template on `None` (merge 99ea7d97, the choice in its message). Paths (1), (2) and (4) merged without conflict; the restart test's seed gained class v2 and a zero era (7d4c8b3c, test code). Suites on the rebased fork, the Mac run (`cargo test --release -j 4` under the build lock, labelled a Mac run: PC 2 was queued behind the Counter ASIC 2.0 chain and no go came inside 30 minutes; the PC 2 slot for the same job still stands with the coordinator): kaspa-consensus 99 passed, 1 failed, 4 ignored (the failure is 0.3.11's own `igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds`, the era-0 stand-in of `pruning_proof/igneum_pow.rs:114` against `EpochSeeds::v2`'s zero era, both from 89dfcb95, neither file touched on the ledger branches; owned by the Counter ASIC 2.0 coordinator), kaspa-consensus-core 108 passed, 0 failed, 2 ignored (db_compat 7 of 7), kaspa-mining 52 of 52, kaspa-p2p-flows 36 of 36, kaspa-pow 14 of 14, kaspad 2 of 2, igneum-exec 23 of 23, igneum-miner 20 of 20. The restart timing on both PCs is still owed (hardware). + ### E16. The 20% pool is burned on the live chain, and the text says it pays provers "Your coinbase sends the 20% to an OP_RETURN tagged `igneum-proving-pool-v0`. Your own comment says provably burned. Your cap test counts it as supply. Your litepaper says, present tense, that it pays a standing prover population." @@ -2134,7 +2148,7 @@ Evidence: the commits above. Experiment: `curl https://igneum.network/api/live` ### P23. An unwound transaction leaves the node's view until its sender resends it "Your pool learns about chain blocks (`on_chain_block`) and about nothing else. A selected-chain reorg unwinds a transaction out of the executed set and the pool never gets it back. The RPC can say `reorged out` all it likes; the transaction is gone unless the wallet resends, and most wallets do not." -Status: Open, found in round 2 (6 October 2026, night, the P17 conformance run on `ledger-fixes-2`); fix named, owner the execution engineer; round 3 (`ledger-rebase`) carries it with the fork rebase. Found by: the ledger-pc2 agent's O-7.2 conformance driver (`tools/p17-conformance/run.mjs`, the "reorged out" path), recorded as finding (1) in the P17 round-2 paragraph. +Status: Fixed on a branch, pending merge (6 October 2026, night, ledger close round 3): fork `ledger-fixes-0311` fbb0082a (the P23 commit, on the merge of `ledger-fixes` and `ledger-fixes-2` onto the 0.3.11 fork tip 89dfcb95); `EvmPool::on_chain_removed` (igneum/exec/src/pool.rs) and `ExecService::requeue_unwound` (service.rs) with `ExecState::unwound` collected by `truncate_to`; unit tests `pool::tests::a_reorg_hands_the_unwound_transactions_back_to_the_pool_in_nonce_order` and `rpc::p17_tests::a_reorg_collects_the_unwound_transactions_in_chain_order_for_the_pool`, igneum-exec 23 of 23 on the Mac (labelled a Mac run); the O-7.2 conformance run on the rebased binaries PASSED (409.9 s) with the `reorged out` case ending in `executed` 2.4 s later without a resend (n2's log: `reorg: 1 unwound transactions handed back to the pool as pending, 0 refused`; bench-log "ledger close round 3"). Was: Open, found in round 2 (6 October 2026, night, the P17 conformance run on `ledger-fixes-2`); fix named, owner the execution engineer; round 3 (`ledger-rebase`) carries it with the fork rebase. Found by: the ledger-pc2 agent's O-7.2 conformance driver (`tools/p17-conformance/run.mjs`, the "reorged out" path), recorded as finding (1) in the P17 round-2 paragraph. Answer: Correct. `igneum/exec/src/pool.rs` has `on_chain_block` and no reorg hook, so a transaction unwound by a selected-chain reorg is neither re-queued nor re-executed; the new `state` word reports `reorged out` with `reorgedFrom`, which tells a wallet to resend and tells nobody else. Fix: on every `virtualChainChanged` removal the executor hands the unwound transactions back to the pool as pending (nonce order kept, the same validity checks as a fresh submission, the 10,000-hash memory of P17 cleared on re-inclusion); a unit test that unwinds a block and sees its transactions re-queued; the conformance driver's `reorged out` case then ends in `executed` again without a resend.