diff --git a/docs/analysis/class-v6/coexist-rows.md b/docs/analysis/class-v6/coexist-rows.md new file mode 100644 index 000000000..9569c0c82 --- /dev/null +++ b/docs/analysis/class-v6/coexist-rows.md @@ -0,0 +1,86 @@ +# Class v6 coexistence rows: the 5.5 GiB miner beside the shard prover on an RTX 3060 12 GB and an RTX 4060 8 GB + +Measured 8 October 2026, 16:10 to 16:38 BST, on two Vast.ai instances rented for the rows and destroyed after them (RTX 3060: instance 54866832, Norway, driver 610.57.04, power limit 170 W, 0.276 h, USD 0.02; RTX 4060: instance 54866835, Mexico, driver 570.211.01, power limit 115 W, 0.545 h, USD 0.07). Record for the Igneum 2.0 pin D1 ("5.5 GiB coexistence rows") and the proving statement's memory condition. Every row below is the RESULT line as the pod wrote it to its run log (scratchpad v6coexist/fb-v6c-3060/run.log, fb-v6c-4060/run.log and run2.log; the 1 Hz samples beside them). Times in the logs are UTC. + +## What ran + +- Miner: the ds55 kit's own worker (`igneum-ca3-ds55-kit-20261008.zip`, sha 2d7f55e8..., worker sha d43be4625b78baf7) on `packs/ds55`, the 5.5 GiB dataset (1,476,395,008 words), `--bench --batch-log2 24 --block-warps 1 --device 0`; 100 batches alone, 400 batches as the beside run. +- Prover: `igneum-prove-host-0317` (sha 71bc2438856bb141) on the fixed shard `fees-v1-shards2.json` shard 0 (4,717,439 cycles, fixture sha 20a108f159c61ff9), `--mode compressed --shard 0`, `SP1_GPU_ELEMENT_THRESHOLD=67108864` (2^26), against the served floor tarballs: sm_86 (`igneum-floor-sm86.tgz`, patched server sha 224200d317cea579) on the 3060, sm_89 (`igneum-floor-sm89.tgz`, patched server sha 882bd34f7f69dc97) on the 4060. +- Sampler: `nvidia-smi --query-gpu=memory.used,power.draw,utilization.gpu` once a second per phase. Watts are the mean of power.draw over the busy samples from 8 s in; the 4060 host reports power.draw as N/A, so the 4060 has no watts. +- Register windows: the class v5 kit's worker (`packs-ca3-v5-20261008T085619Z.zip`, worker sha d84b1b6cb09cebdc) on `hl-reg64c` (the full chain) and `hl-reg64` (arithmetic only), 100 batches each. + +## RTX 3060 12 GB: the rows verbatim + +``` +RESULT start 2026-10-08T15:10:03Z card=NVIDIAGeForceRTX3060 total_mib=12288 driver=610.57.04 power_limit_w=170.00 +RESULT bins worker=d43be4625b78baf7 host=71bc2438856bb141 server=224200d317cea579 fixture=20a108f159c61ff9 +RESULT idle mem_mib=1 power_w=21.32 +RESULT cmd miner_alone: /root/coex/kit/bin/linux/igneum-worker-cuda --bench --pack /root/coex/kit/packs/ds55 --batches 100 --batch-log2 24 --block-warps 1 --device 0 +RESULT miner_alone rc=0 wall_s=67 peak_mib=6129 check=PASS fingerprint=23ced07a4d28b465 mhs=26.824 self-test PASS +RESULT cmd proof_alone: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=67108864 timeout 900 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode compressed --shard 0 --out /root/coex/proof-alone.json +RESULT proof_alone rc=0 wall_s=31 peak_mib=7525 prove_s=13.2 verified=1 err="" +RESULT proof_alone_line RESULT compressed shard 0: prove 13.2 s, proof 1272897 bytes, verify 0.110 s, VERIFIED; statement 0x6adcc7fab21512b58cfa3778756718fd37aea6cccb311e12d2ca33b5f4bf10c0 proof sha256 0x57e133da05ea5f6ecbcbd731b1b26c9bed2f10c5a1aa1bd04a5a5e3dab1e +RESULT cmd miner_beside_comp26: /root/coex/kit/bin/linux/igneum-worker-cuda --bench --pack /root/coex/kit/packs/ds55 --batches 400 --batch-log2 24 --block-warps 1 --device 0 +RESULT cmd proof_beside_comp26: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=67108864 timeout 600 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode compressed --shard 0 --out /root/coex/proof-beside-comp26.json (started 1s+10s after the miner, miner resident mem_mib=6129) +RESULT proof_beside_comp26 mode=compressed thr=67108864 rc=1 wall_s=34 proof_window=1791472334..1791472368 miner_start=1791472323 prove_s= verified=0 miner_alive_after=yes err="thread 'tokio-rt-worker' (1790) panicked at slop/crates/alloc/src/raw_buffer.rs:271:9:" +RESULT miner_beside_comp26 rc=0 wall_s=256 peak_mib=11893 check=PASS fingerprint=23ced07a4d28b465 mhs=26.512 self-test PASS +RESULT beside_fallback compressed 2^26 beside the miner did not verify; core 2^25 beside the miner next +RESULT cmd proof_beside_core25: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=33554432 timeout 600 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode core --shard 0 --out /root/coex/proof-beside-core25.json (started 3s+10s after the miner, miner resident mem_mib=6129) +RESULT proof_beside_core25 mode=core thr=33554432 rc=1 wall_s=18 proof_window=1791472598..1791472616 miner_start=1791472585 prove_s= verified=0 miner_alive_after=yes err="Error: unknown mode core" +RESULT miner_beside_core25 rc=0 wall_s=254 peak_mib=11013 check=PASS fingerprint=23ced07a4d28b465 mhs=26.775 self-test PASS +RESULT beside_failed core 2^25 beside the miner did not verify either +RESULT idle_after mem_mib=1 +RESULT window_hl-reg64c rc=0 wall_s=130 peak_mib=1521 regs=87 blocks_per_sm=16 check=PASS fingerprint=4e7cc25967eba280 mhs=13.467 self-test PASS +RESULT window_hl-reg64 rc=0 wall_s=128 peak_mib=1521 regs=104 blocks_per_sm=16 check=PASS fingerprint=70e786af1a457653 mhs=13.476 self-test PASS +``` + +Watts from the samples (busy mean of power.draw from 8 s in): miner alone 117.4 W; proof alone 122.2 W over the 9 busy seconds; miner with the failed compressed attempt beside it 118.6 W; hl-reg64c 120.8 W; hl-reg64 119.3 W. The card touched its 170 W limit on none of them. + +## RTX 4060 8 GB: the rows verbatim + +The first pass (run.log) ran the proof rows against the stock SDK server, because the served sm_89 tarball carries the stock `sp1-gpu-server` in `home/.sp1/bin` (sha c2642ad1c42e85d8, the 24 GB gate at builder.rs:38) and the patched one only in `bin/` (882bd34f7f69dc97); those two rows are kept here as the record of the fault. The patched server was copied over `home/.sp1/bin` at 16:13 BST and the proof rows re-ran (run2.log). + +``` +RESULT start 2026-10-08T15:10:44Z card=NVIDIAGeForceRTX4060 total_mib=8188 driver=570.211.01 power_limit_w=115.00 +RESULT bins worker=d43be4625b78baf7 host=71bc2438856bb141 server=882bd34f7f69dc97 fixture=20a108f159c61ff9 +RESULT idle mem_mib=2 power_w=[N/A] +RESULT cmd miner_alone: /root/coex/kit/bin/linux/igneum-worker-cuda --bench --pack /root/coex/kit/packs/ds55 --batches 100 --batch-log2 24 --block-warps 1 --device 0 +RESULT miner_alone rc=0 wall_s=91 peak_mib=6116 check=PASS fingerprint=23ced07a4d28b465 mhs=18.837 self-test PASS +RESULT proof_alone rc=1 wall_s=1 peak_mib=2 prove_s= verified=0 err="thread 'tokio-rt-worker' (1470) panicked at sp1-gpu/crates/prover_components/src/builder.rs:38:9:" (stock server: "Unsupported GPU memory: 12, must be at least 24GB") +RESULT proof_beside_comp26 mode=compressed thr=67108864 rc=1 wall_s=1 proof_window=1791472371..1791472372 miner_start=1791472359 prove_s= verified=0 miner_alive_after=yes err="thread 'tokio-rt-worker' (1811) panicked at sp1-gpu/crates/prover_components/src/builder.rs:38:9:" (stock server, as above) +RESULT miner_beside_comp26 rc=0 wall_s=359 peak_mib=6128 check=PASS fingerprint=23ced07a4d28b465 mhs=18.837 self-test PASS +RESULT cmd proof_beside_core25: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=33554432 timeout 600 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode core --shard 0 --out /root/coex/proof-beside-core25.json (started 1s+10s after the miner, miner resident mem_mib=6116) +RESULT proof_beside_core25 mode=core thr=33554432 rc=1 wall_s=5 proof_window=1791472735..1791472740 miner_start=1791472724 prove_s= verified=0 miner_alive_after=yes err="thread 'tokio-rt-worker' (4670) panicked at slop/crates/tensor/src/inner.rs:51:51:" +RESULT miner_beside_core25 rc=0 wall_s=358 peak_mib=7459 check=PASS fingerprint=23ced07a4d28b465 mhs=18.834 self-test PASS +RESULT idle_after mem_mib=2 +RESULT window_hl-reg64c rc=0 wall_s=179 peak_mib=1508 regs=87 blocks_per_sm=20 check=PASS fingerprint=4e7cc25967eba280 mhs=9.508 self-test PASS +RESULT window_hl-reg64 rc=0 wall_s=178 peak_mib=1508 regs=104 blocks_per_sm=16 check=PASS fingerprint=70e786af1a457653 mhs=9.574 self-test PASS +``` + +The rerun on the patched server (run2.log): + +``` +RESULT start 2026-10-08T15:31:00Z card=NVIDIAGeForceRTX4060 total_mib=8188 driver=570.211.01 power_limit_w=115.00 +RESULT bins worker=d43be4625b78baf7 host=71bc2438856bb141 server=882bd34f7f69dc97 fixture=20a108f159c61ff9 +RESULT cmd proof_alone: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=67108864 timeout 900 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode compressed --shard 0 --out /root/coex/proof-alone-rerun.json +RESULT proof_alone_rerun rc=0 wall_s=15 peak_mib=7532 prove_s=8.2 verified=1 err="" +RESULT proof_alone_rerun_line RESULT compressed shard 0: prove 8.2 s, proof 1272897 bytes, verify 0.036 s, VERIFIED; statement 0x6adcc7fab21512b58cfa3778756718fd37aea6cccb311e12d2ca33b5f4bf10c0 proof sha256 0x7b887af9426039e61345f11d2c9faf10d4b4d0d16e4850d10ee08c5fa7002 +RESULT cmd proof_beside_comp26: env HOME=/opt/igneum-floor/home SP1_PROVER=cuda RUST_LOG=off SP1_GPU_FLOOR_LOG=1 SP1_GPU_ELEMENT_THRESHOLD=67108864 timeout 600 /opt/igneum-floor/bin-0317/igneum-prove-host /root/coex/fees-v1-shards2.json --mode compressed --shard 0 --out /root/coex/proof-beside-comp26-rerun.json (started 3s+10s after the miner, miner resident mem_mib=6116) +RESULT proof_beside_comp26 mode=compressed thr=67108864 rc=1 wall_s=5 proof_window=1791473509..1791473514 miner_start=1791473495 prove_s= verified=0 miner_alive_after=yes err="thread 'tokio-rt-worker' (10627) panicked at slop/crates/tensor/src/inner.rs:51:51:" +RESULT miner_beside_comp26 rc=0 wall_s=359 peak_mib=7811 check=PASS fingerprint=23ced07a4d28b465 mhs=18.833 self-test PASS +RESULT beside_fallback compressed 2^26 beside the miner did not verify (the core 2^25 beside row is in run.log) +RESULT idle_after mem_mib=2 +``` + +## The table + +| Card | Miner alone (ds55) | Proof alone (compressed 2^26) | Together | Register windows (v5 kit worker) | +|---|---|---|---|---| +| RTX 3060 12 GB | 26.82 MH/s at 117.4 W, 6,129 MiB resident, fingerprint 23ced07a4d28b465, PASS | 13.2 s, VERIFIED, peak 7,525 MiB, 122 W | 6,129 + 7,525 = 13,654 MiB against 12,288: TIME-SHARING NEEDED. Live attempt: the card filled to 11,893 MiB and the prover died in a device allocation (raw_buffer.rs:271) after 34 s; the miner held 26.51 MH/s through it (1.2 percent under alone). Proof with the miner paused = the proof-alone row | hl-reg64c 13.47 MH/s, 87 regs, 16 of 24 blocks per SM, fingerprint 4e7cc25967eba280 MATCH, 120.8 W; hl-reg64 13.48 MH/s, 104 regs, 16 of 24, 70e786af1a457653 MATCH, 119.3 W | +| RTX 4060 8 GB | 18.84 MH/s, 6,116 MiB resident, fingerprint 23ced07a4d28b465, PASS (no watts: host sensor N/A) | 8.2 s, VERIFIED, peak 7,532 MiB | 6,116 + 7,532 = 13,648 MiB against 8,188: TIME-SHARING NEEDED. Live attempt: the server died in a tensor allocation (inner.rs:51) at 7,811 MiB after 5 s; the miner held 18.83 MH/s | hl-reg64c 9.51 MH/s, 87 regs, 20 of 24 blocks per SM, fingerprint MATCH; hl-reg64 9.57 MH/s, 104 regs, 16 of 24, MATCH | + +Not measured and why: a core-only proof beside the miner (igneum-prove-host-0317 has no `--mode core`: "Error: unknown mode core"; its modes are native, execute, shard, compressed, block, all); watts on the 4060 (the host's power sensor reads N/A). + +## Reconciliation with the served row + +The served sentence (litepaper, "Proving", from `docs/analysis/prover-tiers-real-cards.md`, 6 October 2026) says an RTX 3060 (12 GB) "mines at 23.78 MH/s and proves the v1 shard beside its miner at an 8.9 GB peak in 37.5 s". Today's row on the same card tier reads a 7.5 GiB compressed peak that kills the prover beside a 6.1 GiB miner. The two are not in conflict; they measured different things. The 6 October row is the matrix's `miner-comp-26-v1` point (`tools/fleet/box-matrix.sh` section 7): the patched server at threshold 2^26 in compressed mode, driven by the matrix host (the segment host build at `/opt/igneum-segal/.../igneum-prove-host`, which also carries `--mode core`; the matrix's core rows come from it), beside `igneum-miner mine` on the 1 GiB class v3 pack, whose resident set was 1.4 GB: 1.4 + 7.5 = 8.9 GB, inside 12 GB, proof in 37.5 s with the miner running. Today's row is igneum-prove-host-0317 in compressed mode at the same threshold 2^26 (the same 7.5 GiB own footprint, 7,525 to 7,532 MiB peak alone), beside the ds55 miner on the 5.5 GiB dataset of the genesis floor, whose resident set is 6.1 GB: 6.1 + 7.5 = 13.6 GB, outside 12 GB and 8 GB alike, so the prover's allocation fails while the miner keeps mining. What changed between the rows is the miner's dataset (1 GiB then, 5.5 GiB now), not the prover. The rule that follows: at the 5.5 GiB floor a compressed shard proof beside a running miner needs a 16 GB card (13.6 GB together; the 16 GB tier's own peak is 18 GB on the stock sizes and 7.8 GB patched, so 16 GB holds both with about 2 GB spare); 8 GB and 12 GB cards time-share, proving with the miner paused (13.2 s on the 3060, 8.2 s on the 4060) and mining otherwise. The 6 October beside rows stand only for the 1 GiB dataset; the 6 October core-only beside rows (5.6 GB own on the 3060, 27.2 s) stand only for core mode on the segment host, which the 0317 host does not expose, and are not a coexistence claim at the floor. The served sentence is read as a 1 GiB-dataset row until the site lane rewrites it against this record. diff --git a/docs/analysis/class-v6/connected-state.md b/docs/analysis/class-v6/connected-state.md new file mode 100644 index 000000000..110d463c5 --- /dev/null +++ b/docs/analysis/class-v6/connected-state.md @@ -0,0 +1,124 @@ +# Class v6: the connected-state variant (8 October 2026) + +The experiment of the external review the founder accepted (the 15:4x BST rules): the remaining chip edge (about 2.0x to 2.2x node-for-node, 2.2x to 2.6x a node ahead) survives because a specialist can separate storage, arithmetic and memory scheduling. This lane reorganised the class v5 work, same dataset, same read width (4 bytes), about the same operation count, so that live state feeds each load address, the memory result feeds mixed arithmetic and cross-lane exchange, and that updates the live state for the next address, with a 64-register window per lane that stays necessary across the whole dependent chain. Research class only, behind `--class cssx` in `igneum-pow` (`igneum-pow/src/connected.rs`, branch `class-v6-connected` on the box mirror); never a chain class. + +Every number below is measured unless marked modelled or owed. Times are UK (BST). + +## 1. The structure + +| Item | Class v5 (`mx8+sh256x27`, the control) | Connected state (`cs64s27x16`) | +|---|---|---| +| Registers per lane | 8 | 64 (the window) | +| Per iteration | 64 base instructions with 16 loads, then a 256-instruction block run 27 times | 16 steps: a load, then a 27-instruction block run 16 times | +| Load address | a base register, `x & MASK` (the era stride and site window under an era) | a window register, the same address rule | +| Memory result | xor into the load's destination | xor into `r[m_j]`; block instruction 0 reads it | +| Next address | whatever register the next load reads | written by the block's last instruction (add, sub, xor or shfl) from a fresh spine | +| Result | fold of 8 registers | fold of all 64 (`lo` over the first 32 at 7 i, `hi` over the second 32 at 9 i; the v5 fold at a window of 8) | +| Loads per hash | 128 | 128 | +| ALU instructions per hash | 55,680 (55,296 shadow + 384 base) | 55,296 (0.7 percent fewer) | +| Instruction text per iteration | 320 | 448 | +| Negative controls kept out | | no long program (1,024), no select tree, no wide read (W = 16), no scratchpad | + +The draw (deterministic from the seed words, attempt k re-seeded as every class): per step `a_j` then `m_j != a_j` (and the era window draws); per block instruction the op from the ten non-load families at the v5 weights, the source from the last four spine entries (the memory result first), the destination uniform over the window, the two immediates, the rotation, the selector bit and the shuffle mask. Four rules the first census pass forced, each a construction rather than a filter: + +1. The cover: the first 64 injecting destinations walk a drawn permutation of the window, so every register takes an injecting write (rule (b)); a uniform draw left one register without one in about 70 percent of candidates. +2. The fresh spine: only destinations of add, sub, xor, mad and shfl enter the spine, so every address is fresh by dataflow (rule (a')); with a lossy spine every seed exhausted 256 attempts. +3. Lossy ops feed the next injection: or, mul and mulhi write the register the next injecting instruction of the block writes, so their value enters the chain and no register accumulates a lossy op across the 16 passes (a 16-pass or saturated a register the block never re-injected, a 16-pass mul cleared its low bits: rule (c) refused every candidate). +4. The two closing instructions of a block come from add, sub, xor and shfl (the census lane's rule for a load source's writer): no product on the address writer (a 16-pass mad on the address register read bit z 57.6 at one site). + +The acceptance rule is the sub-version 3 rule over the window: (b), (a') (the fixpoint over the iteration's execution order), (c) over 64 units (constant bits per register, lane-constant sites, saturation at 1 percent of the window's final values, saturated sources, output bias, distinct addresses, the value-level index-bit read judged inside the site's era window), then (c'') at 0.98 and (c''') at 0.995 over 2^20 evaluations per site. (a) holds by construction. + +## 2. Liveness (seed `igneum-v6c/0`, attempt 0, program id 9ad55de91485542b) + +The tool (`igneum-pow liveness --class cs64s27x16 --seed `) walks the unrolled trace of one hash (128 loads, 55,296 ALU instructions). `live` is the backward set at an address: registers whose value just before the load feeds this or any later address. `dep` is the forward set: registers at the previous address whose values feed this address. + +| Measure | Value | +|---|---| +| live before each address | 63 of 64 at every address until the last iteration's tail; iteration 7: 63 62 60 60 60 57 57 54 53 51 45 36 25 20 9 1 | +| registers read by the result | 64 of 64 (the fold) | +| dep per step (the same every iteration, the text repeats) | 1 9 13 14 8 15 7 8 12 14 14 13 10 9 14 9; mean 11.2 of 64 | +| registers touched per block (read or written) | min 16, mean 20.4, max 24 of 64 | +| reads per register per hash | min 384, mean 1,724, max 3,208 | +| writes per register per hash | min 128, mean 866, max 1,664 | +| op mix of the 432 block instructions | add 82, mul 62, xor 51, shfl 51, sub 46, mulhi 39, rotl 35, mad 31, rotr 20, or 15 | + +Meaning: the whole window is necessary over the hash (no register can be dropped or parked for long: the longest gap between writes to one register is under one iteration), and every value is read by a later address, so there is no side calculation a specialist can move to a separate engine. The dependent chain per step is narrow: about 11 of the 64 registers at one address feed the next address through 432 operations, and a block touches about 20. That is the shape a specialist will exploit: a two-level file, about 20 registers hot per step and 44 warm, the hot set moving along the text; the k lane prices exactly that (section 5). The program listing is `liveness.txt` and `program.json` of the pack. + +## 3. Census (the census lane's sub-version 3 harness, `tools/attack/v6-census/v6census.sh`, (c''') 0.995 on, on a rented 5090 host with 40 threads, 16:01 to 16:08 BST) + +| Run | Seeds | Accepted | Exhausted | Rejections per candidate | Mean attempt | Max attempt | Window-bit refusals | Over 6 sigma (reported) | +|---|---|---|---|---|---|---|---|---| +| cs64 no era | 256 | 256 | 0 | 0.283 | 0.39 | 5 | off | 146 of 256 (max z 128) | +| control `mx8+sh256x27` no era (census lane, build-3) | 256 | 256 | 0 | 0.668 | 2.01 | 18 | off | 143 of 256 (max z 97) | +| cs64 eras 0 to 7, window-bit refusal on | 8 x 32 | 256 | 0 | 0.635 | 1.74 | 8 | 306 | 0 (max z 5.9) | +| control eras 0 to 7, refusal on (census lane, build-4) | 8 x 32 | 256 | 0 | 0.830 | 4.87 | 22 | 218 | 0 (max z 5.9) | +| cs64 eras 0 to 7, refusal off | 8 x 32 | 256 | 0 | 0.304 | 0.44 | 2 | off | 94 of 256 (max z 71.5) | + +The no-era rejections are all rule (c) (constant bits, saturation or bias in the 64-unit test); the control's are mostly (a') and (a), which this class satisfies by construction. The window-bit refusals sit on eras 0, 1, 4, 5 and 6 (55 to 64 each) and nearly vanish on eras 2 and 3 (0 and 1): the product-bit class (a product's low bits reaching an address bit through the era stride), the same class the control carries and the layer-1 index fold removes; this class does not change it either way. + +F8 form (`igneum-pow cs-uniform`, 16 seeds x 2^20 nonces, no era): the top 0.1 percent item share reads 0.9987 to 1.0016 of a uniform control of the same size (the control class 0.9993 to 1.0016); the worst per-site distinct ratio 0.9941 (seed 9, site 9; the sequential-nonce sample of the F8 tool, the acceptance's own 2^20 sample passed 0.995 on every accepted program). + +Meaning: the class censuses at least as well as v5 on every instrument of the harness and takes fewer attempts; it inherits v5's product-bit bias and the fix is the same fold. The acceptance costs about 3.7 s per candidate on one core (the (c'') pass dominates, 7 G lane-ops), against v5's 2.8 s. + +## 4. GPU cost + +Instrument: the class v5 nvcc harness (`proto-newpow/class-v5/bench.cu` on `box/ds55-v5`, the v5 design page's 4090 rows), compiled per pack with `-Xptxas -v`, 250 batches of 2^24, nvidia-smi at 1 Hz, both packs on the same card minutes apart; vectors 3 of 3 PASS and the dataset self-test PASS on every row. The cs64 pack is over the class v4 memory-hard dataset (no leaves); v5-genesis carries its 93 leaves. Stock means the card's own power limit and no clock lock. + +| Card | Pack | MH/s | Mean W | Microjoules per hash | Registers per thread | Spills | Resident blocks per SM (1 warp per block) | Fingerprint of 2^24 at base 0 | +|---|---|---|---|---|---|---|---|---| +| RTX 5090 (Vast 54862507, driver 580.159.03, 575 W cap), stock | cs64s27x16 | 64.93 | 574.8 | 8.853 | 80 | 0 | 24 | ad0cec2a42c84aff | +| RTX 5090, the same card | v5-genesis | 65.30 | 574.8 | 8.803 | 48 | 0 | 24 | ae74193ddad19e19 | +| RTX 4090 (RunPod 386yytbh4bkfnz, driver 580.159.04, 450 W cap), stock | cs64s27x16 | 62.44 | 268.8 | 4.305 | 87 | 0 | 20 | ad0cec2a42c84aff | +| RTX 4090, the same card | v5-genesis | 62.44 | 271.3 | 4.345 | 32 | 0 | 24 | ae74193ddad19e19 | +| RTX 5090 on PC 1 at the 1,300 MHz lock | both | OWED: PC 1 booked to 17:40 BST; the bound pack and the kit are at build-1:/srv/builds/igneum-wt-connected/cs-kit (sha c9aff54aaf10d79e) and the hash lane publishes the job when PC 1 frees | | | | | | | + +The kit worker (the brief's instrument, `igneum-worker-cuda --bench --batch-log2 24 --batches 250`, the class v5 kit's NVRTC worker of 7 October loading the pack's `kernel_bound.cu`; check PASS on both packs): + +| Card | Pack | MH/s | Mean W | Microjoules per hash | Registers per thread | Fingerprint | +|---|---|---|---|---|---|---| +| RTX 5090 (the Vast card above), stock | cs64s27x16 (bound pack) | 62.88 | 574.2 | 9.131 | 80 | ad0cec2a42c84aff | +| RTX 5090, the same card | v5-genesis | 62.96 | 571.4 | 9.076 | 48 | ae74193ddad19e19 | +| RTX 4090 (the RunPod card above), stock | cs64s27x16 (bound pack) | 62.41 | 269.4 | 4.317 | 87 | ad0cec2a42c84aff | +| RTX 4090, the same card | v5-genesis | 62.39 | 271.9 | 4.358 | 32 | ae74193ddad19e19 | + +Both instruments agree with each other on each card (the harness and the worker within 3 percent of rate) and agree on the comparison: the window moves energy per hash by +0.6 percent on the 5090 (harness and worker alike) and by -0.9 percent on the 4090 (harness and worker alike), inside the run-to-run noise of a power reading. The 4090 is not at its cap (269 W of 450) and both packs read the same rate to three figures, so there the hash is bound by the memory chain, not the ALU or the register file; the 5090 is at its 575 W cap and the window costs under 1 percent of rate. (The fingerprints are the same on both cards and both instruments: ad0cec2a42c84aff for cs64, ae74193ddad19e19 for v5-genesis.) + +Meaning: at stock the window costs the 5090 0.6 percent of energy per hash against a 10 percent budget; the compiled allocation is 80 registers per thread with no spill, so the window is in registers, not local memory, and the occupancy under this harness is the same as v5's. The harness reads 65 MH/s where the NVRTC worker reads about twice that on a 5090 (one warp per block, 24 resident blocks); the ratio between two packs on the same harness is the measurement, the absolute rate is not. The lock row is where the energy comparison binds (the 5090 at the lock reads 2.33 microjoules per hash on v5); the stock rows say the card is bound by its power cap in both cases and the window moves the rate by under 1 percent. + +## 5. The chip side + +The k lane (floor lane 2) priced the re-optimised core on the drawn program at 17:2x BST (synthesis only, a model and never a lower bound; its placed row is due 21:00 as an amendment). The core: 8 lanes, a 64 x 32-bit window per lane in clock-gated flops (a macro file reads within 5 percent), a 512-entry imem holding the 448-instruction text, one in-order op per cycle per lane (the spine's ILP is met by lane count, which is free), every class unit, the load's fold on the address path; gate-level random-input VCD, every pin annotated; 253,059 cells. + +| Row (the k lane's) | pJ per lane-op, ASAP7 | N5 (the card's node) | N3 | N2 | k at the 1,300 lock, N5 / N3 / N2 | k at stock, N5 / N3 | +|---|---|---|---|---|---|---| +| cs64s27x16, the re-optimised core (gated window, 512 imem) | 6.3 | 4.4 | 3.2 | 2.3 | 0.71 / 0.51 / 0.37 | 0.39 / 0.28 | +| the same window on the class v4 draw, 256 imem | 6.2 | 4.3 | 3.1 | 2.2 | 0.70 / 0.50 / 0.36 | 0.38 / 0.27 | +| the adversary's 32-register base, gated (the genesis window) | 4.5 | 3.2 | 2.3 | 1.6 | 0.51 / 0.37 / 0.26 | 0.28 / 0.20 | +| the GPU-shaped 64-register core, ungated (shadow-k.md, the earlier default) | 9.7 | 6.8 | 4.9 | 3.5 | 1.09 / 0.78 / 0.56 | 0.60 / 0.43 | + +What the adversary's re-optimisation did to each part of the structure: the gated file charges only the register written, so the whole-window liveness costs it nothing beyond the write it would make anyway and the hot-20 banking of section 2 is not even needed; the 16-pass loop and the 448 text cost the shared imem 0.1 pJ per lane-op; the narrow per-step chain sets the lane count, which is free. The window itself is worth +1.2 pJ per lane-op at N5 over the genesis window (+0.14 of k at the lock), the same knob as the design document's 64-register row; the connected organisation around it adds about 0.1 pJ. The placed ungated core came in 64 percent over its synthesis, so the placed figure is expected near 8 to 10 pJ at ASAP7 (k node-for-node near 0.9 to 1.1, approximate); both rows move together and the ratio below holds. + +## 6. The score and the verdict + +E_GPU over E_adversary, absolute convention, GDDR7 board (E_mem 0.466 microjoules per hash), E_chip = E_mem + 55,296 x e_chip, E_GPU = the 5090 at the lock (2.33 microjoules per hash on class v5) x 1.006 for the window (the stock rows of section 4; the lock row is owed): + +| Core | Node-for-node (N5) | A node ahead (N3) | Two nodes (N2) | +|---|---|---|---| +| cs64s27x16, re-optimised | 2.344 / (0.466 + 0.243) = 3.3x | 2.344 / (0.466 + 0.177) = 3.6x | 2.344 / (0.466 + 0.127) = 4.0x | +| the genesis window (the control) | 2.33 / (0.466 + 0.177) = 3.6x | 2.33 / (0.466 + 0.127) = 3.9x | 2.33 / (0.466 + 0.088) = 4.2x | +| the window's effect on the chip's edge | 1.10x | 1.08x | 1.05x | + +On the placed figures (both rows 64 percent higher) the pair reads about 2.2x and 2.4x node-for-node and the ratio stays near 1.1x. The gate was 1.25x node-for-node for the 1.5x one-node-ahead ambition; the row reads 1.10x node-for-node and 1.08x a node ahead. + +**Verdict: KILL as a class.** The hypothesis was that a connected organisation of the same work, with the window independently necessary across the whole chain, would deny a specialist its separation of storage, arithmetic and scheduling. It does not: the liveness rows show the window is necessary (63 of 64 at every address) and the chip answers with a clock-gated file that pays per write, not per live register, so necessity costs it nothing; the only term that reaches the chip is the window's own width (+0.14 k at the lock), which the design document already holds as its one robust core knob, and the connected structure adds about 0.1 pJ around it. The GPU side passes its budget with room (+0.6 percent of energy per hash at stock on the 5090, -0.9 percent on the 4090, 80 to 87 registers per thread with no spill), and the census passes every instrument with fewer attempts than v5; neither moves the score. The founder's accepted review stands in a sharper form than before: a specialist's edge against this family is a per-op energy ratio on a known op mix, and reorganising the dependency graph of the same ops does not change what an op costs on either side. + +What is kept: the generator variant and the liveness tool (research class, behind the flag) for the v7 tests below; the measured fact that a 64-register window costs a card under 1 percent at stock, which fixes the design document's modelled "about 0 rate" row; the kit worker and nvcc harness agreement on two cards. What is withdrawn: the "connected state" line as a resistance mechanism. + +## 7. What a v7 variant would test next + +- The index fold on the address (the layer-1 row) in this class, which removes the window-bit refusals on eras 0, 1, 4, 5 and 6 for the control and this class alike. +- A wider per-step chain: a spine of depth 8 to 16 so `dep` rises from about 11 toward the window, at the cost of ILP on the card (measure the rate first; the chain per step is what a two-level file exploits). +- The window at 32 and 16 (`cs32s27x16`, `cs16s27x16`) for the k curve, and the block at 16 x 27 (`cs64s16x27`, text 272) if the imem matters to the re-optimised core. +- The op-mix re-weight of the census lane at this structure (the two closing instructions already take the injecting table). +- The PC 1 lock row (informational now: the verdict does not turn on it; it lands as an amendment if PC 1 runs it). +- A knob that reaches a gated file: not more live state but more WRITES per op the chip cannot skip (every op writing two registers, or a window write per load), priced against the card's own write cost first; the k lane's placed row at 21:00 says whether even that moves k. diff --git a/docs/analysis/class-v6/logs/connected/bench-4090.log b/docs/analysis/class-v6/logs/connected/bench-4090.log new file mode 100644 index 000000000..83058c530 --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/bench-4090.log @@ -0,0 +1,46 @@ +RESULT start 2026-10-08T15:14:09Z host=dbd4e396219f arch=sm_89 card=NVIDIA GeForce RTX 4090, 580.159.04, 450.00 W +RESULT pack packs/cs64-v6c0 +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 87 registers, used 0 barriers, 376 bytes cmem[0], 8 bytes cmem[2] +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 40 registers, used 0 barriers, 372 bytes cmem[0] +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 43 registers, used 0 barriers, 364 bytes cmem[0] +RESULT bench packs/cs64-v6c0 class-v5 bench pack "igneum-v6c/0" class control generator 2 (test harness: no pool, no network, no wallet) +RESULT bench packs/cs64-v6c0 GPU: NVIDIA GeForce RTX 4090 (128 SMs, cc 8.9, 24081 MiB), CUDA driver 13.0 runtime 12.8 +RESULT bench packs/cs64-v6c0 hash kernel: 87 registers/thread, 20 resident blocks/SM at 1 warp/block +RESULT bench packs/cs64-v6c0 device memory at start: 395 MiB used of 24081 MiB +RESULT bench packs/cs64-v6c0 cache fill (GPU): 1.84 ms first, 1.82 ms second +RESULT bench packs/cs64-v6c0 cache head and last 16 words against the pack: PASS +RESULT bench packs/cs64-v6c0 dataset build (GPU): 30.57 ms first, 30.54 ms second (16777216 items, 1024 MiB) +RESULT bench packs/cs64-v6c0 device memory after the build: 1675 MiB used +RESULT bench packs/cs64-v6c0 dataset self-test: head PASS, last PASS, samples 64 of 64 +RESULT bench packs/cs64-v6c0 vector warps against the pack: 3 of 3 PASS +RESULT bench packs/cs64-v6c0 fingerprint of 2^24 outputs at base 0: ad0cec2a42c84aff (lane 0 c2b2466c00d3f12b) +RESULT bench packs/cs64-v6c0 hash rate: 62.436 MH/s over 250 batches of 2^24 (GPU event time 67177.7 ms) +RESULT bench packs/cs64-v6c0 RESULT pack=igneum-v6c/0 class=control build_ms=30.54 rate_mhs=62.436 vectors=3/3 +RESULT smi packs/cs64-v6c0 samples 64 mean_power_w 268.8 mean_sm_mhz 2811 mean_mem_mhz 10251 +RESULT pack v5-genesis +RESULT ptxas v5-genesis cc1plus: fatal error: ../../bench.cu: No such file or directory +RESULT ptxas v5-genesis 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas v5-genesis ptxas info : Used 32 registers, used 0 barriers, 376 bytes cmem[0] +RESULT ptxas v5-genesis 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas v5-genesis ptxas info : Used 40 registers, used 0 barriers, 384 bytes cmem[0] +RESULT ptxas v5-genesis 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas v5-genesis ptxas info : Used 43 registers, used 0 barriers, 364 bytes cmem[0] +RESULT bench v5-genesis class-v5 bench pack "igneum-genesis" class v5 generator 5 (test harness: no pool, no network, no wallet) +RESULT bench v5-genesis GPU: NVIDIA GeForce RTX 4090 (128 SMs, cc 8.9, 24081 MiB), CUDA driver 13.0 runtime 12.8 +RESULT bench v5-genesis hash kernel: 32 registers/thread, 24 resident blocks/SM at 1 warp/block +RESULT bench v5-genesis device memory at start: 395 MiB used of 24081 MiB +RESULT bench v5-genesis cache fill (GPU): 1.83 ms first, 1.81 ms second +RESULT bench v5-genesis cache head and last 16 words against the pack: PASS +RESULT bench v5-genesis leaves: 93 x 64 B from leaves.bin (5952 bytes), FNV-1a 64 850ad094a937a5c5 against the pack's 850ad094a937a5c5: PASS; state root 1c583d352bb9c75a06dadb8d82d42836ebe8afa82d0b413be87bf921741f1526, chain block af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3 (159357) +RESULT bench v5-genesis dataset build (GPU): 30.80 ms first, 30.75 ms second (16777216 items, 1024 MiB) +RESULT bench v5-genesis device memory after the build: 1677 MiB used +RESULT bench v5-genesis dataset self-test: head PASS, last PASS, samples 64 of 64 +RESULT bench v5-genesis vector warps against the pack: 3 of 3 PASS +RESULT bench v5-genesis fingerprint of 2^24 outputs at base 0: ae74193ddad19e19 (lane 0 61b73fdc4b19aa6e) +RESULT bench v5-genesis hash rate: 62.437 MH/s over 250 batches of 2^24 (GPU event time 67176.1 ms) +RESULT bench v5-genesis RESULT pack=igneum-genesis class=v5 build_ms=30.75 rate_mhs=62.437 vectors=3/3 +RESULT smi v5-genesis samples 64 mean_power_w 271.3 mean_sm_mhz 2805 mean_mem_mhz 10251 +RESULT end 2026-10-08T15:16:34Z diff --git a/docs/analysis/class-v6/logs/connected/bench-5090c.log b/docs/analysis/class-v6/logs/connected/bench-5090c.log new file mode 100644 index 000000000..364c48cb4 --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/bench-5090c.log @@ -0,0 +1,40 @@ +RESULT start 2026-10-08T15:09:57Z host=f271665b754f arch=sm_120 card=NVIDIA GeForce RTX 5090, 580.159.03, 575.00 W +RESULT pack packs/cs64-v6c0 +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 80 registers, used 0 barriers +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 38 registers, used 0 barriers +RESULT ptxas packs/cs64-v6c0 0 bytes stack frame, 0 bytes spill stores, 0 bytes spill loads +RESULT ptxas packs/cs64-v6c0 ptxas info : Used 41 registers, used 0 barriers +RESULT bench packs/cs64-v6c0 class-v5 bench pack "igneum-v6c/0" class control generator 2 (test harness: no pool, no network, no wallet) +RESULT bench packs/cs64-v6c0 GPU: NVIDIA GeForce RTX 5090 (170 SMs, cc 12.0, 32109 MiB), CUDA driver 13.0 runtime 12.8 +RESULT bench packs/cs64-v6c0 hash kernel: 80 registers/thread, 24 resident blocks/SM at 1 warp/block +RESULT bench packs/cs64-v6c0 device memory at start: 6188 MiB used of 32109 MiB +RESULT bench packs/cs64-v6c0 cache fill (GPU): 0.65 ms first, 0.65 ms second +RESULT bench packs/cs64-v6c0 cache head and last 16 words against the pack: PASS +RESULT bench packs/cs64-v6c0 dataset build (GPU): 29.75 ms first, 27.68 ms second (16777216 items, 1024 MiB) +RESULT bench packs/cs64-v6c0 device memory after the build: 7468 MiB used +RESULT bench packs/cs64-v6c0 dataset self-test: head PASS, last PASS, samples 64 of 64 +RESULT bench packs/cs64-v6c0 vector warps against the pack: 3 of 3 PASS +RESULT bench packs/cs64-v6c0 fingerprint of 2^24 outputs at base 0: ad0cec2a42c84aff (lane 0 c2b2466c00d3f12b) +RESULT bench packs/cs64-v6c0 hash rate: 64.929 MH/s over 250 batches of 2^24 (GPU event time 64598.6 ms) +RESULT bench packs/cs64-v6c0 RESULT pack=igneum-v6c/0 class=control build_ms=27.68 rate_mhs=64.929 vectors=3/3 +RESULT smi packs/cs64-v6c0 samples 128 mean_power_w 574.8 mean_sm_mhz 2778 mean_mem_mhz 13801 +RESULT pack v5-genesis +RESULT ptxas v5-genesis cc1plus: fatal error: ../../bench.cu: No such file or directory +RESULT bench v5-genesis class-v5 bench pack "igneum-genesis" class v5 generator 5 (test harness: no pool, no network, no wallet) +RESULT bench v5-genesis GPU: NVIDIA GeForce RTX 5090 (170 SMs, cc 12.0, 32109 MiB), CUDA driver 13.0 runtime 12.8 +RESULT bench v5-genesis hash kernel: 48 registers/thread, 24 resident blocks/SM at 1 warp/block +RESULT bench v5-genesis device memory at start: 6188 MiB used of 32109 MiB +RESULT bench v5-genesis cache fill (GPU): 0.65 ms first, 0.65 ms second +RESULT bench v5-genesis cache head and last 16 words against the pack: PASS +RESULT bench v5-genesis leaves: 93 x 64 B from leaves.bin (5952 bytes), FNV-1a 64 850ad094a937a5c5 against the pack's 850ad094a937a5c5: PASS; state root 1c583d352bb9c75a06dadb8d82d42836ebe8afa82d0b413be87bf921741f1526, chain block af89be5ddbadb6f6b4aee28ac8f249713be5d4c12621e3cea7f83ceada3c66b3 (159357) +RESULT bench v5-genesis dataset build (GPU): 27.57 ms first, 27.53 ms second (16777216 items, 1024 MiB) +RESULT bench v5-genesis device memory after the build: 7470 MiB used +RESULT bench v5-genesis dataset self-test: head PASS, last PASS, samples 64 of 64 +RESULT bench v5-genesis vector warps against the pack: 3 of 3 PASS +RESULT bench v5-genesis fingerprint of 2^24 outputs at base 0: ae74193ddad19e19 (lane 0 61b73fdc4b19aa6e) +RESULT bench v5-genesis hash rate: 65.303 MH/s over 250 batches of 2^24 (GPU event time 64228.4 ms) +RESULT bench v5-genesis RESULT pack=igneum-genesis class=v5 build_ms=27.53 rate_mhs=65.303 vectors=3/3 +RESULT smi v5-genesis samples 126 mean_power_w 574.8 mean_sm_mhz 2788 mean_mem_mhz 13801 +RESULT end 2026-10-08T15:12:13Z diff --git a/docs/analysis/class-v6/logs/connected/cs64-era-bt.tsv b/docs/analysis/class-v6/logs/connected/cs64-era-bt.tsv new file mode 100644 index 000000000..5220b4c2a --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/cs64-era-bt.tsv @@ -0,0 +1,259 @@ +# cs64-era-bt class cs64s27x16 eras [0,1,2,3,4,5,6,7] seeds 32 era-widths 4 weights base bittest 1 bin 54b905920b91becc start 2026-10-08T15:01:08Z host f271665b754f threads 40 +cand era seed candidates accepted attempt bit_z bit_site bit_bit reasons +cs64-era-bt 0 16 9 1 8 3.2 7 8 c,=7;c=1; +cs64-era-bt 0 21 2 1 1 3.2 14 21 c=1; +cs64-era-bt 0 20 1 1 0 3.8 10 1 +cs64-era-bt 0 30 2 1 1 3.0 3 18 c,=1; +cs64-era-bt 0 19 3 1 2 3.6 1 19 c,=2; +cs64-era-bt 1 1 2 1 1 2.8 6 20 c=1; +cs64-era-bt 0 12 5 1 4 3.5 10 25 c,=3;c=1; +cs64-era-bt 0 18 4 1 3 3.2 11 13 c,=3; +cs64-era-bt 0 17 7 1 6 4.2 4 19 c,=4;c=2; +cs64-era-bt 0 6 1 1 0 5.1 3 19 +cs64-era-bt 0 28 5 1 4 5.9 12 19 c,=2;c=2; +cs64-era-bt 0 0 9 1 8 4.2 9 19 c,=5;c=3; +cs64-era-bt 0 5 2 1 1 3.9 5 1 c=1; +cs64-era-bt 0 29 1 1 0 4.2 8 22 +cs64-era-bt 1 0 9 1 8 3.2 14 26 c,=5;c=3; +cs64-era-bt 0 11 2 1 1 3.1 5 0 c,=1; +cs64-era-bt 0 7 4 1 3 2.9 11 20 c,=3; +cs64-era-bt 0 15 1 1 0 2.8 14 16 +cs64-era-bt 1 7 4 1 3 3.3 12 8 c,=3; +cs64-era-bt 0 25 2 1 1 3.3 2 14 c=1; +cs64-era-bt 0 13 5 1 4 3.2 13 11 c,=4; +cs64-era-bt 0 4 1 1 0 3.2 12 20 +cs64-era-bt 0 31 3 1 2 3.0 1 6 c,=1;c=1; +cs64-era-bt 0 22 1 1 0 3.0 1 19 +cs64-era-bt 0 26 3 1 2 3.4 3 13 c,=2; +cs64-era-bt 0 14 6 1 5 3.5 1 19 c,=4;c=1; +cs64-era-bt 0 10 4 1 3 3.0 0 18 c=2;c,=1; +cs64-era-bt 1 2 1 1 0 2.9 15 20 +cs64-era-bt 1 4 3 1 2 3.2 7 22 c,=2; +cs64-era-bt 0 27 2 1 1 3.9 15 19 c,=1; +cs64-era-bt 0 9 1 1 0 3.1 1 17 +cs64-era-bt 1 3 1 1 0 3.3 15 7 +cs64-era-bt 0 3 1 1 0 2.7 12 10 +cs64-era-bt 1 5 2 1 1 3.6 4 16 c=1; +cs64-era-bt 0 23 3 1 2 3.7 3 20 c,=2; +cs64-era-bt 0 8 7 1 6 5.3 8 19 c,=5;c=1; +cs64-era-bt 1 6 9 1 8 2.8 14 19 c,=6;c=2; +cs64-era-bt 0 1 6 1 5 3.3 0 8 c,=3;c=2; +cs64-era-bt 0 2 1 1 0 2.8 9 21 +cs64-era-bt 0 24 6 1 5 3.0 6 9 c,=5; +cs64-era-bt 1 8 7 1 6 5.3 8 6 c,=5;c=1; +cs64-era-bt 1 14 6 1 5 2.9 1 6 c,=4;c=1; +cs64-era-bt 1 15 1 1 0 3.2 6 1 +cs64-era-bt 1 22 1 1 0 3.3 4 25 +cs64-era-bt 1 11 2 1 1 3.1 3 6 c,=1; +cs64-era-bt 1 9 1 1 0 4.0 11 0 +cs64-era-bt 1 19 3 1 2 3.2 5 13 c,=2; +cs64-era-bt 1 10 4 1 3 4.0 10 17 c=2;c,=1; +cs64-era-bt 1 30 2 1 1 3.1 15 15 c,=1; +cs64-era-bt 1 13 5 1 4 3.3 7 3 c,=4; +cs64-era-bt 2 1 2 1 1 3.3 0 4 c=1; +cs64-era-bt 1 25 2 1 1 3.3 14 25 c,=1; +cs64-era-bt 1 12 5 1 4 3.1 2 9 c,=3;c=1; +cs64-era-bt 2 15 1 1 0 3.0 13 7 +cs64-era-bt 1 28 3 1 2 3.6 4 18 c,=1;c=1; +cs64-era-bt 1 16 9 1 8 3.3 13 18 c,=7;c=1; +cs64-era-bt 1 17 7 1 6 2.9 7 25 c,=4;c=2; +cs64-era-bt 1 20 1 1 0 3.0 15 9 +cs64-era-bt 1 21 2 1 1 2.6 11 19 c=1; +cs64-era-bt 2 5 2 1 1 3.0 10 12 c=1; +cs64-era-bt 2 13 2 1 1 3.1 2 26 c=1; +cs64-era-bt 1 27 2 1 1 5.8 15 6 c,=1; +cs64-era-bt 2 12 2 1 1 2.8 13 23 c=1; +cs64-era-bt 1 18 4 1 3 3.4 0 5 c,=3; +cs64-era-bt 1 29 1 1 0 3.9 10 6 +cs64-era-bt 1 31 4 1 3 3.5 1 23 c=2;c,=1; +cs64-era-bt 2 11 2 1 1 3.0 12 15 c=1; +cs64-era-bt 1 23 1 1 0 4.8 12 6 +cs64-era-bt 1 26 3 1 2 3.5 5 8 c,=2; +cs64-era-bt 2 3 1 1 0 2.6 11 1 +cs64-era-bt 1 24 6 1 5 2.9 0 19 c,=5; +cs64-era-bt 2 16 1 1 0 3.0 7 12 +cs64-era-bt 2 4 1 1 0 2.7 0 10 +cs64-era-bt 2 8 2 1 1 3.5 13 24 c=1; +cs64-era-bt 2 0 2 1 1 3.1 5 25 c=1; +cs64-era-bt 2 9 1 1 0 2.6 6 1 +cs64-era-bt 2 6 1 1 0 3.1 0 1 +cs64-era-bt 2 10 1 1 0 3.1 2 20 +cs64-era-bt 2 14 1 1 0 3.2 3 15 +cs64-era-bt 2 2 1 1 0 3.3 0 0 +cs64-era-bt 2 7 2 1 1 3.2 9 24 c=1; +cs64-era-bt 2 17 1 1 0 2.7 10 2 +cs64-era-bt 2 18 1 1 0 3.2 3 11 +cs64-era-bt 2 26 2 1 1 4.6 1 26 c=1; +cs64-era-bt 2 21 2 1 1 2.8 15 4 c=1; +cs64-era-bt 2 29 1 1 0 3.5 11 7 +cs64-era-bt 2 23 1 1 0 3.7 15 20 +cs64-era-bt 2 24 1 1 0 3.5 3 11 +cs64-era-bt 2 19 3 1 2 3.1 8 20 c=2; +cs64-era-bt 2 20 1 1 0 2.8 10 3 +cs64-era-bt 3 5 2 1 1 3.1 3 20 c=1; +cs64-era-bt 3 4 1 1 0 3.7 9 10 +cs64-era-bt 2 31 1 1 0 3.3 15 18 +cs64-era-bt 2 22 1 1 0 2.9 5 1 +cs64-era-bt 3 11 2 1 1 3.2 6 13 c,=1; +cs64-era-bt 3 1 2 1 1 3.3 9 13 c=1; +cs64-era-bt 2 30 1 1 0 3.1 8 20 +cs64-era-bt 3 16 1 1 0 3.2 13 0 +cs64-era-bt 3 2 1 1 0 3.1 3 25 +cs64-era-bt 3 8 2 1 1 3.3 0 14 c=1; +cs64-era-bt 3 0 2 1 1 3.2 0 7 c=1; +cs64-era-bt 2 28 2 1 1 3.0 2 23 c=1; +cs64-era-bt 2 27 1 1 0 3.3 9 18 +cs64-era-bt 3 14 1 1 0 2.8 2 18 +cs64-era-bt 2 25 2 1 1 3.1 2 7 c=1; +cs64-era-bt 3 20 1 1 0 3.4 2 2 +cs64-era-bt 3 6 1 1 0 3.1 2 9 +cs64-era-bt 3 18 1 1 0 2.8 9 2 +cs64-era-bt 3 22 1 1 0 3.0 11 11 +cs64-era-bt 3 9 1 1 0 3.4 3 9 +cs64-era-bt 3 3 1 1 0 3.3 2 14 +cs64-era-bt 3 10 1 1 0 3.8 5 4 +cs64-era-bt 3 15 1 1 0 2.7 7 3 +cs64-era-bt 3 13 2 1 1 3.1 0 25 c=1; +cs64-era-bt 3 12 2 1 1 3.4 14 17 c=1; +cs64-era-bt 3 7 2 1 1 3.2 8 17 c=1; +cs64-era-bt 3 19 3 1 2 3.3 13 17 c=2; +cs64-era-bt 3 26 2 1 1 3.3 5 16 c=1; +cs64-era-bt 3 21 2 1 1 3.0 0 15 c=1; +cs64-era-bt 3 29 1 1 0 3.0 5 7 +cs64-era-bt 3 31 1 1 0 3.4 15 8 +cs64-era-bt 3 17 1 1 0 3.0 2 12 +cs64-era-bt 3 23 1 1 0 2.9 3 25 +cs64-era-bt 3 25 2 1 1 3.2 13 6 c=1; +cs64-era-bt 4 1 2 1 1 3.3 12 22 c=1; +cs64-era-bt 3 24 1 1 0 3.5 13 5 +cs64-era-bt 3 27 1 1 0 2.9 15 13 +cs64-era-bt 3 28 2 1 1 4.4 15 0 c=1; +cs64-era-bt 4 12 5 1 4 3.6 7 23 c,=3;c=1; +cs64-era-bt 3 30 1 1 0 2.8 8 20 +cs64-era-bt 4 10 4 1 3 3.1 11 16 c=2;c,=1; +cs64-era-bt 4 6 1 1 0 5.0 3 10 +cs64-era-bt 4 2 1 1 0 2.9 10 22 +cs64-era-bt 4 0 9 1 8 3.7 9 10 c,=5;c=3; +cs64-era-bt 4 4 3 1 2 2.8 4 24 c,=2; +cs64-era-bt 4 5 2 1 1 3.3 15 27 c=1; +cs64-era-bt 4 11 2 1 1 3.7 8 16 c,=1; +cs64-era-bt 4 3 1 1 0 2.7 10 11 +cs64-era-bt 4 7 4 1 3 4.4 11 10 c,=3; +cs64-era-bt 4 19 3 1 2 3.4 2 0 c,=2; +cs64-era-bt 4 13 5 1 4 3.1 15 14 c,=3;c=1; +cs64-era-bt 4 8 7 1 6 5.1 12 10 c,=5;c=1; +cs64-era-bt 4 16 9 1 8 2.7 5 8 c,=7;c=1; +cs64-era-bt 4 15 1 1 0 3.2 14 25 +cs64-era-bt 4 9 1 1 0 3.7 6 8 +cs64-era-bt 4 24 6 1 5 3.7 7 11 c,=5; +cs64-era-bt 4 14 6 1 5 3.3 3 20 c,=4;c=1; +cs64-era-bt 4 21 2 1 1 2.8 8 10 c=1; +cs64-era-bt 4 31 4 1 3 3.4 3 20 c=2;c,=1; +cs64-era-bt 4 29 1 1 0 3.7 10 9 +cs64-era-bt 4 17 7 1 6 3.6 8 12 c,=4;c=2; +cs64-era-bt 4 28 3 1 2 3.3 8 6 c,=1;c=1; +cs64-era-bt 4 25 2 1 1 3.3 0 22 c=1; +cs64-era-bt 4 18 4 1 3 3.4 3 16 c,=3; +cs64-era-bt 4 20 1 1 0 3.2 9 11 +cs64-era-bt 5 7 4 1 3 4.0 11 22 c,=3; +cs64-era-bt 4 22 1 1 0 3.2 8 24 +cs64-era-bt 4 30 2 1 1 2.7 7 14 c,=1; +cs64-era-bt 5 1 2 1 1 3.2 9 2 c=1; +cs64-era-bt 4 26 3 1 2 3.6 12 24 c,=2; +cs64-era-bt 4 23 1 1 0 5.8 12 10 +cs64-era-bt 4 27 3 1 2 4.0 15 21 c,=2; +cs64-era-bt 5 3 1 1 0 3.1 5 8 +cs64-era-bt 5 2 1 1 0 3.0 2 6 +cs64-era-bt 5 5 2 1 1 3.5 14 23 c=1; +cs64-era-bt 5 6 1 1 0 4.6 3 22 +cs64-era-bt 5 8 7 1 6 5.2 8 22 c,=5;c=1; +cs64-era-bt 5 0 9 1 8 2.7 8 23 c,=5;c=3; +cs64-era-bt 5 4 3 1 2 3.0 12 20 c,=2; +cs64-era-bt 5 9 1 1 0 4.1 8 7 +cs64-era-bt 5 12 5 1 4 3.2 12 13 c,=3;c=1; +cs64-era-bt 5 14 6 1 5 3.7 1 22 c,=4;c=1; +cs64-era-bt 5 11 2 1 1 3.1 4 11 c,=1; +cs64-era-bt 5 10 4 1 3 3.2 6 5 c=2;c,=1; +cs64-era-bt 5 15 1 1 0 3.6 13 2 +cs64-era-bt 5 16 9 1 8 2.8 15 2 c,=7;c=1; +cs64-era-bt 5 20 1 1 0 3.3 2 16 +cs64-era-bt 5 21 2 1 1 3.1 10 16 c=1; +cs64-era-bt 5 17 7 1 6 3.0 5 19 c,=4;c=2; +cs64-era-bt 5 19 3 1 2 2.7 14 24 c,=2; +cs64-era-bt 5 13 5 1 4 3.2 10 13 c,=4; +cs64-era-bt 5 29 1 1 0 3.6 12 26 +cs64-era-bt 5 22 1 1 0 3.4 0 16 +cs64-era-bt 5 25 2 1 1 3.0 5 1 c=1; +cs64-era-bt 5 18 4 1 3 2.8 11 4 c,=3; +cs64-era-bt 5 30 2 1 1 3.0 15 21 c,=1; +cs64-era-bt 5 24 6 1 5 2.9 14 1 c,=5; +cs64-era-bt 5 23 1 1 0 5.7 12 22 +cs64-era-bt 5 27 2 1 1 5.0 15 22 c,=1; +cs64-era-bt 5 28 5 1 4 3.2 12 22 c,=2;c=2; +cs64-era-bt 6 5 2 1 1 2.8 5 11 c=1; +cs64-era-bt 5 26 3 1 2 3.2 5 21 c,=2; +cs64-era-bt 6 4 3 1 2 3.1 12 10 c,=2; +cs64-era-bt 6 2 1 1 0 3.1 0 9 +cs64-era-bt 6 0 9 1 8 3.0 1 26 c,=5;c=3; +cs64-era-bt 6 7 4 1 3 3.6 9 16 c,=3; +cs64-era-bt 6 6 9 1 8 3.1 10 5 c,=6;c=2; +cs64-era-bt 6 1 2 1 1 3.4 7 27 c=1; +cs64-era-bt 5 31 4 1 3 3.7 5 7 c=2;c,=1; +cs64-era-bt 6 11 2 1 1 3.0 6 22 c,=1; +cs64-era-bt 6 10 4 1 3 3.3 10 1 c=2;c,=1; +cs64-era-bt 6 3 1 1 0 4.0 10 5 +cs64-era-bt 6 18 4 1 3 3.2 13 25 c,=3; +cs64-era-bt 6 8 7 1 6 5.7 8 3 c,=5;c=1; +cs64-era-bt 6 9 1 1 0 2.5 9 4 +cs64-era-bt 6 14 6 1 5 4.0 12 12 c,=4;c=1; +cs64-era-bt 6 13 5 1 4 3.7 2 25 c,=4; +cs64-era-bt 6 12 5 1 4 2.7 2 3 c,=3;c=1; +cs64-era-bt 6 20 1 1 0 3.0 4 26 +cs64-era-bt 6 15 1 1 0 3.0 11 24 +cs64-era-bt 6 21 2 1 1 2.7 0 13 c=1; +cs64-era-bt 6 23 3 1 2 2.6 8 13 c,=2; +cs64-era-bt 6 27 2 1 1 3.0 6 17 c,=1; +cs64-era-bt 6 24 6 1 5 3.0 9 22 c,=5; +cs64-era-bt 6 31 4 1 3 3.6 1 16 c=2;c,=1; +cs64-era-bt 6 16 9 1 8 2.9 8 0 c,=7;c=1; +cs64-era-bt 6 19 3 1 2 3.0 15 2 c,=2; +cs64-era-bt 6 17 7 1 6 2.8 11 0 c,=4;c=2; +cs64-era-bt 6 29 1 1 0 3.2 14 17 +cs64-era-bt 6 26 3 1 2 2.7 7 21 c,=2; +cs64-era-bt 7 6 1 1 0 4.3 3 7 +cs64-era-bt 6 22 1 1 0 3.9 9 14 +cs64-era-bt 7 11 2 1 1 3.8 14 24 c,=1; +cs64-era-bt 6 30 2 1 1 2.7 7 7 c,=1; +cs64-era-bt 6 28 5 1 4 4.3 10 20 c,=2;c=2; +cs64-era-bt 7 1 2 1 1 2.9 8 11 c=1; +cs64-era-bt 6 25 2 1 1 3.0 2 1 c=1; +cs64-era-bt 7 0 2 1 1 3.3 1 12 c=1; +cs64-era-bt 7 5 2 1 1 3.3 4 23 c=1; +cs64-era-bt 7 4 1 1 0 3.1 13 14 +cs64-era-bt 7 12 5 1 4 3.3 4 5 c=3;c,=1; +cs64-era-bt 7 13 4 1 3 2.7 8 11 c,=2;c=1; +cs64-era-bt 7 9 1 1 0 3.4 12 24 +cs64-era-bt 7 2 1 1 0 2.6 5 8 +cs64-era-bt 7 3 1 1 0 3.8 14 22 +cs64-era-bt 7 10 4 1 3 4.0 13 25 c=2;c,=1; +cs64-era-bt 7 8 2 1 1 3.0 12 17 c=1; +cs64-era-bt 7 7 2 1 1 2.9 13 6 c,=1; +cs64-era-bt 7 15 1 1 0 2.7 14 22 +cs64-era-bt 7 14 1 1 0 3.1 11 1 +cs64-era-bt 7 21 2 1 1 2.8 7 21 c=1; +cs64-era-bt 7 17 1 1 0 3.3 5 11 +cs64-era-bt 7 25 2 1 1 2.9 14 21 c=1; +cs64-era-bt 7 24 1 1 0 3.2 3 20 +cs64-era-bt 7 26 2 1 1 2.3 3 20 c,=1; +cs64-era-bt 7 23 1 1 0 3.8 12 27 +cs64-era-bt 7 18 1 1 0 2.9 14 23 +cs64-era-bt 7 16 2 1 1 3.7 5 11 c,=1; +cs64-era-bt 7 27 2 1 1 3.5 13 8 c,=1; +cs64-era-bt 7 20 1 1 0 3.0 3 14 +cs64-era-bt 7 22 1 1 0 2.8 5 25 +cs64-era-bt 7 30 1 1 0 5.9 2 27 +cs64-era-bt 7 29 1 1 0 3.2 13 4 +cs64-era-bt 7 31 1 1 0 3.8 5 27 +cs64-era-bt 7 19 3 1 2 3.0 13 1 c=2; +cs64-era-bt 7 28 2 1 1 3.0 14 11 c=1; +# end 2026-10-08T15:07:36Z rows=257 diff --git a/docs/analysis/class-v6/logs/connected/cs64-era-nobt.tsv b/docs/analysis/class-v6/logs/connected/cs64-era-nobt.tsv new file mode 100644 index 000000000..29386837b --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/cs64-era-nobt.tsv @@ -0,0 +1,259 @@ +# cs64-era-nobt class cs64s27x16 eras [0,1,2,3,4,5,6,7] seeds 32 era-widths 4 weights base bittest off bin 54b905920b91becc start 2026-10-08T15:01:08Z host f271665b754f threads 24 +cand era seed candidates accepted attempt bit_z bit_site bit_bit reasons +cs64-era-nobt 0 21 2 1 1 3.2 14 21 c=1; +cs64-era-nobt 0 6 1 1 0 5.1 3 19 +cs64-era-nobt 0 2 1 1 0 2.8 9 21 +cs64-era-nobt 0 4 1 1 0 3.2 12 20 +cs64-era-nobt 0 16 1 1 0 24.0 13 19 +cs64-era-nobt 0 12 2 1 1 12.5 15 19 c=1; +cs64-era-nobt 0 17 1 1 0 24.9 13 19 +cs64-era-nobt 0 8 2 1 1 32.0 3 19 c=1; +cs64-era-nobt 0 3 1 1 0 2.7 12 10 +cs64-era-nobt 0 15 1 1 0 2.8 14 16 +cs64-era-nobt 0 1 2 1 1 7.0 1 20 c=1; +cs64-era-nobt 0 19 3 1 2 3.6 1 19 c=2; +cs64-era-nobt 0 11 2 1 1 3.1 5 0 c=1; +cs64-era-nobt 0 7 2 1 1 46.9 13 19 c=1; +cs64-era-nobt 0 22 1 1 0 3.0 1 19 +cs64-era-nobt 0 10 1 1 0 16.2 6 19 +cs64-era-nobt 0 18 1 1 0 14.6 2 19 +cs64-era-nobt 0 0 2 1 1 10.8 0 19 c=1; +cs64-era-nobt 0 9 1 1 0 3.1 1 17 +cs64-era-nobt 0 14 1 1 0 65.0 8 19 +cs64-era-nobt 0 5 2 1 1 3.9 5 1 c=1; +cs64-era-nobt 0 23 1 1 0 7.4 12 19 +cs64-era-nobt 0 13 2 1 1 31.2 12 19 c=1; +cs64-era-nobt 0 20 1 1 0 3.8 10 1 +cs64-era-nobt 0 24 1 1 0 31.8 2 19 +cs64-era-nobt 0 30 1 1 0 46.5 14 19 +cs64-era-nobt 0 26 2 1 1 29.4 3 19 c=1; +cs64-era-nobt 0 31 1 1 0 6.9 0 19 +cs64-era-nobt 0 29 1 1 0 4.2 8 22 +cs64-era-nobt 0 28 2 1 1 70.2 15 19 c=1; +cs64-era-nobt 0 27 1 1 0 8.7 9 19 +cs64-era-nobt 1 3 1 1 0 3.3 15 7 +cs64-era-nobt 0 25 2 1 1 3.3 2 14 c=1; +cs64-era-nobt 1 0 2 1 1 11.4 0 6 c=1; +cs64-era-nobt 1 12 2 1 1 13.1 15 6 c=1; +cs64-era-nobt 1 5 2 1 1 3.6 4 16 c=1; +cs64-era-nobt 1 9 1 1 0 4.0 11 0 +cs64-era-nobt 1 4 1 1 0 10.9 6 7 +cs64-era-nobt 1 6 1 1 0 6.7 3 6 +cs64-era-nobt 1 1 2 1 1 2.8 6 20 c=1; +cs64-era-nobt 1 7 2 1 1 46.8 13 6 c=1; +cs64-era-nobt 1 10 1 1 0 14.5 6 6 +cs64-era-nobt 1 2 1 1 0 2.9 15 20 +cs64-era-nobt 1 11 2 1 1 3.1 3 6 c=1; +cs64-era-nobt 1 13 2 1 1 32.6 11 6 c=1; +cs64-era-nobt 1 15 1 1 0 3.2 6 1 +cs64-era-nobt 1 8 2 1 1 31.6 3 6 c=1; +cs64-era-nobt 1 14 1 1 0 63.5 8 6 +cs64-era-nobt 1 16 1 1 0 24.5 13 6 +cs64-era-nobt 1 17 1 1 0 24.0 13 6 +cs64-era-nobt 1 19 3 1 2 3.2 5 13 c=2; +cs64-era-nobt 1 21 2 1 1 2.6 11 19 c=1; +cs64-era-nobt 1 18 1 1 0 15.9 2 6 +cs64-era-nobt 1 20 1 1 0 3.0 15 9 +cs64-era-nobt 1 30 1 1 0 47.8 14 6 +cs64-era-nobt 1 23 1 1 0 4.8 12 6 +cs64-era-nobt 1 27 1 1 0 10.1 9 6 +cs64-era-nobt 2 1 2 1 1 3.3 0 4 c=1; +cs64-era-nobt 1 28 2 1 1 70.7 15 6 c=1; +cs64-era-nobt 1 24 1 1 0 30.4 2 6 +cs64-era-nobt 1 26 2 1 1 29.1 3 6 c=1; +cs64-era-nobt 1 22 1 1 0 3.3 4 25 +cs64-era-nobt 1 25 2 1 1 3.3 14 25 c=1; +cs64-era-nobt 1 29 1 1 0 3.9 10 6 +cs64-era-nobt 2 0 2 1 1 3.1 5 25 c=1; +cs64-era-nobt 2 3 1 1 0 2.6 11 1 +cs64-era-nobt 2 11 2 1 1 3.0 12 15 c=1; +cs64-era-nobt 2 7 2 1 1 3.2 9 24 c=1; +cs64-era-nobt 1 31 1 1 0 7.8 0 6 +cs64-era-nobt 2 2 1 1 0 3.3 0 0 +cs64-era-nobt 2 9 1 1 0 2.6 6 1 +cs64-era-nobt 2 10 1 1 0 3.1 2 20 +cs64-era-nobt 2 8 2 1 1 3.5 13 24 c=1; +cs64-era-nobt 2 6 1 1 0 3.1 0 1 +cs64-era-nobt 2 4 1 1 0 2.7 0 10 +cs64-era-nobt 2 5 2 1 1 3.0 10 12 c=1; +cs64-era-nobt 2 12 2 1 1 2.8 13 23 c=1; +cs64-era-nobt 2 16 1 1 0 3.0 7 12 +cs64-era-nobt 2 13 2 1 1 3.1 2 26 c=1; +cs64-era-nobt 2 14 1 1 0 3.2 3 15 +cs64-era-nobt 2 24 1 1 0 3.5 3 11 +cs64-era-nobt 2 15 1 1 0 3.0 13 7 +cs64-era-nobt 2 25 2 1 1 3.1 2 7 c=1; +cs64-era-nobt 2 20 1 1 0 2.8 10 3 +cs64-era-nobt 2 18 1 1 0 3.2 3 11 +cs64-era-nobt 2 19 3 1 2 3.1 8 20 c=2; +cs64-era-nobt 2 17 1 1 0 2.7 10 2 +cs64-era-nobt 2 22 1 1 0 2.9 5 1 +cs64-era-nobt 2 21 2 1 1 2.8 15 4 c=1; +cs64-era-nobt 2 23 1 1 0 3.7 15 20 +cs64-era-nobt 2 26 2 1 1 4.6 1 26 c=1; +cs64-era-nobt 2 29 1 1 0 3.5 11 7 +cs64-era-nobt 2 28 2 1 1 3.0 2 23 c=1; +cs64-era-nobt 2 27 1 1 0 3.3 9 18 +cs64-era-nobt 2 30 1 1 0 3.1 8 20 +cs64-era-nobt 3 1 2 1 1 3.3 9 13 c=1; +cs64-era-nobt 2 31 1 1 0 3.3 15 18 +cs64-era-nobt 3 0 2 1 1 3.2 0 7 c=1; +cs64-era-nobt 3 4 1 1 0 3.7 9 10 +cs64-era-nobt 3 6 1 1 0 3.1 2 9 +cs64-era-nobt 3 5 2 1 1 3.1 3 20 c=1; +cs64-era-nobt 3 3 1 1 0 3.3 2 14 +cs64-era-nobt 3 2 1 1 0 3.1 3 25 +cs64-era-nobt 3 7 2 1 1 3.2 8 17 c=1; +cs64-era-nobt 3 8 2 1 1 3.3 0 14 c=1; +cs64-era-nobt 3 17 1 1 0 3.0 2 12 +cs64-era-nobt 3 11 2 1 1 3.2 6 13 c=1; +cs64-era-nobt 3 9 1 1 0 3.4 3 9 +cs64-era-nobt 3 15 1 1 0 2.7 7 3 +cs64-era-nobt 3 18 1 1 0 2.8 9 2 +cs64-era-nobt 3 10 1 1 0 3.8 5 4 +cs64-era-nobt 3 19 3 1 2 3.3 13 17 c=2; +cs64-era-nobt 3 14 1 1 0 2.8 2 18 +cs64-era-nobt 3 21 2 1 1 3.0 0 15 c=1; +cs64-era-nobt 3 12 2 1 1 3.4 14 17 c=1; +cs64-era-nobt 3 13 2 1 1 3.1 0 25 c=1; +cs64-era-nobt 3 16 1 1 0 3.2 13 0 +cs64-era-nobt 3 24 1 1 0 3.5 13 5 +cs64-era-nobt 3 20 1 1 0 3.4 2 2 +cs64-era-nobt 3 22 1 1 0 3.0 11 11 +cs64-era-nobt 3 26 2 1 1 3.3 5 16 c=1; +cs64-era-nobt 3 29 1 1 0 3.0 5 7 +cs64-era-nobt 3 23 1 1 0 2.9 3 25 +cs64-era-nobt 3 31 1 1 0 3.4 15 8 +cs64-era-nobt 3 25 2 1 1 3.2 13 6 c=1; +cs64-era-nobt 4 1 2 1 1 3.3 12 22 c=1; +cs64-era-nobt 4 0 2 1 1 11.8 0 10 c=1; +cs64-era-nobt 3 28 2 1 1 4.4 15 0 c=1; +cs64-era-nobt 4 4 1 1 0 11.1 6 11 +cs64-era-nobt 3 30 1 1 0 2.8 8 20 +cs64-era-nobt 3 27 1 1 0 2.9 15 13 +cs64-era-nobt 4 3 1 1 0 2.7 10 11 +cs64-era-nobt 4 2 1 1 0 2.9 10 22 +cs64-era-nobt 4 6 1 1 0 5.0 3 10 +cs64-era-nobt 4 5 2 1 1 3.3 15 27 c=1; +cs64-era-nobt 4 7 2 1 1 47.7 13 10 c=1; +cs64-era-nobt 4 10 1 1 0 15.7 6 10 +cs64-era-nobt 4 9 1 1 0 3.7 6 8 +cs64-era-nobt 4 11 2 1 1 3.7 8 16 c=1; +cs64-era-nobt 4 12 2 1 1 15.9 15 10 c=1; +cs64-era-nobt 4 13 2 1 1 32.3 11 10 c=1; +cs64-era-nobt 4 8 2 1 1 33.1 3 10 c=1; +cs64-era-nobt 4 14 1 1 0 63.9 8 10 +cs64-era-nobt 4 15 1 1 0 3.2 14 25 +cs64-era-nobt 4 17 1 1 0 22.9 13 10 +cs64-era-nobt 4 16 1 1 0 22.5 13 10 +cs64-era-nobt 4 18 1 1 0 16.0 2 10 +cs64-era-nobt 4 20 1 1 0 3.2 9 11 +cs64-era-nobt 4 22 1 1 0 3.2 8 24 +cs64-era-nobt 4 28 2 1 1 70.4 15 10 c=1; +cs64-era-nobt 4 19 3 1 2 3.4 2 0 c=2; +cs64-era-nobt 4 29 1 1 0 3.7 10 9 +cs64-era-nobt 4 31 1 1 0 7.3 0 10 +cs64-era-nobt 4 25 2 1 1 3.3 0 22 c=1; +cs64-era-nobt 4 21 2 1 1 2.8 8 10 c=1; +cs64-era-nobt 4 26 2 1 1 30.5 3 10 c=1; +cs64-era-nobt 4 24 1 1 0 30.3 2 10 +cs64-era-nobt 4 27 1 1 0 9.1 9 10 +cs64-era-nobt 4 30 1 1 0 48.5 14 10 +cs64-era-nobt 4 23 1 1 0 5.8 12 10 +cs64-era-nobt 5 0 2 1 1 10.7 0 22 c=1; +cs64-era-nobt 5 1 2 1 1 3.2 9 2 c=1; +cs64-era-nobt 5 4 1 1 0 9.9 6 23 +cs64-era-nobt 5 3 1 1 0 3.1 5 8 +cs64-era-nobt 5 5 2 1 1 3.5 14 23 c=1; +cs64-era-nobt 5 2 1 1 0 3.0 2 6 +cs64-era-nobt 5 7 2 1 1 47.0 13 22 c=1; +cs64-era-nobt 5 6 1 1 0 4.6 3 22 +cs64-era-nobt 5 9 1 1 0 4.1 8 7 +cs64-era-nobt 5 10 1 1 0 14.9 12 22 +cs64-era-nobt 5 8 2 1 1 31.2 3 22 c=1; +cs64-era-nobt 5 11 2 1 1 3.1 4 11 c=1; +cs64-era-nobt 5 14 1 1 0 63.4 8 22 +cs64-era-nobt 5 12 2 1 1 13.0 15 22 c=1; +cs64-era-nobt 5 13 2 1 1 30.8 11 22 c=1; +cs64-era-nobt 5 15 1 1 0 3.6 13 2 +cs64-era-nobt 5 16 1 1 0 24.0 13 22 +cs64-era-nobt 5 18 1 1 0 13.4 2 22 +cs64-era-nobt 5 17 1 1 0 23.8 13 22 +cs64-era-nobt 5 19 3 1 2 2.7 14 24 c=2; +cs64-era-nobt 5 21 2 1 1 3.1 10 16 c=1; +cs64-era-nobt 5 20 1 1 0 3.3 2 16 +cs64-era-nobt 5 26 2 1 1 29.3 3 22 c=1; +cs64-era-nobt 5 24 1 1 0 30.5 2 22 +cs64-era-nobt 5 23 1 1 0 5.7 12 22 +cs64-era-nobt 5 22 1 1 0 3.4 0 16 +cs64-era-nobt 5 25 2 1 1 3.0 5 1 c=1; +cs64-era-nobt 5 27 1 1 0 10.1 9 22 +cs64-era-nobt 5 28 2 1 1 71.5 15 22 c=1; +cs64-era-nobt 5 29 1 1 0 3.6 12 26 +cs64-era-nobt 5 31 1 1 0 6.4 0 22 +cs64-era-nobt 5 30 1 1 0 46.0 14 22 +cs64-era-nobt 6 1 2 1 1 3.4 7 27 c=1; +cs64-era-nobt 6 0 2 1 1 11.7 0 3 c=1; +cs64-era-nobt 6 2 1 1 0 3.1 0 9 +cs64-era-nobt 6 3 1 1 0 4.0 10 5 +cs64-era-nobt 6 4 1 1 0 8.4 6 4 +cs64-era-nobt 6 6 1 1 0 6.1 3 3 +cs64-era-nobt 6 5 2 1 1 2.8 5 11 c=1; +cs64-era-nobt 6 7 2 1 1 47.9 13 3 c=1; +cs64-era-nobt 6 10 1 1 0 16.1 6 3 +cs64-era-nobt 6 8 2 1 1 32.0 3 3 c=1; +cs64-era-nobt 6 11 2 1 1 3.0 6 22 c=1; +cs64-era-nobt 6 9 1 1 0 2.5 9 4 +cs64-era-nobt 6 12 2 1 1 14.8 15 3 c=1; +cs64-era-nobt 6 13 2 1 1 31.9 11 3 c=1; +cs64-era-nobt 6 14 1 1 0 63.6 8 3 +cs64-era-nobt 6 15 1 1 0 3.0 11 24 +cs64-era-nobt 6 16 1 1 0 24.1 13 3 +cs64-era-nobt 6 17 1 1 0 22.9 13 3 +cs64-era-nobt 6 18 1 1 0 18.8 2 3 +cs64-era-nobt 6 19 3 1 2 3.0 15 2 c=2; +cs64-era-nobt 6 21 2 1 1 2.7 0 13 c=1; +cs64-era-nobt 6 20 1 1 0 3.0 4 26 +cs64-era-nobt 6 23 1 1 0 8.2 12 3 +cs64-era-nobt 6 22 1 1 0 3.9 9 14 +cs64-era-nobt 6 24 1 1 0 30.1 2 3 +cs64-era-nobt 6 26 2 1 1 29.5 3 3 c=1; +cs64-era-nobt 6 28 2 1 1 71.3 15 3 c=1; +cs64-era-nobt 6 25 2 1 1 3.0 2 1 c=1; +cs64-era-nobt 6 27 1 1 0 8.6 9 3 +cs64-era-nobt 6 29 1 1 0 3.2 14 17 +cs64-era-nobt 6 30 1 1 0 47.4 14 3 +cs64-era-nobt 6 31 1 1 0 6.2 0 3 +cs64-era-nobt 7 1 2 1 1 2.9 8 11 c=1; +cs64-era-nobt 7 0 2 1 1 3.3 1 12 c=1; +cs64-era-nobt 7 4 1 1 0 3.1 13 14 +cs64-era-nobt 7 6 1 1 0 4.3 3 7 +cs64-era-nobt 7 3 1 1 0 3.8 14 22 +cs64-era-nobt 7 2 1 1 0 2.6 5 8 +cs64-era-nobt 7 5 2 1 1 3.3 4 23 c=1; +cs64-era-nobt 7 7 2 1 1 2.9 13 6 c=1; +cs64-era-nobt 7 8 2 1 1 3.0 12 17 c=1; +cs64-era-nobt 7 10 1 1 0 15.2 6 27 +cs64-era-nobt 7 9 1 1 0 3.4 12 24 +cs64-era-nobt 7 11 2 1 1 3.8 14 24 c=1; +cs64-era-nobt 7 12 2 1 1 12.5 15 27 c=1; +cs64-era-nobt 7 14 1 1 0 3.1 11 1 +cs64-era-nobt 7 13 2 1 1 27.9 14 27 c=1; +cs64-era-nobt 7 15 1 1 0 2.7 14 22 +cs64-era-nobt 7 16 1 1 0 24.0 13 27 +cs64-era-nobt 7 17 1 1 0 3.3 5 11 +cs64-era-nobt 7 18 1 1 0 2.9 14 23 +cs64-era-nobt 7 19 3 1 2 3.0 13 1 c=2; +cs64-era-nobt 7 21 2 1 1 2.8 7 21 c=1; +cs64-era-nobt 7 20 1 1 0 3.0 3 14 +cs64-era-nobt 7 23 1 1 0 3.8 12 27 +cs64-era-nobt 7 22 1 1 0 2.8 5 25 +cs64-era-nobt 7 26 2 1 1 2.3 3 20 c=1; +cs64-era-nobt 7 24 1 1 0 3.2 3 20 +cs64-era-nobt 7 25 2 1 1 2.9 14 21 c=1; +cs64-era-nobt 7 28 2 1 1 3.0 14 11 c=1; +cs64-era-nobt 7 29 1 1 0 3.2 13 4 +cs64-era-nobt 7 27 1 1 0 10.0 9 27 +cs64-era-nobt 7 30 1 1 0 5.9 2 27 +cs64-era-nobt 7 31 1 1 0 3.8 5 27 +# end 2026-10-08T15:07:58Z rows=257 diff --git a/docs/analysis/class-v6/logs/connected/cs64-none.tsv b/docs/analysis/class-v6/logs/connected/cs64-none.tsv new file mode 100644 index 000000000..5291eb63c --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/cs64-none.tsv @@ -0,0 +1,259 @@ +# cs64-none class cs64s27x16 eras [none] seeds 256 era-widths 4 weights base bittest off bin 54b905920b91becc start 2026-10-08T15:01:08Z host f271665b754f threads 40 +cand era seed candidates accepted attempt bit_z bit_site bit_bit reasons +cs64-none none 12 1 1 0 3.8 4 20 +cs64-none none 8 1 1 0 55.1 1 0 +cs64-none none 36 1 1 0 3.2 15 24 +cs64-none none 2 1 1 0 2.7 12 3 +cs64-none none 14 1 1 0 2.7 0 16 +cs64-none none 10 1 1 0 3.1 1 22 +cs64-none none 37 1 1 0 42.9 6 0 +cs64-none none 38 2 1 1 20.3 3 0 c=1; +cs64-none none 29 2 1 1 3.4 7 24 c=1; +cs64-none none 7 1 1 0 35.3 11 0 +cs64-none none 31 1 1 0 17.2 3 0 +cs64-none none 18 1 1 0 49.8 13 0 +cs64-none none 11 1 1 0 3.3 4 26 +cs64-none none 0 1 1 0 3.6 9 17 +cs64-none none 35 1 1 0 42.4 13 0 +cs64-none none 23 3 1 2 29.2 11 0 c=2; +cs64-none none 4 1 1 0 38.8 11 0 +cs64-none none 30 1 1 0 3.1 13 17 +cs64-none none 20 1 1 0 3.0 3 11 +cs64-none none 17 1 1 0 3.8 7 1 +cs64-none none 32 1 1 0 5.5 8 0 +cs64-none none 28 2 1 1 2.8 6 11 c=1; +cs64-none none 39 1 1 0 3.7 9 0 +cs64-none none 21 1 1 0 31.7 9 0 +cs64-none none 9 1 1 0 59.0 9 0 +cs64-none none 33 2 1 1 30.3 11 0 c=1; +cs64-none none 24 1 1 0 21.1 10 0 +cs64-none none 5 2 1 1 23.5 6 0 c=1; +cs64-none none 25 1 1 0 2.8 9 27 +cs64-none none 6 1 1 0 17.3 0 0 +cs64-none none 1 1 1 0 16.6 3 0 +cs64-none none 16 1 1 0 22.5 2 0 +cs64-none none 3 1 1 0 26.8 7 0 +cs64-none none 26 1 1 0 24.3 14 0 +cs64-none none 27 1 1 0 3.4 14 7 +cs64-none none 34 2 1 1 3.1 2 26 c=1; +cs64-none none 22 1 1 0 22.3 3 0 +cs64-none none 19 1 1 0 16.5 14 1 +cs64-none none 13 1 1 0 4.7 12 1 +cs64-none none 15 3 1 2 4.0 0 1 c=2; +cs64-none none 46 1 1 0 2.6 3 4 +cs64-none none 42 2 1 1 4.0 10 21 c=1; +cs64-none none 50 1 1 0 64.1 10 1 +cs64-none none 51 2 1 1 30.9 11 0 c=1; +cs64-none none 40 1 1 0 65.4 6 0 +cs64-none none 63 1 1 0 6.3 10 0 +cs64-none none 66 1 1 0 2.6 14 24 +cs64-none none 58 3 1 2 17.7 4 0 c=2; +cs64-none none 43 1 1 0 64.4 9 0 +cs64-none none 59 1 1 0 127.7 4 0 +cs64-none none 45 1 1 0 13.3 13 0 +cs64-none none 44 1 1 0 3.0 14 3 +cs64-none none 41 1 1 0 12.4 8 0 +cs64-none none 53 1 1 0 3.2 8 7 +cs64-none none 47 1 1 0 33.8 7 0 +cs64-none none 56 1 1 0 3.0 12 22 +cs64-none none 52 1 1 0 47.9 12 0 +cs64-none none 48 2 1 1 50.0 4 1 c=1; +cs64-none none 49 1 1 0 3.3 7 2 +cs64-none none 60 2 1 1 9.4 6 0 c=1; +cs64-none none 55 1 1 0 13.0 13 0 +cs64-none none 75 3 1 2 3.2 10 3 c=2; +cs64-none none 54 3 1 2 13.5 8 0 c=2; +cs64-none none 57 1 1 0 32.5 6 0 +cs64-none none 76 1 1 0 9.3 12 0 +cs64-none none 61 2 1 1 15.1 4 0 c=1; +cs64-none none 64 1 1 0 3.0 2 8 +cs64-none none 70 2 1 1 20.6 2 0 c=1; +cs64-none none 71 1 1 0 14.4 2 0 +cs64-none none 67 4 1 3 9.5 6 0 c=3; +cs64-none none 62 1 1 0 3.0 7 20 +cs64-none none 65 3 1 2 12.0 4 0 c=2; +cs64-none none 79 1 1 0 84.3 9 0 +cs64-none none 69 2 1 1 2.9 3 22 c=1; +cs64-none none 77 1 1 0 19.8 15 0 +cs64-none none 68 2 1 1 31.4 3 0 c=1; +cs64-none none 85 2 1 1 3.1 9 15 c=1; +cs64-none none 73 1 1 0 3.5 1 2 +cs64-none none 78 3 1 2 3.1 7 13 c=2; +cs64-none none 72 1 1 0 3.8 7 1 +cs64-none none 74 1 1 0 5.5 0 0 +cs64-none none 88 1 1 0 64.0 13 0 +cs64-none none 83 2 1 1 4.0 8 15 c=1; +cs64-none none 101 1 1 0 29.9 11 0 +cs64-none none 80 3 1 2 4.1 1 0 c=2; +cs64-none none 81 2 1 1 11.0 7 0 c=1; +cs64-none none 91 1 1 0 3.4 8 22 +cs64-none none 84 1 1 0 26.1 1 0 +cs64-none none 86 1 1 0 2.9 9 24 +cs64-none none 82 1 1 0 2.9 9 19 +cs64-none none 87 1 1 0 3.3 10 21 +cs64-none none 93 1 1 0 3.1 7 26 +cs64-none none 103 1 1 0 4.4 0 0 +cs64-none none 99 3 1 2 50.9 13 0 c=2; +cs64-none none 96 1 1 0 3.0 7 26 +cs64-none none 89 1 1 0 93.8 8 0 +cs64-none none 102 1 1 0 14.1 3 0 +cs64-none none 94 1 1 0 3.6 1 19 +cs64-none none 92 1 1 0 3.9 0 13 +cs64-none none 114 1 1 0 3.9 7 17 +cs64-none none 95 6 1 5 32.2 11 0 c=5; +cs64-none none 97 1 1 0 6.7 6 0 +cs64-none none 90 2 1 1 2.9 8 27 c=1; +cs64-none none 104 1 1 0 12.8 2 0 +cs64-none none 108 3 1 2 21.0 12 0 c=2; +cs64-none none 111 1 1 0 18.4 4 0 +cs64-none none 106 1 1 0 4.8 6 0 +cs64-none none 100 1 1 0 13.0 1 0 +cs64-none none 98 1 1 0 3.2 14 25 +cs64-none none 105 1 1 0 5.4 1 0 +cs64-none none 113 1 1 0 3.7 0 26 +cs64-none none 121 2 1 1 3.4 10 6 c=1; +cs64-none none 107 2 1 1 3.4 1 8 c=1; +cs64-none none 118 1 1 0 27.1 15 0 +cs64-none none 110 1 1 0 2.8 15 4 +cs64-none none 115 1 1 0 67.1 0 0 +cs64-none none 122 1 1 0 128.0 4 0 +cs64-none none 117 2 1 1 25.7 6 0 c=1; +cs64-none none 109 1 1 0 46.1 3 0 +cs64-none none 112 1 1 0 60.5 11 0 +cs64-none none 119 1 1 0 3.3 3 3 +cs64-none none 116 1 1 0 6.9 13 0 +cs64-none none 124 1 1 0 8.1 15 0 +cs64-none none 126 1 1 0 2.6 10 18 +cs64-none none 125 1 1 0 35.3 3 0 +cs64-none none 140 1 1 0 26.0 1 10 +cs64-none none 123 1 1 0 3.2 8 6 +cs64-none none 130 1 1 0 53.1 11 0 +cs64-none none 120 1 1 0 2.9 5 6 +cs64-none none 145 3 1 2 51.8 4 0 c=2; +cs64-none none 128 1 1 0 3.3 4 1 +cs64-none none 127 4 1 3 41.6 4 0 c=3; +cs64-none none 143 1 1 0 23.8 8 0 +cs64-none none 129 1 1 0 14.0 11 0 +cs64-none none 139 2 1 1 8.2 13 0 c=1; +cs64-none none 144 1 1 0 3.8 13 13 +cs64-none none 134 1 1 0 54.0 5 0 +cs64-none none 132 1 1 0 3.1 12 16 +cs64-none none 131 1 1 0 20.3 0 0 +cs64-none none 138 1 1 0 3.1 3 25 +cs64-none none 133 2 1 1 30.1 4 0 c=1; +cs64-none none 152 1 1 0 127.9 13 0 +cs64-none none 141 1 1 0 4.3 11 0 +cs64-none none 137 2 1 1 21.0 1 0 c=1; +cs64-none none 146 1 1 0 3.5 4 22 +cs64-none none 136 1 1 0 3.0 7 16 +cs64-none none 150 1 1 0 6.4 1 0 +cs64-none none 153 1 1 0 15.0 8 0 +cs64-none none 135 6 1 5 10.2 11 0 c=5; +cs64-none none 142 2 1 1 11.2 7 0 c=1; +cs64-none none 149 1 1 0 24.9 11 0 +cs64-none none 148 2 1 1 43.3 9 0 c=1; +cs64-none none 163 1 1 0 17.9 15 0 +cs64-none none 147 1 1 0 30.1 4 0 +cs64-none none 155 2 1 1 4.8 7 0 c=1; +cs64-none none 151 4 1 3 55.9 0 0 c=3; +cs64-none none 166 1 1 0 3.2 8 0 +cs64-none none 157 1 1 0 3.6 1 17 +cs64-none none 160 1 1 0 4.1 6 26 +cs64-none none 154 1 1 0 16.5 13 0 +cs64-none none 156 1 1 0 83.9 2 0 +cs64-none none 165 1 1 0 9.2 4 0 +cs64-none none 162 1 1 0 19.9 10 0 +cs64-none none 158 1 1 0 3.1 8 3 +cs64-none none 169 2 1 1 35.4 8 0 c=1; +cs64-none none 159 1 1 0 5.0 7 0 +cs64-none none 161 1 1 0 3.2 13 7 +cs64-none none 164 1 1 0 59.8 8 0 +cs64-none none 180 1 1 0 4.0 11 2 +cs64-none none 177 1 1 0 21.3 0 0 +cs64-none none 175 1 1 0 3.1 12 21 +cs64-none none 168 1 1 0 3.5 0 8 +cs64-none none 171 1 1 0 18.7 2 0 +cs64-none none 172 1 1 0 18.7 3 0 +cs64-none none 170 1 1 0 22.3 0 0 +cs64-none none 176 3 1 2 3.2 1 2 c=2; +cs64-none none 173 2 1 1 49.9 4 0 c=1; +cs64-none none 181 1 1 0 3.3 4 8 +cs64-none none 179 1 1 0 17.5 2 0 +cs64-none none 167 1 1 0 19.3 9 0 +cs64-none none 186 1 1 0 38.4 5 0 +cs64-none none 174 1 1 0 24.1 0 0 +cs64-none none 185 2 1 1 3.0 4 14 c=1; +cs64-none none 178 2 1 1 43.0 3 0 c=1; +cs64-none none 182 1 1 0 3.3 0 26 +cs64-none none 187 2 1 1 82.5 0 0 c=1; +cs64-none none 189 3 1 2 8.2 15 0 c=2; +cs64-none none 188 1 1 0 31.2 6 0 +cs64-none none 190 1 1 0 3.5 12 11 +cs64-none none 193 1 1 0 19.7 5 0 +cs64-none none 183 1 1 0 3.0 15 21 +cs64-none none 192 1 1 0 6.8 3 0 +cs64-none none 196 1 1 0 3.6 9 0 +cs64-none none 198 1 1 0 8.6 13 0 +cs64-none none 184 1 1 0 3.5 7 0 +cs64-none none 195 1 1 0 14.5 6 0 +cs64-none none 191 2 1 1 29.9 6 0 c=1; +cs64-none none 194 1 1 0 14.1 6 0 +cs64-none none 197 1 1 0 31.6 5 0 +cs64-none none 204 1 1 0 3.0 15 15 +cs64-none none 210 1 1 0 46.5 15 0 +cs64-none none 207 1 1 0 3.5 8 11 +cs64-none none 202 1 1 0 3.8 11 12 +cs64-none none 199 1 1 0 18.5 3 1 +cs64-none none 200 2 1 1 10.9 12 0 c=1; +cs64-none none 209 1 1 0 3.1 10 17 +cs64-none none 214 1 1 0 3.3 5 16 +cs64-none none 201 2 1 1 3.3 8 17 c=1; +cs64-none none 208 1 1 0 34.3 1 0 +cs64-none none 206 1 1 0 15.5 11 0 +cs64-none none 205 1 1 0 28.4 11 0 +cs64-none none 216 1 1 0 45.3 13 0 +cs64-none none 203 1 1 0 3.3 1 24 +cs64-none none 221 1 1 0 3.2 12 16 +cs64-none none 220 1 1 0 3.5 14 14 +cs64-none none 218 4 1 3 4.0 6 22 c=3; +cs64-none none 223 3 1 2 42.6 10 0 c=2; +cs64-none none 224 1 1 0 3.2 2 11 +cs64-none none 212 1 1 0 28.8 1 0 +cs64-none none 217 1 1 0 3.0 15 7 +cs64-none none 215 4 1 3 53.8 9 0 c=3; +cs64-none none 225 3 1 2 3.8 4 1 c=2; +cs64-none none 228 1 1 0 3.0 8 3 +cs64-none none 211 1 1 0 3.7 8 1 +cs64-none none 213 1 1 0 13.4 4 0 +cs64-none none 229 1 1 0 3.9 12 1 +cs64-none none 219 2 1 1 33.2 6 1 c=1; +cs64-none none 232 1 1 0 3.2 8 13 +cs64-none none 231 1 1 0 9.3 15 0 +cs64-none none 222 1 1 0 16.5 10 0 +cs64-none none 235 1 1 0 32.7 3 0 +cs64-none none 234 1 1 0 3.6 11 23 +cs64-none none 233 1 1 0 3.1 13 21 +cs64-none none 226 3 1 2 9.0 15 0 c=2; +cs64-none none 227 2 1 1 3.4 1 4 c=1; +cs64-none none 238 1 1 0 15.6 13 0 +cs64-none none 230 1 1 0 20.9 0 0 +cs64-none none 237 3 1 2 3.9 5 19 c=2; +cs64-none none 236 1 1 0 3.2 7 23 +cs64-none none 239 1 1 0 19.7 4 0 +cs64-none none 251 1 1 0 26.7 14 0 +cs64-none none 240 1 1 0 31.3 12 0 +cs64-none none 252 2 1 1 61.1 9 0 c=1; +cs64-none none 242 1 1 0 14.0 12 0 +cs64-none none 244 1 1 0 2.7 11 8 +cs64-none none 241 1 1 0 50.7 13 0 +cs64-none none 248 1 1 0 3.1 1 17 +cs64-none none 246 2 1 1 11.2 5 0 c=1; +cs64-none none 253 2 1 1 8.2 9 0 c=1; +cs64-none none 247 1 1 0 34.2 5 0 +cs64-none none 249 1 1 0 3.3 7 3 +cs64-none none 250 2 1 1 25.8 9 0 c=1; +cs64-none none 243 2 1 1 52.5 8 1 c=1; +cs64-none none 254 1 1 0 3.1 12 10 +cs64-none none 245 1 1 0 11.4 8 0 +cs64-none none 255 1 1 0 12.2 8 0 +# end 2026-10-08T15:07:34Z rows=257 diff --git a/docs/analysis/class-v6/logs/connected/uniform-cs64-none.tsv b/docs/analysis/class-v6/logs/connected/uniform-cs64-none.tsv new file mode 100644 index 000000000..08d76ac7d --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/uniform-cs64-none.tsv @@ -0,0 +1,17 @@ +class era seed attempt program_id min_site_ratio min_site top0.1_share control_share ratio_to_control max_item_reads control_max reads +cs64s27x16 none 0 0 9ad55de91485542b 1.00006 15 0.002383 0.002382 1.0002 27 27 134217728 +cs64s27x16 none 4 0 ef05f7b4f74f8b34 0.99876 11 0.002381 0.002377 1.0016 26 29 134217728 +cs64s27x16 none 9 0 4f7dfb188ea079f8 0.99407 9 0.002382 0.002380 1.0010 27 28 134217728 +cs64s27x16 none 3 0 423f3fcb11ffd16c 0.99937 7 0.002380 0.002380 1.0001 27 28 134217728 +cs64s27x16 none 12 0 f2ee7ca7642ce409 1.00010 1 0.002378 0.002381 0.9987 27 27 134217728 +cs64s27x16 none 7 0 a05222bdb885f832 0.99795 11 0.002381 0.002379 1.0010 28 27 134217728 +cs64s27x16 none 10 0 d6229a4ebc3da203 1.00013 1 0.002381 0.002381 0.9999 28 27 134217728 +cs64s27x16 none 8 0 5d3c176e39a2d7bd 0.99565 1 0.002377 0.002379 0.9991 27 27 134217728 +cs64s27x16 none 1 0 118f3f6ee409eb00 1.00000 3 0.002379 0.002381 0.9990 26 27 134217728 +cs64s27x16 none 5 1 66da80dabf645c59 0.99958 6 0.002382 0.002379 1.0014 27 28 134217728 +cs64s27x16 none 15 2 7261a08393ef6b71 1.00000 2 0.002379 0.002380 0.9996 26 27 134217728 +cs64s27x16 none 6 0 0f25af70edd287cc 0.99985 0 0.002381 0.002380 1.0003 26 28 134217728 +cs64s27x16 none 11 0 b1ccae46f9288cc2 1.00008 14 0.002381 0.002382 0.9997 27 27 134217728 +cs64s27x16 none 2 0 53c13e9f37bad71f 1.00010 3 0.002380 0.002380 0.9999 26 29 134217728 +cs64s27x16 none 14 0 e84c88374beb684f 1.00010 6 0.002382 0.002382 1.0002 27 27 134217728 +cs64s27x16 none 13 0 87d88cf6b4db69a2 1.00011 10 0.002383 0.002383 1.0003 29 27 134217728 diff --git a/docs/analysis/class-v6/logs/connected/worker-4090.log b/docs/analysis/class-v6/logs/connected/worker-4090.log new file mode 100644 index 000000000..1d54c2ac2 --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/worker-4090.log @@ -0,0 +1,17 @@ +RESULT worker pack packs/cs64-bound 15:17:37 +RESULT check packs/cs64-bound info igneum-worker-cuda 1.0 (4 October 2026): device 0 NVIDIA_GeForce_RTX_4090 (sm_89, 128 SMs), driver 13.0 from libcuda.so.1, NVRTC 12.8 from libnvrtc.so.12, target sm_89 (the device's architecture, listed by NVRTC) +RESULT check packs/cs64-bound check PASS packs/cs64-bound in 2953 ms: nvrtc 1813 cache 2 dataset 31 hot 0 check 1106 race 0 ms variant base class v2; self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT check packs/cs64-bound epoch 69676e65756d2d7636632f30 day 6461792f323032362d31302d3033, dataset 2^28 words, cache 2^26 words in 65536 segments, 87 registers, 20 blocks/SM at 1 warp(s)/block, target sm_89 +RESULT bench packs/cs64-bound pack packs/cs64-bound on NVIDIA_GeForce_RTX_4090: nvrtc 1749 cache 2 dataset 31 hot 0 check 1101 race 0 ms variant base class v2; self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT bench packs/cs64-bound warm-up dispatch (base 0): 268.83 ms; 250 timed dispatches of 16777216 nonces: mean 268.83 ms +RESULT bench packs/cs64-bound RESULT pack=packs/cs64-bound class=mx8+sh256x27 device=NVIDIA_GeForce_RTX_4090 arch=sm_89 regs=87 blocks_per_sm=20 warps=0 resident=2560 arena_mib=0 hot_mib=0 hot_slots=0 hot_fill_ms=0.00 nonces=16777216 batches=250 check=PASS fingerprint=ad0cec2a42c84aff mhs=62.408 loads=128 bytes=512 scratch_ops=0 time=wall +RESULT smi packs/cs64-bound samples 66 mean_power_w 269.4 mean_sm_mhz 2809 +RESULT worker pack v5-genesis 15:18:52 +RESULT check v5-genesis info igneum-worker-cuda 1.0 (4 October 2026): device 0 NVIDIA_GeForce_RTX_4090 (sm_89, 128 SMs), driver 13.0 from libcuda.so.1, NVRTC 12.8 from libnvrtc.so.12, target sm_89 (the device's architecture, listed by NVRTC) +RESULT check v5-genesis check PASS v5-genesis in 1722 ms: nvrtc 586 cache 2 dataset 31 hot 0 check 1102 race 0 ms variant base class v5 (state leaves 93, uploaded for the build and freed); self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT check v5-genesis epoch 69676e65756d2d67656e65736973 day 6461792f323032362d31302d3033, dataset 2^28 words, cache 2^26 words in 65536 segments, 32 registers, 24 blocks/SM at 1 warp(s)/block, target sm_89 +RESULT bench v5-genesis pack v5-genesis on NVIDIA_GeForce_RTX_4090: nvrtc 559 cache 2 dataset 32 hot 0 check 1100 race 0 ms variant base class v5 (state leaves 93, uploaded for the build and freed); self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT bench v5-genesis warm-up dispatch (base 0): 268.89 ms; 250 timed dispatches of 16777216 nonces: mean 268.89 ms +RESULT bench v5-genesis RESULT pack=v5-genesis class=mx8+sh256x27+state device=NVIDIA_GeForce_RTX_4090 arch=sm_89 regs=32 blocks_per_sm=24 warps=0 resident=3072 arena_mib=0 hot_mib=0 hot_slots=0 hot_fill_ms=0.00 nonces=16777216 batches=250 check=PASS fingerprint=ae74193ddad19e19 mhs=62.394 loads=128 bytes=512 scratch_ops=0 time=wall +RESULT smi v5-genesis samples 65 mean_power_w 271.9 mean_sm_mhz 2805 +RESULT worker end 15:20:03 diff --git a/docs/analysis/class-v6/logs/connected/worker-5090.log b/docs/analysis/class-v6/logs/connected/worker-5090.log new file mode 100644 index 000000000..1a5ac8d6f --- /dev/null +++ b/docs/analysis/class-v6/logs/connected/worker-5090.log @@ -0,0 +1,17 @@ +RESULT worker pack packs/cs64-bound 15:16:17 +RESULT check packs/cs64-bound info igneum-worker-cuda 1.0 (4 October 2026): device 0 NVIDIA_GeForce_RTX_5090 (sm_120, 170 SMs), driver 13.0 from libcuda.so.1, NVRTC 12.8 from libnvrtc.so.12, target sm_120 (the device's architecture, listed by NVRTC) +RESULT check packs/cs64-bound check PASS packs/cs64-bound in 2256 ms: nvrtc 1089 cache 3 dataset 30 hot 0 check 1130 race 0 ms variant base class v2; self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT check packs/cs64-bound epoch 69676e65756d2d7636632f30 day 6461792f323032362d31302d3033, dataset 2^28 words, cache 2^26 words in 65536 segments, 80 registers, 24 blocks/SM at 1 warp(s)/block, target sm_120 +RESULT bench packs/cs64-bound pack packs/cs64-bound on NVIDIA_GeForce_RTX_5090: nvrtc 1086 cache 3 dataset 30 hot 0 check 1122 race 0 ms variant base class v2; self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT bench packs/cs64-bound warm-up dispatch (base 0): 268.09 ms; 250 timed dispatches of 16777216 nonces: mean 266.80 ms +RESULT bench packs/cs64-bound RESULT pack=packs/cs64-bound class=mx8+sh256x27 device=NVIDIA_GeForce_RTX_5090 arch=sm_120 regs=80 blocks_per_sm=24 warps=0 resident=4080 arena_mib=0 hot_mib=0 hot_slots=0 hot_fill_ms=0.00 nonces=16777216 batches=250 check=PASS fingerprint=ad0cec2a42c84aff mhs=62.882 loads=128 bytes=512 scratch_ops=0 time=wall +RESULT smi packs/cs64-bound samples 65 mean_power_w 574.2 mean_sm_mhz 2797 +RESULT worker pack v5-genesis 15:17:29 +RESULT check v5-genesis info igneum-worker-cuda 1.0 (4 October 2026): device 0 NVIDIA_GeForce_RTX_5090 (sm_120, 170 SMs), driver 13.0 from libcuda.so.1, NVRTC 12.8 from libnvrtc.so.12, target sm_120 (the device's architecture, listed by NVRTC) +RESULT check v5-genesis check PASS v5-genesis in 1709 ms: nvrtc 505 cache 5 dataset 32 hot 0 check 1162 race 0 ms variant base class v5 (state leaves 93, uploaded for the build and freed); self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT check v5-genesis epoch 69676e65756d2d67656e65736973 day 6461792f323032362d31302d3033, dataset 2^28 words, cache 2^26 words in 65536 segments, 48 registers, 24 blocks/SM at 1 warp(s)/block, target sm_120 +RESULT bench v5-genesis pack v5-genesis on NVIDIA_GeForce_RTX_5090: nvrtc 500 cache 3 dataset 30 hot 0 check 1156 race 0 ms variant base class v5 (state leaves 93, uploaded for the build and freed); self-test PASS (cache head, last line and FNV-1a 64 48c4f5bf24166b2e; dataset head, word [268435455] and 64 samples; 96 of 96 vector lanes) +RESULT bench v5-genesis warm-up dispatch (base 0): 258.26 ms; 250 timed dispatches of 16777216 nonces: mean 266.46 ms +RESULT bench v5-genesis RESULT pack=v5-genesis class=mx8+sh256x27+state device=NVIDIA_GeForce_RTX_5090 arch=sm_120 regs=48 blocks_per_sm=24 warps=0 resident=4080 arena_mib=0 hot_mib=0 hot_slots=0 hot_fill_ms=0.00 nonces=16777216 batches=250 check=PASS fingerprint=ae74193ddad19e19 mhs=62.963 loads=128 bytes=512 scratch_ops=0 time=wall +RESULT smi v5-genesis samples 65 mean_power_w 571.4 mean_sm_mhz 2798 +RESULT worker end 15:18:41 diff --git a/docs/analysis/proving-pipeline-2026-10-08.md b/docs/analysis/proving-pipeline-2026-10-08.md new file mode 100644 index 000000000..ad385e641 --- /dev/null +++ b/docs/analysis/proving-pipeline-2026-10-08.md @@ -0,0 +1,121 @@ +# Devnet 3 proving pipeline, end to end, 8 October 2026 + +The external review's order (through the coordinator, 15:4x BST): every paid shard's time in each stage, separated, with the median and +the slowest 5 and 1 percent; the failure and retry rate; the queue depth over time; realised earnings and wasted work per hardware tier, +which cards complete paid work after the 10 DAA-second exclusive window, and how often a faster claimant takes an assigned prover's reward. + +## The window and its limit + +The measurement window is the whole of 8 October's proving on the rented fleet, 07:00:26Z (first claim) to 14:27:15Z (last claim), read +from every prover box's own log after Devnet 3 was turned off at 15:34Z. Paid work exists only between 07:46:55Z and 10:43:10Z: 93 paid +segments, 172.88 IGN. From 11:45Z the chain stalled at the class v5 crossing and then partitioned (every solo branch carried old-object +blocks, the network restarted from the stall sink at 15:27Z and was turned off at 15:34Z), so every segment claimed after 11:45Z was +submitted into a chain that never paid it. The hold's declared workload (150 tx/s) ran 11:42Z to 12:23Z with inclusion, then without, so +no paid shard carries a hold transaction: the stage columns below are the fleet's proving of the chain's own blocks, under the pre-stall +load (the DEX and faucet lanes, the hold's earlier steps), on the 0.3.24 node (5b673577). The window asked for, two hours under the hold, +does not exist in the record; this is the honest substitute, and the instrument is in place for the next chain. + +## The instrument + +Collector `tools/fleet/pipeline-collect.py` (hub-1's Devnet 3 node, `igneum_getProvingStatus` every 30 s; every prover's RESULT lines +every 5 min) and the per-box logs `/root/fleet/out/prover.log` written by `tools/fleet/box-prover.py`, pulled whole after the stop. Each +column names its lines. + +| column | source lines in prover.log | how the number is read | +|---|---|---| +| assignment wait | `RESULT claim segment A..B (n shards, fresh) margin=M tip=T` | not separable from the logs: a segment becomes claimable when its last block settles and the box claims on its next pass (passes every 15 s). The proxy recorded is the margin at claim, the DAA left before the deadline (600 DAA window): median 467, p5 (slowest) 557 is not a wait but an early claim. Block timestamps would give the wait exactly; Devnet 3 is off, so they are not read. | +| inputs | claim stamp to the chain's start (the `RESULT seg N chain` stamp minus its `wall`) | the export of the segment's records from the node, the pair check and the cuts | +| proving | `RESULT seg N chain k shard records, chain_len c, proof b bytes, shards P s, aggregation A s, wall W s, peak MiB` field P | the shard proofs on the card (SP1 floor server) | +| aggregation | the same line's A | the segment chain over the shard proofs | +| verification | chain stamp to `RESULT seg N shards accepted k of n` | the node's verification of each shard record at submission; it answers inside the second, so verification and submission are one column | +| inclusion and payment | `RESULT submitted ... end to end E s` to `RESULT paid ... after S s` | S is the prover's own clock from the record's acceptance to the payment read on its node | +| failure, retry | `RESULT seg N ... FAILED`, `RESULT segment_refused`, `RESULT unpaid`, `RESULT paid_other`, `record accepted on retry` | counted per kind | +| queue depth | `RESULT pass n no whole segment inside the margin (worklist N entries, tip T)` | N is the node's assigned-shard worklist as the prover reads it on each idle pass | + +## Stage columns, seconds, every segment that reached the stage + +| stage | n | median | slowest 5 % | slowest 1 % | max | +|---|---|---|---|---|---| +| inputs (claim to export and cuts done) | 2,447 | 2.4 | 7.5 | 10.1 | 14.7 | +| proving (shard proofs) | 2,453 | 26.8 | 216.1 | 364.7 | 1,104.7 | +| aggregation (segment chain) | 2,453 | 22.8 | 44.2 | 96.4 | 156.6 | +| verification and shard-record submission | 2,453 | 0.0 | 2.0 | 2.0 | 10.0 | +| segment-record submission | 1,909 | 0.0 | 1.0 | 1.0 | 1.0 | +| claim to submitted (end to end) | 1,909 | 75.1 | 230.3 | 301.6 | 497.4 | +| inclusion and payment (submitted to paid) | 93 | 171.0 | 543.0 | 31,397 | 31,470 | +| claim to paid | 91 | 336.0 | 720.0 | 1,098 | 1,240 | +| peak GPU memory during the chain, MiB | 2,453 | 11,948 | 21,174 | 25,788 | 26,210 | + +The two 31,000-second payments are segments submitted before the 02:4xZ pause and paid when the chain resumed; without them the +inclusion-and-payment p99 is 902 s. The assignment wait is not in the table (see the instrument row). + +## Paid segments per tier + +| tier | paid segments | IGN | proving median s | aggregation median s | payment median s | payment p95 s | +|---|---|---|---|---|---|---| +| RTX 4090 | 48 | 89.33 | 117.3 | 20.1 | 177.5 | 649 | +| RTX 3090 | 34 | 59.66 | 69.8 | 75.0 | 166.0 | 543 | +| L40S | 10 | 21.86 | 67.0 | 18.7 | 125.0 | 370 | +| RTX 6000 Ada | 1 | 2.03 | 20.2 | 18.4 | 116.0 | 116 | +| RTX 3060 (12 GB) | 0 | 0 | | | | | + +The 3090's aggregation median (75 s) is three times the 4090's: the segment chain is memory-bound and the 3090 pays for it. The 4090's +proving median on paid segments (117 s) is above the all-segment median (27 s) because paid segments are the long ones (the short ones +were taken by a faster claimant, below). + +## Outcomes per tier and wasted work + +| tier | claimed | paid | stolen | refused | submitted, never paid | claimed, never submitted | work s paid | work s wasted | +|---|---|---|---|---|---|---|---|---| +| RTX 4090 | 2,515 | 48 | 98 | 93 | 1,322 | 959 | 7,025 | 183,524 | +| RTX 3060 12 GB | 313 | 0 | 0 | 0 | 34 | 280 | 0 | 6,765 | +| L40S | 273 | 10 | 25 | 28 | 147 | 63 | 1,196 | 26,026 | +| RTX 3090 | 263 | 34 | 8 | 30 | 152 | 41 | 6,484 | 34,855 | +| RTX 6000 Ada | 45 | 1 | 6 | 0 | 26 | 12 | 57 | 3,055 | + +- "submitted, never paid" (1,681 segments) is the partition: records accepted into a chain that never settled them after 11:45Z. It is + the day's largest waste and is not a pipeline fault; it is the fault of the afternoon (the fleet record). +- "claimed, never submitted" (1,355): the chain step failed or the claim was abandoned. The failures are counted below. +- The 3060 tier completed no paid segment in 313 claims: at 12 GB the chain runs out of margin (its proving median on completed chains + is above the 4090's by the card's ratio, and a 4090 claimant finishes the same segment first), so the 12 GB tier is a miner, not a + prover, on this segment size. The 3060's 34 submitted segments were all after 11:45Z (never paid for the partition's reason). +- Wasted work is the end-to-end seconds of every claimed segment that was not paid; the fleet spent 254,000 card-seconds (70 card-hours) + on segments that did not pay against 14,800 (4.1 card-hours) that did. Before the stall the ratio was about 3 to 1 (the steals and + refusals below); after it, everything was waste. + +## Failures and retries + +- `RESULT seg N chain FAILED`: 900, median wall 2.7 s. 629 "NotFound: No such file or directory": the sm_89 floor tarball's + `igneum-prove-host` was a dangling link until the real host was served at 10:50Z (08:00 to 10:59Z, the fleet record's floor fault); + 264 "invalid string length" (the host's proof-bytes string on the 48 GB cards' larger segments); 4 OutOfMemory (12 GB cards). After + 10:50Z the NotFound class ended; the string-length class remains open for the node lane. +- `RESULT segment_refused`: 153. 62 "does not chain to segment N..N" (the previous segment's record moved under the claim), 54 "unproven: + the record is carried after the segment's deadline" (the chain step finished too late), 35 "segment already paid" (a faster claimant). +- Retries: 0 lines "record accepted on retry". The prover does not retry a failed chain; it drops the export and claims afresh. +- Failure rate on claims: 900 chain failures plus 153 refusals over 3,421 claims is 30.8 percent; without the floor-link class (fixed) it + is 12.5 percent. + +## Steals: a faster claimant takes an assigned prover's reward + +`RESULT paid_other`: 137 segments this box had claimed were paid to another key, 4.0 percent of claims (98 on 4090s, 25 on L40S, 8 on +3090s, 6 on the 6000 Ada). The time from this box's claim to the other key's payment read: median 306 s, p95 9,757 s (the long tail is the +same pause-and-resume as the payment column). The exclusive window (10 DAA seconds) does not hold a slow claimant's segment for it: a +second box that finishes its chain first is paid. The 3060 tier was never the winner and never the victim (it never finished). + +## Queue depth over time + +The worklist as the provers read it on idle passes, median entries per hour (tip in the line): 02Z 596, 05Z 596, 08Z 596, 11Z 713, 14Z +594. Bounded at about 600 entries (the 600 DAA unproven window times one entry a DAA) for the whole day; it did not grow, because a +segment leaves the list at its deadline whether proved or not. Growth would show the window itself lengthening; it did not. + +## What this means + +- With the floor link fixed, the pipeline's own stages are fast: inputs 2 s, verification and submission under 2 s, aggregation 23 s + (75 s on a 3090); the proving stage sets the pace, 27 s median and 216 s at the slowest 5 percent, and payment lands 171 s after + submission (543 s at the slowest 5 percent) when the chain settles. +- The waste is structural, not incidental: 70 card-hours wasted against 4 paid, dominated by the partition, then by the floor fault, + then by steals and late chains (13 percent of claims). Two changes would cut the pre-stall waste: a claim that is honoured for the + window it was granted (the steal rate goes to zero) and a 12 GB tier that claims only segments it can finish (the 3060's 313 claims + earned nothing). +- The next chain (igneum-devnet-4) starts this instrument from block zero; the two-hour window under the hold's declared workload is + the first measurement to run on it, with block timestamps read so the assignment wait becomes a real column. diff --git a/docs/bench-log.md b/docs/bench-log.md index 116de5fd2..687b97913 100644 --- a/docs/bench-log.md +++ b/docs/bench-log.md @@ -2819,3 +2819,129 @@ What the rows say. 2. The hot packs hold their rate under the lock far better than mx8: the 1,300 MHz lock costs mx8 7.5 percent of rate (137.7 to 127.3) and costs the hot packs 2 percent (hot32k4 147.4 to 144.4, hot64k8 164.2 to 160.9). The hot packs are bound by the table's latency, not by the core; the lock takes a third of the watts off every pack (319 to 215 W) and the hot packs pay almost no rate for it. 3. Per watt at the lock the hot family runs 0.52 to 0.73 MH/W against the control's 0.60: hot64k8 is 22 percent cheaper per hash than mx8 on this card, hot32k4 11 percent cheaper, the "a" packs 10 to 13 percent dearer. Whether a cheaper hash on the GPU is a gain or a loss for resistance is the research lane's call: it is a gain only if the saving comes from the memory path an ASIC would have to buy too. 4. The 5090's locked class v4 reading from the efficiency pass (1,300 MHz: 134.6 MH/s at 223 W, 0.60 MH/W) sits level with the mx8 control here (0.602), so the two passes agree on the control and the hot rows are comparable to the v4 grid. +## 7 October 2026, 10:08 UK: igneum-testnet-1 re-cut, the two-node 18-decimal gate (GPU form) PASS + +The re-cut testnet object (genesis `01294fd3...`, digest `80af8aa1...`, every switch on from genesis; `docs/plans/testnet-go.md` +"The genesis, re-cut") on igneumd 8a6f1f56... and igneum-miner 726cf290... (fork `testnet-genesis-2-node` f1717419), the +gate script `tools/fleet/base-unit-gate.sh` at 72b02b48, run by the fleet lane on a one-shot RunPod RTX 3090. + +| Check | Result | +|---|---| +| both nodes agree | 577 blocks, one sink, exec tips 0x1a5 and 0x1a5 | +| blocks mined in 600 s | 577 (421 chain blocks) against the minimum 60 | +| the UTXO side, last 30 blocks | identical on both nodes; 30 payload subsidies at the 18-decimal schedule, 0 wrong; 80/20 exact on 18 of 18 single-payee coinbases | +| the execution layer | balance equal on both nodes; 577 rewards against the schedule at each blue block's own DAA, 0 wrong; the sum of the rewards equals eth_getBalance: 4,617,536,546,296,296,296,298 wei = 4,617.53654629 IGN | +| the start-up lines | `Base unit: 10^18`, digest `80af8aa1...`, ladder active at rung 0, fees v1 from DAA 0, proof verification from DAA 0 under shard `0x2b1a81cb...` and aggregator `0x474678f3...` | + +Consequences: the layout, the switches and the bridge hold at 18 decimals on real GPU blocks; no tier changes (docs/design/base-unit.md +section 5 stands). The first run of the form read 165 of 561 rewards one ramp step low because the gate priced every reward at the +chain block's DAA while the object credits each merged block its own (subsidy_per_block_activation_daa 0): the script, not the node. + +## 7 October 2026, 11:12 UK: igneum-testnet-1 re-cut, the object at fast time (devnet-suffix, 5 nodes) PASS + +`infra/fast-time/testnet-object.mjs` run 10 on igneum-build-1 (the archive binaries, fork `testnet-genesis-2-node` 5c25c1fb; network +igneum-devnet-973 on the 60x profile with every switch of `infra/seed-nodes/testnet-object.json` from genesis, the fast-time finality +profile, leave delay 60; four voting CPU miners and one `--no-vote` key; 600 s, the leave at 240 s). + +| Check | Result | +|---|---| +| start-up lines, one digest | every node: ladder active at rung 0, fees v1 from DAA 0, verification from DAA 0 under the pinned ids, rule v3 and C1 from DAA 0, the leave rule from DAA 0 | +| class v4 at rung 0 | ten epochs, 27 shadow passes, no ladder bits on the chain, object byte 0 | +| the chain | 551 blocks, 525 chain blocks, 0 rejected, one sink on five nodes | +| finality | first lock at DAA 142 (172 s), lock 18 at the end, active | +| the signing bonus (UTXO side) | the silent key's 87 blocks at 72 percent of each block's own subsidy; the voters' 320 at 80 percent | +| the bridge identity | UTXO payments x 10^10 = execution credits for all five miners over the chain (the tip's own credit set aside) | +| the leave item | accepted at DAA 212, voters 5 to 4 at DAA 351 (within the delay and a window), longest pause after it 1 s | + +Consequences: a miner that stops signing while in the table earns 72 percent on both ledgers, never 80 on one and 72 on the other (the +N7 fix, c7ea1e21); a side block merged one DAA late is credited its own subsidy on both ledgers (the N8 fix, d840537b, from genesis); +a miner that leaves cleanly is out of every denominator an hour after its leave is carried on the testnet (60 DAA here) and holds +nothing; nothing changes for hash rate, power or any tier's hardware. + +## 7 October 2026, 14:36 UK: igneum-testnet-1 re-cut, the late-join gate (proof archive, ledger N9 second half) PASS + +`infra/fast-time/tn-late-join.mjs` on a one-shot RunPod 3070 pod (os-latejoin-ylp1), the fast-time join shape of ca3-v4-node e5f993d4 with +consensus proof verification and proving v0 from genesis in the override, a CPU prover beside node A (`infra/fast-time/tn-prover-loop.mjs`). + +| Side | Binary | Result | +|---|---|---| +| node A | archive binary 57ad7dc2... (fork 5c25c1fb, aea0ca5c in) | 6,297 DAA, 37 proofs carried and verified, 34 in the archive, pruning point at DAA 1,679 | +| B, known-failed first | 57ad7dc2... (before 70e4601e) | stalled at DAA 1,828 six times, "proofs this peer did not deliver in 20 s", while A held the file | +| B, the fix | fbed53cd... (fork 26e648ff, 70e4601e in) | headers-proof IBD completed, A's sink reached in 35 s, 4,618 headers, 0 errors | + +Consequences: with `proving_consensus_verify_daa` 0 from genesis a node joining igneum-testnet-1 after the pool's window syncs from the +pruning point and fetches every proof above it from any peer's archive (one 1.27 MB file per carried proof, kept for the pruning window: +108,000 DAA on the testnet, so about 30 hours of proofs, at most a few GB on a seed); before 70e4601e such a joiner never finished its +IBD. The fix is on `testnet-genesis-2-node` (26e648ff) and the node lane's `proof-hold-fix`; the 0.3.20 line takes it from there. + +## 7 October 2026, 15:19 UK: igneum-testnet-1 re-cut FINAL, the two-node 18-decimal gate (GPU form) PASS on the final object + +The final object (genesis `01294fd3...`, digest `4fbb2152...`, every switch on from genesis, the genesis forward-compatibility fields in; +`docs/plans/testnet-go.md` "The genesis, re-cut") on igneumd 58f96049... and igneum-miner 5625caee... (fork `testnet-genesis-2-node` +e6dd3afd), `tools/fleet/base-unit-gate.sh` 72b02b48, run by the fleet lane on a one-shot RunPod RTX A5000. + +| Check | Result | +|---|---| +| both nodes agree | one sink, exec tips 0x142 and 0x142 | +| blocks mined in 600 s | 322 chain blocks against the minimum 60 | +| the UTXO side, last 30 blocks | identical on both nodes; 30 payload subsidies at the 18-decimal schedule, 0 wrong | +| the execution layer | 491 rewards against the schedule at each blue block's own DAA, 0 wrong; the sum of the rewards equals eth_getBalance on both nodes: 3,929,111,342,592,592,592,602 wei = 3,929.11134259 IGN | +| the start-up lines | `Base unit: 10^18`, digest `4fbb2152...`, `igneumd/2.1.0-e6dd3afd`, genesis `01294fd3...` executed, chain id 4462 | +| the known-failed form | the 8-decimal schedule against the same chain: payloads wrong 30 of 30, rewards wrong 305 of 305, FAIL | + +Consequences: the cut's four gates are green on one object (this gate, the fast-time line of 11:12 UK, the late-join gate of 14:36 UK, the +suites); what the seeds' cut-over needs is the founder's go alone (the build-server lane's `wave1-0320.sh seeds` line is armed and dry-run clean on +these values). No tier changes: the base-unit costs of docs/design/base-unit.md section 5 stand, a Windows node needs igneum-prove-host +beside it, a miner that stops cleanly sends its leave, a silent key earns 72 percent on both ledgers. + +## 8 October 2026, 10:43 UK: igneum-testnet-1 on the 0.3.24 pin 5b673577, the two-node 18-decimal gate (GPU form) PASS + +The go object as landed (the 0.3.24 node pin 5b673577: the Devnet 3 object commit plus the 18-decimal re-cut; genesis `01294fd3...`, digest +`b2e856ed...`; `docs/plans/testnet-go.md` "The go object"), the gate artefact igneumd a3b1a2c9... and igneum-miner cfa9f5ca..., the script +`tools/fleet/base-unit-gate.sh` at 940d91de (`--nodnsseed` on both nodes), run by the fleet hand on a one-shot RunPod A5000 (pod 2 after a +3090 whose GPU was dead for CUDA). + +| Check | Result | +|---|---| +| both nodes agree | one sink, one exec tip | +| blocks mined in 600 s | 340 chain blocks against the minimum 60 (41.65 MH/s on the hive 0.3.24 CUDA worker) | +| the UTXO side, last 30 blocks | identical on both nodes; 30 payload subsidies at the 18-decimal schedule, 0 wrong; 80/20 exact on 20 of 20 single-payee coinbases | +| the execution layer | 512 rewards against the schedule at each blue block's own DAA, 0 wrong; the sum of the rewards equals eth_getBalance on both nodes: 4,097,208,879,629,629,629,622 wei = 4,097.20887963 IGN | +| the start-up lines | both heads on digest `b2e856ed...`; no public seed dialled | +| the known-failed form | the 8-decimal schedule against the same chain shape (420 s, 286 blocks): payloads wrong 30 of 30, rewards wrong 285 of 285, each by exactly 10^10; the sinks, tips and balances still equal between the nodes; FAIL | + +The fast-time line of the object on the same pair (six keys, 10:33 to 10:43 UK): 15 of 16 checks true (the stamped object byte 7 on every mined +block, class v4 at rung 0, the first lock at DAA 142 and lock 19 at the end, the bonus 72/28 on the silent key's 91 blocks and 80/20 on the +voters' 352, the bridge identity exact for all six keys, a leave accepted and effective within the delay, no pause after it); the one false +check was the harness's final read after its own miners had exited (fixed at b8074151); the re-run on b8074151 (10:47 to 10:57 UK) read +SUMMARY PASS on every check: 614 blocks, 492 chain blocks, eleven epochs at class v4 rung 0, the first lock at DAA 141, the silent key 72/28 on +89 blocks, the voters 80/20 on 377, the bridge identity exact for all six keys, a leave accepted and effective, one sink on six nodes. Consequences: unchanged from the +7 October entries; the object on the go line reads the same numbers as the re-cut it came from. + +## 8 October 2026, 16:18 UK: igneum-testnet-1 go object on the 0.3.25 line (acaf08b0), the three pod gates green, the seeds armed + +The day's line (`docs/plans/testnet-go.md` rows 9n to 9v): Devnet 3 crossed its class v5 floor clean at 12:57 UK; the node lane +re-cut the testnet object with class v5 from genesis (0d05e795, digest `1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f`, +byte 6, genesis `01294fd3...` unchanged); the coordinator moved the go seeds to the 0.3.25 node code (ba294c98); the pod gates then +found three defects in turn, each fixed on that line the same afternoon: the miner's class v5 state lookup wired to the devnet exec +port on every network (f41f48a7), no state stream after the genesis seed block (6e04f7fc), and the executor's sync wait that no +fresh chain could satisfy (acaf08b0, one rule with the cold-start deadlock: no guard waits on what only a block can produce). +Pod: RunPod 7e2jbcma9apjne (tn-gate-0324c), RTX A5000 secure, driver 570.211.01, USD 0.27/h, rented 14:50 UK, the fleet hand; +the earlier 0324c rent deadlocked on the fleet registry lock (killed by pid 15:48 UK) and left a stray 4090 pod destroyed at +14:51 UK (about USD 0.48). + +| Run | Pair | Result | +|---|---|---| +| Two-node 18-decimal gate, GPU form, 0d05e795 (relay 26790 to 28190) | igneumd a3b1... line's 0d05e795 `b76d8671...` | VOID, 0 blocks: the miner refused the genesis seed state (row 9v found) | +| Fast-time line at b5925261 (class v4 network), 0d05e795 | same | PASS 16 of 16, nodes stamping 7 (the harness's v4 gap, row 9u) | +| Fast-time line at c5fe28e4 (byte 6, `--exec-rpc` per miner), 0d05e795 | same | reproduced the genesis refusal on all six miners, no relay | +| Two-node gate, known-failed of 6e04f7fc, ba294c98 (script e88aa875) | igneumd `74ae96c6...`, miner `bbabfa91...` | FAIL as designed: the miner reached 28190 by the script's flag, no genesis stream, tip 0 | +| Two-node gate, 6e04f7fc | igneumd `18e7d223...` | NO BLOCK: the executor waited for a consensus sync a fresh chain never reaches | +| Two-node gate form 1, acaf08b0 (script b38f1ad3, no relay, 600 s) | igneumd `9e4217f3...`, miner `bbabfa91...` | PASS: the genesis stream published in the first follower pass, block one ACCEPTED 70 s after start, exec tip 327, 30 of 30 subsidies at 10^18, 80/20 exact 16 of 16, 502 rewards 0 wrong, balance 4017.16194444 IGN on both, votes 15/15, 3.07 MH/s wall | +| Form 2, GATE_EXPECT_DECIMALS=8, acaf08b0 (420 s) | same | FAIL as designed: checks 3 and 5 wrong by exactly 10^10 on every row, block one mined (tip 183) | +| Fast-time line at c5fe28e4 (byte 6), acaf08b0 (600 s, leave at 240) | same | PASS 16 of 16: epochs e0 to e9 class 5 rung 0, first lock 5 at DAA 143, six bridges true, leave 6 to 5, blocks 580 chain 452, rejected 0, one sink on six, object_bytes {6: 574}, refusals 0 | + +The seed-class go pair (build-server lane, build-1): `/srv/artefacts/0325-acaf08b0/seed/igneumd` `cb35df68...`, `igneum-miner` +`0b7e9d73...`; its bare start prints byte 6, 10^18, the digest, `igneumd/2.1.0-acaf08b0`, "genesis ... executed" and "the state +stream after genesis ... is published" with no sync wait; the third dry run on seed1, seed2 and seed3 rc 0 at 16:03 UK. The seeds +are armed; the go line is in the runbook and runs on the founder's own word. diff --git a/docs/build/compatibility.md b/docs/build/compatibility.md new file mode 100644 index 000000000..62ec3d3c5 --- /dev/null +++ b/docs/build/compatibility.md @@ -0,0 +1,80 @@ +# Compatibility, measured + +A GPU-secured network for Ethereum-compatible applications and verifiable computation. Compatibility is a product deliverable here, not a sentence: every row below is a test that ran against the devnet from the repository (`tools/reference-apps/compat/run.mjs`), with its evidence, and a row that could not run says so and why. Devnet, no value. + +Last run: not run yet. 0 passed, 0 failed, 0 untested. Sender none. + +Three boundaries hold for everything on this page: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. The four words included, executed, proven and finalised are defined on [/receipt](/receipt). + +## Representative contracts + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| an ERC-20 deploys (CREATE address, code at the address) | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| ERC-20 transfer: balances, the Transfer log, eth_call | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| ERC-20 approve and transferFrom | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| a probe contract deploys | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| a counter increments and persists | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Wallet fee estimation + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory shapes | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| a transfer: estimateGas against gasUsed | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| a contract call: estimateGas against gasUsed | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| the documented difference: a transfer sent with a local 21,000 limit | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Indexing + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| eth_getLogs by address, topic and range against the receipts | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| block, receipts and transaction lookups agree on indices | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Failed transactions + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| a revert: status 0, gas charged, nonce advanced, eth_call reason | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| an out-of-gas call | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Receipts + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| every Ethereum field, logsBloom from the logs, contractAddress on creation | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| the receipts trie root rebuilt equal to the header | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Application assumptions + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| block.number, timestamp, chainid, basefee, blockhash(n-1), msg.sender, tx.origin | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | +| CREATE2 address | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Differences: block context + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| block.coinbase is the including DAG block's miner | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Differences: randomness + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| block.prevrandao derives from the epoch seed, fixed per epoch | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## Differences: two-dimensional fees + +| Row | Verdict | What was measured | Evidence | +|---|---|---|---| +| the receipt's proving dimension and the fee split | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | | + +## What the differences mean for an application + +- Block context: `block.coinbase` is the miner of the DAG block that first included the transaction, so one chain block can carry transactions with different coinbases; code that pays or trusts `block.coinbase` as "the block producer" sees several producers per block. +- Randomness: `block.prevrandao` derives from the chain's epoch seed and holds for an epoch, so it is not fresh per block and must not seed a lottery or a commitment; use an application-level randomness source. +- Two-dimensional fees: every transaction pays execution gas and proving gas; the node folds the second into the gas it quotes, so a wallet that quotes from the node (eth_estimateGas, eth_gasPrice, eth_feeHistory) is covered and a wallet with Ethereum's constants (21,000 for a transfer) is not; the receipt carries the split under `igneum` (pgasUsed, provingBaseFeePerGas, burnedProvingFee, burnedExecutionBaseFee, minerTip). + +Source: `tools/reference-apps/compat/run.mjs` (the rows), `tools/reference-apps/compat/results.json` (the evidence), `docs/build/compatibility.md` (this page, rendered by `render.mjs`). diff --git a/docs/design/class-rotation-four-layers.md b/docs/design/class-rotation-four-layers.md new file mode 100644 index 000000000..513e8f18d --- /dev/null +++ b/docs/design/class-rotation-four-layers.md @@ -0,0 +1,202 @@ +# Class rotation, four layers: the hourly program, the weekly parameter era, the 180-day family epoch, the emergency miner vote + +8 October 2026, 14:1x to 15:30 UK, branch `class-v6-rotation` (worktree `igneum-wt-rotation` from the box mirror's master bfe7607a), the rotation lane under the Counter ASIC coordinator. The founder's order (14:3x UK, verbatim intent): "layer 1 the hourly change; layer 2 a weekly or monthly change; layer 3 the 180 day change; layer 4 emergency miner vote change. All automated." No release and no hand for any of the four once shipped. Inputs: the five research lanes' documents on `rotation-research` (build-3, 2f986d70: `docs/analysis/rotation/layer1-hourly.md`, `layer2-weekly.md`, `layer3-family-bank.md`, `layer4-miner-vote.md`, `other-layers.md`), each recommendation kept or rejected in section 8 with its reason; `docs/design/class-v6-rotating-family.md` (the per-tier rows, the band, the three rings); the release record's rules 16 to 19 on `ship-docs-0321` (`docs/plans/release-rules.md` lines 22 to 25, read by `git show`); the node at the mirror's `release-0.3.25-node` c9ad753a. Status: a design document and a research-class prototype on a fork branch behind a params switch (section 9); nothing here touches the devnet, Devnet 3, the testnet object or any served number. Labels: **measured** (a card or a box on a named job, with the clock), **modelled** (arithmetic on cited figures), **claimed** (a vendor's or an author's figure), **approximate**. + +Framing (the coordinator's word, 16:5x UK; Igneum 2.0 is the reference, `docs/plans/igneum-2.0.md` on the mirror): rotation is optional to the security argument, the four layers simplify to those with a distinct demonstrated benefit, and this document describes a CAPABILITY the chain has (what changes, from which chain value, under which rules, at what cost per boundary), never a resistance claim; it makes no claim that rotation strands any hardware, and where a chip row appears it says what a draw changes for a datapath or a firmware, labelled, and nothing about any product's life. The prototype of section 9 is kept as the no-rescue test's control. + +The founder's bar is "error free and future proof", so every guarantee below is named as what it is and nothing more: a **test** (a unit test that fires on a known-failed case), an **in-node rule** (an acceptance rule every node applies to every draw, deterministically), a **census** (an offline run over drawn eras that bounds a failure fraction at a confidence, never a proof), or a **fast-time crossing** (a three-node network crossing the boundary on the box, which shows the code path once, not every future draw). A claim resting on none of the four is marked owed. + +## 0. One page + +| Layer | Boundaries a year | What is drawn | From which chain value | What it may touch | What it may never touch | What makes the boundary safe (named as what it is) | What still needs a release | +|---|---|---|---|---|---|---|---| +| 1. The hourly program | 3,600 DAA s: **8,766** | the program: the instruction stream, the register init, the load sites, the shadow block's instructions | the epoch's reference block: the last selected-chain block below `3,600 e - 600` (the node's `epoch_seed`, class v5's `C_w`) | the program only | the dataset derivation, the read atom, the layout, the week's table, the family set | in-node rules (a) (b) (c) (a') (c') (c''') and the per-site tests of ring B, the 256-attempt cap then the verified last resort; a wrong program refused at packcheck and by every node's PoW check (`check_header` regenerates the program): test, the class v4 harness's stale-miner case | a new generator (the 64-bit `program_rng` state is one: layer1-hourly.md item 2, ledger M7) | +| 2. The weekly parameter era | 604,800 DAA s (7 days): **52.18** (monthly 30 days: 12.18, priced in 3.4) | the table the hourly draw reads: the op-mix weights (B = 4 on the seven injecting families, the lossy three at base), the shadow block shape in {64, 128, 256}, the stride multiplier M and rotation R, the index fold's constants (once the fold's form is in), the cross-lane shuffle pattern from a genesis-vectored set; NOT the mixer multiplier (a per-family axis), NOT W (a per-class pin, 4 words), NOT N (the ladder's signal), NOT the layout `pos` | the week's reference block: the selected-chain block at the greatest DAA at or below `604,800 w - 7,200` (two hours below the boundary), through the 1-hour VDF once live | the program's generator inputs only | the dataset derivation, the read atom, the dataset layout, the object digest, every activation height, the binary | ring A in the node (band membership, the lossy-share bound, the rotation class, the pattern index) in microseconds; the table judged by the first epoch's draw (over 32 attempts: the stream's next block, three blocks, then the genesis table, total and the same on every node): in-node rule with tests; the census bounds the redraw (0 of 3,000 band eras exhausted at 256, max attempt 59: measured, lane D 17:00 UK) | a wider band, a new pattern, a new base table | +| 3. The 180-day family epoch | 15,552,000 DAA s: **2.03** | structure from the genesis bank (section 4): the live reserve subset, the dataset atom from the bank's atom list, the fold form, the shapes admissible that epoch | the family epoch's reference block: the era cut, the last selected-chain block below `15,552,000 n - 7,200` (the node's `era_seed`; the era VDF over the cut's day once live), the same block the class v5 dataset's state is read at | the family set, the atom (within the bank's list), the admissible shapes | anything outside the bank; the read atom outside the genesis list (W = 4; 8 as `admissible: false` until its rows) | the node's own lead-ahead self-test on the coming object (section 6.2: a fast-time crossing per node), rule 18's feed check and rule 19's fingerprint pairing (section 6.3: in-node rules with their CI checks), the per-vendor 5 percent rule and four-vendor fingerprints per bank entry at genesis (tests), the stale-kernel refusal (test) | a family beyond the bank, a read atom or a derivation not in the bank (bank refresh: `bank_version` in the digest, entries added `admissible: false`, the 90 percent tally in epoch n effective at n + 2) | +| 4. The emergency miner vote | 0 expected; at most one bring-forward per scheduled epoch: **at most 2.03 extra** | nothing new: the vote names the NEXT scheduled family epoch's draw at a target height brought forward; the draw at that height is layer 3's from that height's reference block | the finality votes' carriers: a `FlipVote` item under its own tag in the coinbase finality section, read by Q2's block reading over the certified checkpoints | what layer 3 touches | what layer 3 never touches; and nothing can be delayed: a target at or past the scheduled height is dropped | two thirds of active weight AND half of total 30-day weight at every one of the last 240 of 720 consecutive checkpoint indices (in-node rule; tests on the fold); no vote counts while finality is paused; the flip at the first epoch boundary at least 14,400 DAA s after the tally closes; one bring-forward per family epoch | a trigger no bell can see (the detector is for people, section 5.1) | + +The three numbers the 15:45 close quotes. **Boundaries a year**: 8,766 / 52.18 / 2.03 / at most 2.03 extra (the weekly cadence is the default; the monthly alternative 12.18 is priced in 3.4). **The detector's false-positive rate on today's fleet rows** (section 5.1; layer4-miner-vote.md section 2, measured rows): as a trigger it is unusable, as a bell it rings a few times a year: signal A (a hash-rate step over 1.5x in a day) fired on 2 of the 14 days of the two crossing weeks on the record (4 October 152 to 280 MH/s when PC 2 joined, 1.84x in minutes; 6 October's 38-pod wave 1,748 MH/s onto about 1.16 GH/s), about **50 cases a year** at that fleet's behaviour (arithmetic on measured days, approximate); signal B (a clique of 3 correlated keys held 6 windows) read 0 cliques and 1 edge on the 6 October honest baseline (r 0.94 on two same-model 5090s, 4 ids, epochs 40 to 45, measured, `tools/observer/README.md`), and on a real network one candidate clique per few hundred ids from multi-card rental hosts (derived, approximate): **a few cases a year at today's key count**, never a consensus input; signal C has no on-chain form. **The vote window**: 720 consecutive checkpoint indices at 30 DAA s each = **21,600 DAA s, 6 hours of UK clock time at the 1 s block**, the pass line read at the last 240 indices (2 hours), the flip at the first hourly boundary at least 14,400 DAA s (4 hours) after the tally closes: **a carried vote flips between 10 and 11 hours after its first qualifying index** (on the fast-time file the window is 4 indices and the delay 60 DAA s; section 9). + +What this document does not claim: no layer moves the per-joule identity (`edge = (E_card + F) / (E_mem + k F)`, the research file's section 2): against the chip that stores the dataset every drawn value is firmware, the edge stays 3.6x at zero shadow, 2.8x at the sequencer core's k 0.56 and 2.1x at k = 1 on a 5090 at its knee (measured card, modelled chip; other-layers.md section 1), and the four layers decide which chip can be built and how long its tape-out lives. Layer 2's weekly cadence does not shorten layer 3's 180 days, so the close's amortisation unit for a chip project stands at 180 days; the week shortens the life of a FIXED-FUNCTION tape-out to a week, which the chip model prices at zero for the chip anyone builds. The read width stays pinned at 4 words (class v6 10.3) in every layer. + +## 1. The reference-block rule, one definition for every layer + +Every drawn value of every layer is a deterministic function of one chain block, the layer's **reference block**: for a boundary at DAA score `B` with the layer's lead `lead`, the reference block is the last selected-chain block whose DAA score is below `B - lead`, walking down from the header's selected parent (the node's `HeaderProcessor::epoch_seed` for the hour at lead 600 and `era_seed` for the era at lead 7,200, `consensus/src/pipeline/header_processor/processor.rs`; class v5's `C_w` is the same block for the hour). The draw's seed bytes are the VDF over that block where the VDF is live (the 10-minute class-group VDF for the hour, the 1-hour VDF over the cut's day for the era, spec 04 section 4.4) and the block's hash as the stand-in before (every network today). The week takes lead 7,200 like the era. Consequences, each named: + +- **Every node computes the same draw or no draw** (in-node rule; the fork's test `rotation_era_draw_is_deterministic_and_moves_with_the_reference`): the reference block is on the selected chain `lead` before the boundary, so a node that has the chain has the draw; a node that has not reached it keeps the old table and its blocks past the boundary are refused by every node that has (the stale-kernel class), at its own cost. +- **No accepted reorg replaces a week's or an era's reference block** (in-node rule resting on the merge-depth bound, 3,600 DAA s: a lead of 7,200 is two merge depths); the hour's lead of 600 is inside the bound, which is today's known behaviour (an epoch's seed block can move with a reorg before the boundary, and then it moves for every node together). +- **The one thing that would break it** (layer2-weekly.md section 2, taken whole): a draw that reads anything but the reference block. The tip (the 2720d8d2 fork made two views), a state root or record count (class v5's stale-node refusal, 86 of 86), the signal tally at a window's edge, a node's own DAA reading or the wall clock (the three lost floors of 8 October), a file. The design rule, enforced by the types in the prototype: the draw functions take the reference block's bytes and the genesis constants and nothing else. +- **The index never enters the draw bytes** (the era rule of igneum-pow: `E_n` commits to `n` through the VDF input), so a boundary's identity is its height, not its number. Test: `era_draw_deterministic_and_bounded` (igneum-pow) and the fork's `rotation_flip_moves_the_era_boundaries_and_rebases_the_schedule`. + +## 2. Layer 1: the hourly program + +What exists today is layer 1: `pow_epoch_blocks` 3,600 and `pow_epoch_lead` 600; the epoch seed from the reference block; the generator's draw with attempts `k = 0, 1, 2, ...`; the acceptance rules of sub-version 3 and class v5 ((a) stale source, (b) injecting write, (c) the dynamic test over 64 units, (a') the freshness fixpoint, (c') saturation per site, (c''') the distinct-item ratio floor 0.995 in the v5 tree); the cap `MAX_ATTEMPTS_V4` = 256 (exhaustion under 1e-45 per seed at two thirds rejection per attempt, modelled; 0 of 24,631 devnet seeds exhausted, max attempt 29, measured by the hash lane's census) and the verified last resort after it; the program id `program_id_class(generator, seed, attempt, class)` the miner's pack carries (packcheck) while the node regenerates the program from the seeds and refuses a mismatch as invalid PoW (`consensus/pow/src/igneum.rs`, `check_header`). Under rotation layer 1 changes in two ways only: + +1. **Its inputs come from layers 2 and 3.** The week's table and the family epoch's structure enter the generator as the class, so the program id carries them and a kernel built against another week or family set is refused exactly as a kernel of another class is. Test: the stale-miner case of the class v4 harness, re-run across a week boundary and a family boundary (section 9). +2. **The acceptance rule takes those inputs** (ring B): (c''') with the expectation divided by the width, the per-site largest-bucket bound in sigma and the per-site index-bit one-count in sigma on the same 2^20 pass (2.2 s per chosen candidate on a box core, measured), the window-bit test a refusal only once the index fold is in (on today's `load_index` it would redraw about 40 percent of epochs, lane D). In-node rules; the census's n (10,000 random and 3,000 band eras) bounds the failing fraction at 3.0e-4 and 1.0e-3 at 95 percent (measured, lane D). + +Kept from layer1-hourly.md (section 8): the hourly period stands (600 s costs the iGPU tier 20.7 percent of the epoch under load and puts the VDF core at 100 percent duty, measured on PC 1; per block is impossible at a 0.6 to 1.1 s prepare); the known-ahead window is 600 s at every epoch length, already the compile deadline an FPGA faces. What layer 1 never touches: the dataset derivation, the read atom, the layout, the table, the families. The cost per boundary is today's: the program compile per epoch (the miner's "program and cache ready" line, 13 to 42 ms measured on the 5090 and the M5 Max at 1 GiB), the verifier +0 ms, no re-tune (the hourly draw moves neither rate nor watts outside the band, measured, class v6 section 2). + +## 3. Layer 2: the weekly parameter era + +### 3.1 The draw (layer2-weekly.md section 1, taken; the mixer multiplier removed from this document's earlier draft on its reason) + +Week `w` is the DAA interval `[604,800 w, 604,800 (w + 1))`. One SplitMix64 stream seeded from `seed_words_from_bytes("igneum-week/" || V_w)` words 0 and 1 (`V_w` the VDF over the reference block's hash; the hash itself as the stand-in), drawn in a fixed order, every slot consumed whether used or not: + +| Slot | Parameter | Band (genesis) | Why that band (measured rows) | The node's test at the boundary | +|---|---|---|---|---| +| 1 | The op-mix weights (add, xor, mul, mad, shfl, rotl, sub, mulhi, rotr, or) | each injecting family perturbed by `below(2B + 1) - B`, B = 4, around the base table; or, mul, mulhi never above base; shfl never above 8; renormalised by largest remainder | the lossy-capped band reads r 0.595, mean attempt 1.47, max 59, 0 exhausted of 3,000 eras; with the lossy three free 1.2 percent of eras exhaust (measured, lane D); shfl is the dearest op (29.4 pJ at the lock, measured) | ring A: the lossy-share bound `or + mul + mulhi` at most base + B; the rotation class | +| 2 | The shadow block shape | {64, 128, 256} at 6,912 shadow instructions per iteration; the placement never moves | 64-instruction blocks 2.5 to 3.5 percent faster than 256 on the 5090 and the M5 Max (measured 6 October); 1,024 cost the M5 Max 17 percent | `is_family_shape` in the draw and the acceptance alike | +| 3, 4 | The stride multiplier `M = low32(next()) OR 1` and the rotation `R = 1 + below(31)` | the 1.13.1 address draws, moved from the era to the week | the index fold is what makes R drawable: without it 7 of 16 drawn eras carry a site at abs z 130 to 511 at address bit R (measured, lane D) | ring A records the rotation class; ring B's window-bit refusal on every candidate | +| 5, 6 | The index fold's constants | two draws, `1 + below(31)` and a 32-bit mask with the low `b` bits forced set | the fold's form is layer 1's open item; until it and its vectors are in, both slots are consumed and the genesis constants stand | the window-bit refusal; the known-failed case is lane D's 7 of 16 eras, which must read 0 of 16 with the fold | +| 7 | The cross-lane shuffle pattern | `below(S)` over a genesis-enumerated, genesis-vectored set (the butterfly's 31 xor masks and shfla's 31 deltas) | a pattern outside the vectored set is never drawn; the AMD `ds_bpermute` row is owed (layer1-hourly.md) | ring A: the index inside S | +| 8, 9, 10 | N, W, the mixer multiplier m | consumed, not read | N is the ladder's signal (an unconditional draw retires the Apple tier, -10 percent at 200,000, measured); W is a per-class pin (4; 8 after the owed rows; 16 never, +25 to +34 percent energy per hash on four cards, measured by floor lane 5); m is a per-family axis closed by adv-mixer-3's ladder and the x16 verifier row (11.4 ms loaded, over the 10 ms gate), the card pays nothing for it (x8 against x16 within 0.1 MH/s and 0.5 W, measured) so it is the verifier's budget and not a weekly knob | none | + +### 3.2 The acceptance at the boundary and the fallback (in-node rule; tests) + +Ring A on the drawn table in microseconds (band membership of every value, the lossy-share bound, the rotation class, the pattern index). Then the table is judged by the first epoch's program draw under it through ring B: if that epoch's program is not accepted within 32 attempts, the table is discarded and the next block of the week stream is drawn, every slot again in order, three blocks at most; after the third the fallback is the genesis table (the base weights, shape 256 x 27, M and R from the six-monthly era's own draw, the genesis fold constants, pattern 0) with no further check. Total, and the same on every node, because every input is the reference block and the genesis constants. Worst case 96 candidates, 211 s on a box core and 480 s on a 5 s core, inside the 7,200 DAA s lead (measured per-candidate cost, arithmetic). Odds: under the band the max attempt in 3,000 eras was 59 and the mean 1.47 (measured), so a block redraw fires in under 0.1 percent of weeks and the fallback in none seen; the exact count over 32 is owed from lane D's rows. The prototype's tests (section 9): a corner no draw can pass takes the base table at the cap on every seed (`rotation_era_draw_exhausts_to_base_table`, known-failed first); the genesis band accepts at attempt 1 on 2,000 references (`rotation_era_draw_accepts_at_attempt_1_under_the_band`). + +### 3.3 Why a weekly boundary needs no state agreement (layer2-weekly.md section 2, taken whole) + +The week reads one chain value (the reference block, through the VDF) and writes nothing. Untouched, with the record's reason for each: the dataset derivation (class v5's leaves under the day key, the item's 64 bytes, the mapping under the six-monthly `pos`): the read atom and the layout are what a stale node disagrees on; the object, its digest and every activation height: faults 1 and 2 of the crossing day (section 6.3) are exactly a digest and a height moving; the acceptance rule's code and the worker's class set: rule 19 and rule 16, the rule takes the table as INPUT and the worker carries every band value from genesis; the verifier's budget (m, W, the block count); the public feed's lock (rule 18 reads the same reference block the week does). A node that is behind reaches the reference block in order, computes the same table, accepts the same programs, with no message, no file, no sweep and no minute; the restart case of the fast-time harness already resyncs across a class boundary in 28.1 s (measured, cross-0324), and a week boundary is strictly less than that case. So the failure mode of a wrong week is a refused block at the drawing miner's own cost, never a two-sided chain: that is the sense in which layers 1 and 2 are "program only" boundaries. + +### 3.4 Boundaries a year and the cost per boundary (the close's units) + +| Cadence | Boundaries a year | A card with a lever (5090, 5070 Ti, 4070): Ember's re-tune per boundary | A card without one (9070 XT, every Apple machine) | Verifier | Chip | Label | +|---|---|---|---|---|---|---| +| Weekly (default) | 52.18 | 11 to 12 minutes at stock watts, about 15 s of hashing lost and 0.05 kWh (about 1 p) per boundary: 52 a year is 13 minutes of hashing and 2.6 kWh, under GBP 1 a year per 5090; the measured band says the point does not move (within 0.1 MH/s and 0.5 W at the lock across the mixer draw, 0.6 W across the three weight tables, 3.5 percent of rate across the shapes), so a 3-minute confirm replaces the re-tune | the 3-minute baseline, nothing lost | +0.2 to +1.5 ms per era draw on the epoch build; the daily build unmoved | what a draw changes for a chip: a wired lane ratio, block shape or fold is wrong from the first draw that leaves its value (a fact about the draw, not a claim about any product); a programmable part takes the draw as firmware; its verification burden the same three rings as a node, 3 to 9 s a week typical, 211 to 480 s worst | measured per boundary (the hash lane's rows), multiplied | +| Monthly | 12.18 | 3 minutes of hashing and 0.6 kWh a year | nothing | the same | the same, with 4.3x the use per draw-specific optimisation | measured, multiplied | + +Seven days, not thirty (layer2-weekly.md section 3, taken): the era length moves nothing on joules for a programmable chip and moves a draw-specific optimisation's planning window one for one; the honest cost is a re-tune no card needs. + +## 4. Layer 3: the 180-day family epoch and the bank + +### 4.1 The bank at genesis (layer3-family-bank.md, taken; this document's earlier "twenty entries" corrected to its count) + +The bank is what ships at genesis so that no family epoch ever needs a release: **18 op families** (class v4's ten: add, xor, mul, mad, shfl, rotl, sub, mulhi, rotr, or; the reserve R1 to R8 of `docs/plans/counter-asic-3-reserve.md`, ordered by hardware orthogonality: shfla, perm, popc and clz, bfe, shl and shr, sel, andn, mm8), **3 dataset atoms** (the mixer at x4 and x8, the derive program dr368), **1 fold form** with drawn constants, **3 block shapes** (64, 128, 256); x16, dr736 and W = 8 in the list as `admissible: false` from genesis (the ladder's flag shape, flipped only by the 90 percent path once measured). Each entry carries at genesis its emitter on every vendor, the conformance vectors of spec 1.15 with four-vendor fingerprints (Metal, CUDA, OpenCL on NVIDIA and AMD), the per-vendor 5 percent rule's measurement (class v6 4.2's table: shfla 1.91x per op on Apple, 1.53 NVIDIA; perm 1.13 / 1.30; mm8 emulated 1.6x per dot4; measured), and its price in chip k (shadow-k.md: mad 0.20, the ARX families 0.17 to 0.18, the fold 0.14, or 0.12, mul 0.082, prmt 0.056, mulhi 0.032; the shuffle, crossbar and tile rows owed). The entry rule is sub-version 3's acceptance under the entry's own shape, ring C's census (10,000 random and 3,000 band eras, 0 of 10^6 exhaustions per corner), the 5 percent rule, and the 10 ms verifier gate for atoms. Entries are never removed, so program ids stay decodable. + +### 4.2 The draw (structure from the bank, never content) + +The family epoch's reference block (the era cut) seeds one stream; five draws in fixed order: (1) the live reserve subset: during the reserve (epochs 1 to 8) entry `n` unlocks at epoch `n` with `W_new` = 4 points taken proportionally (spec 1.13.2, the slot consumed and unused); after the reserve, two entries live by a fixed cycle over the reserve whose phase the draw sets, so a retired family returns on a schedule a chip cannot wait out; (2) the atom from the bank's admissible atom list (the one draw of any layer that changes the dataset derivation); (3) the fold form's genesis constants (the week draws the values); (4) the admissible shapes; (5) the B = 4 band the week draws inside. The split with layer 2, this document's resolution of the two lanes' overlap: **the family epoch sets the structure (which families, which atom, which form, which shapes are admissible); the week draws the values inside it (the weights, the shape, M, R, the fold constants, the pattern).** 180 days aligned to the six-month era; the dataset floor's steps offset by 90 days (lane 3's schedule), so the chain has at most two boundary events a year of the costly class. On the chip timelines (layer3-family-bank.md section 4, claimed dates): 3 flips inside Kaspa's 22 months to the KS0, 6 inside Ethash's 36 to the E3, 7 inside Monero's 46 to the X5. + +### 4.3 What a chip must cover + +What the bank asks of a datapath (a capability statement, no claim about any product): to compute every bank entry (about 8 to 14 adders per lane, about USD 4 of N5 on a 14,000-lane array, class v6 4.2, modelled) and every atom in the bank, else a family's weight of the mix (4 points of 79) is computed by emulation at the measured vendor penalty (1.5x to 2.4x per op) on the day it goes live. The chip that survives any flip is the sequencer core (layer3-family-bank.md item 2): 3.1x the bare lane (6.9 against 2.2 pJ on ASAP7, synthesised), k 0.56 at the lock at N3 against the bare 0.18; so the layer's honest floor is a chip that is the GPU, unmoved against the memory system (GDDR7 2.8x at the knee, the SRAM die 4.7x, the M5 Max column 1.7x to 2.8x; modelled on measured cards), and the bank changes about 1.2x of edge over the bare floor and nothing for a programmable part. Under the 2.0 framing this is the layer's cost side; it is not offered as resistance. + +### 4.4 What a layer 3 or 4 boundary requires that 1 and 2 do not + +A family epoch can change the atom and the admissible shapes, so a node on the wrong dataset refuses every honest block: a two-sided chain, the DAA 198,000 class and this morning's crossing (section 6.3). The guards, each named: the node's own lead-ahead self-test (6.2, a fast-time crossing per node); rule 18's feed check and rule 19's fingerprint pairing (6.3, in-node rules with CI checks); the bank's conformance vectors (a test per entry per vendor); ban clearing (object-mismatch strikes not counted within one window of the flip, cleared at it; F23 untouched); the stale-kernel refusal (test). None is a proof that a future draw is right; the vectors are what say a family computes the same value everywhere. + +## 5. Layer 4: the emergency miner vote + +### 5.1 The trigger: the detector is a bell for people, never a consensus input (layer4-miner-vote.md section 2, taken; this document's earlier "6-sigma trigger" withdrawn on its numbers) + +| Signal | What the chain can read | Its false-positive price on today's rows | Its false-negative price against a disciplined chip fleet | Verdict | +|---|---|---|---|---| +| A: a hash-rate step beyond the fleet-tier envelope | the difficulty's implied rate; the envelope from 98 measured rows over 43 tiers (14.9 MH/s on a 2060 to 416 on a B200; consumer 0.08 to 0.58 MH/W; the 5090 99 to 123 MH/s, n 849) | the 4 October crossing stepped 152 to 280 MH/s in minutes (1.84x, measured); the 6 October wave put 1,748 MH/s on about 1.16 GH/s; a rule on a 2x day step fires on every day of both crossing weeks; a 20 to 30 percent daily swing is ordinary rental churn (approximate) | a fleet ramping 5 percent a week is under every honest swing; doubling a 1 TH/s mainnet is USD 3,500 an hour of rentals, inside the market (approximate) | a gate (no flip vote is worth raising under a 1.5x step in 30 days), never a trigger | +| B: share concentration and correlation of winning keys (`tools/observer/detector.mjs`: spread over 10 percent, band, early, nonce; a clique of 3 ids over r 0.8 held 6 windows) | blue-block share per key, residual-rate correlation, nonce law | the 6 October baseline: 6 pairs, max r 0.94 on two honest 5090s on one Windows schedule, 1 edge, 0 cliques (measured); a Vast 8-card host is a clique of 8 at r near 1 | a chip throttled into a card band (bandTol 30 percent), keys split, 10 percent per-unit jitter, randomised nonces: every test beaten for under 1 percent of its edge (modelled) | a bell | +| C: an efficiency signature in timing | the early-epoch share, template-to-block latency, nonce order | all three are shapes of the honest card (compile, fetch, counter) | a chip is on time and its nonce order is firmware; joules per hash never reach the chain | no on-chain form; the off-chain instrument is the bounty and benchmark | + +The number for the close: signal A about 50 cases a year at the record's fleet behaviour (2 of 14 crossing-week days, arithmetic, approximate); signal B a few a year at today's key count (derived from the one measured baseline, approximate); so an automatic flip on either would be griefable for under USD 1 an hour on devnet data and a consensus input the observer feeds. The signals decide when nodes SHOW a flip proposal with its evidence and when miners' signers offer their operators the vote; they never decide the vote. + +### 5.2 The vote (layer4-miner-vote.md section 3, taken; this document's earlier veto, day-long window and frozen-table denominator withdrawn on the reasons in section 8) + +- **The payload**: a `FlipVote` item under its own tag in the coinbase finality section (the Leave item's shape, tag 8, carried last so an older decoder stops cleanly; never a widened `Vote`, whose decoder dispatches on exact length): a BLS signature by a finality voter's key over `"igneum-flip-v1/" || chain_id || 0 || index || hash(C_i) || family_id || target_height`; relayed where votes are relayed. `family_id` is the next scheduled epoch's bank structure id; `target_height` an hourly epoch boundary. **A target at or past the scheduled height is invalid and dropped, so no vote can delay**; there is no veto because the scheduled epoch is a height and not a vote. +- **The tally** (in-node rule; the prototype's `vote_carries` with its tests): over 720 consecutive checkpoint indices (6 hours; 4 on the fast-time file), by Q2's block reading (a key's vote at index j counts when a block in the past of C_i carries it), weighted by W2 at C_i: the vote passes when at every one of the last 240 indices the summed weight of keys whose latest flip vote names the same `(family_id, target_height)` is at least two thirds of active weight (W2 times participation, Q3's first test) and at least half of total 30-day weight. Why both: the active test means silence cannot block (a key that stops signing leaves the denominator within a presence window); the half-of-total floor means an eclipsed minority cannot pass alone. Memoised per seed block like the class signal, so a fork has its own answer. No vote counts while `finality_active` is false. +- **The delay and the flip**: the first hourly boundary at least 14,400 DAA s (4 hours, the publish rule's own lead) after the tally closes; nobody fetches anything (the bank is in every binary that could vote); every node runs the lead-ahead self-test on the incoming structure and refuses to serve a template it cannot verify; Ember re-tunes once. UK clock: 6 hours of window plus 4 of delay, so a carried vote flips 10 to 11 hours after its first qualifying index at the 1 s block. The next scheduled epoch re-bases from the flip (the prototype's `era_index_with_flip`); one bring-forward per family epoch. +- **Every node deterministic**: the carried votes are chain values (carriers in the certified checkpoints' past), so every node with the checkpoints computes the same flip height and a node that joins later reads it from the blocks it syncs; a node synced from a pruning proof cannot tally below its pruning point and takes the schedule (owed, the class signal's same gap). + +### 5.3 The attack read + +| Attack | What happens | The read | +|---|---|---| +| A chip fleet at a third of weight blocking by abstention | it blocks every bring-forward while it holds a third of active weight; it cannot delay the scheduled epoch (a height); if it goes silent it leaves the denominator within a presence window and, at a third, pauses finality (3.11.3), which costs it its own locks | the vote adds no new threshold to buy: a third of active weight is a third of the 30-day blocks, the same third that pauses finality; the damage is bounded by the schedule's cadence (180 days), which no vote shortens | +| A chip fleet with majority weight | it is the finality problem itself (20 days of 100 percent hash to reach two thirds); it could carry a bring-forward, which only hurts a chip; it cannot delay | layer 4 is a lever for an honest two thirds and a cost to nobody else | +| A griefing vote (a two-thirds coalition flipping early for the cost to others) | one bring-forward per family epoch; each costs every honest miner one bench pass (minutes) and nothing else; a floor step's rate cost (4 to 10 percent per hash on the 5090 at 2 to 8 GiB, measured) only where the family carries one | worst case twelve re-tunes a year by a majority that wanted them; the coalition pays the same | +| A flip during a partition | no vote counts while finality is paused (C5, 3.9); a partition shorter than the lead heals before the flip; one longer has already paused finality on at least one side (3.7 item 9), so the vote is void there and the schedule stands; a vote carried before the split flips on both sides at the same height from the same reference block | the flip cannot be one-sided; today's Devnet 3 (14.7 MH/s, a handful of keys, two PCs on one schedule) could never pass one, which is correct: nothing on it has the weight to speak | +| A replayed or forged vote | the tag separates it from a checkpoint vote; `chain_id` stops cross-network replay; `index || hash(C_i)` expires it with its checkpoint; two flip votes by one key at one index naming different targets are equivocation under 3.6's evidence shape; forging is forging BLS12-381 | in-node rules with the finality suite's shape; a pool cannot vote for a member (no verifier, no vote) | +| A vote naming a height outside the window | ignored | in-node rule; test `rotation_flip_height_outside_the_window_is_ignored` | + +## 6. The exposure: a flip is a boundary + +### 6.1 The arithmetic + +A boundary is a height at which every node must compute the same new value or refuse the other side's blocks. Boundaries a year: layer 1 8,766, layer 2 52 (12 monthly), layer 3 2, layer 4 at most 2 extra. The exposure is the failure class a disagreement can cause times the count: + +| Boundary class | Failure if a node disagrees | Recovery | Boundaries a year | The exposure | +|---|---|---|---|---| +| Program only (layers 1 and 2) | the disagreeing miner's blocks are refused by every node with the reference block; the chain does not fork | automatic: the miner's next template after its node catches up | 8,818 | 8,818 chances a year of one miner losing one epoch's blocks; zero of a two-sided chain, because no agreement beyond the reference block is needed and every node already agrees on that | +| Structure (layers 3 and 4: the atom, the admissible shapes, the family set) | a node on the wrong dataset refuses every honest block: a two-sided chain | the losing side's execution reset and a deep reorg; nothing automatic beyond the merge-depth bound | 2 to 4 | 2 to 4 chances a year of the costliest class; this is why layer 3's cadence is 180 days and not 7, and why layers 1 and 2 are forbidden the derivation and the atom | + +The layers are split by exposure class, not by cadence: a weekly boundary is cheap because it is program only, and a family boundary is rare because it is not. Putting the atom under a weekly draw would be 52 chances a year of the two-sided class against 2. + +### 6.2 What a layer 3 or 4 boundary requires: the node's own fast-time crossing self-test + +Before every family boundary (scheduled or voted), from the reference block on, every node crosses the boundary against itself in fast time: it derives the coming structure from the reference block, generates the new epoch's first program and packchecks it against its own generator, runs the 96 vector lanes and the 2^24 fingerprint of each live family against the bank's table, builds the dataset head under the coming atom, captures and persists the day stream at the cut, and only then prints the family line and serves the new template at the boundary. A node whose self-test fails keeps the old structure (its blocks refused from the boundary, at its own cost) and reports the failure home with the reason shown (the plug, tune, play rule). This is a fast-time crossing per node: it shows this node can cross; the reference block and the vectors are what say every node agrees. + +### 6.3 The four crossing faults and rules 16 to 19 (the release record on `ship-docs-0321`, `docs/plans/release-0.3.22.md` section 25 and `release-rules.md` lines 22 to 25, read today) + +The four faults of the class v5 crossing on Devnet 3 (12:48 to 13:30 UK, 8 October), each a boundary where nodes had to agree on something beyond the chain's own blocks: (1) every fleet miner's worker ran generators 2 to 4 only, so the chain made no block for 9 min 26 s at DAA 68,400 (rule 16: every shipped worker prepares the live epoch before the cut; a package is checked by whether its worker can prepare the new class, never by its packs' presence); (2) container OOM kills and a proof map without a window (rule 17: memory read against the container's cap, never the host's; anything held per received item needs a window); (3) the re-walking node's chain-id refusal and its misbehaviour strikes (a mismatch between the network's own ids is a refusal, never a strike); (4) the public feeds read build-1's observer in a drifted one-peer cluster, so the public saw the chain dead from 12:59 UK while the chain ran (**rule 18, the feed check**: "every public feed names its source node and reads it only while that node's hash and state root at the current epoch's reference block equal the network's; on a mismatch the feed fails over to the next listed node and says so"). A fifth, behind **rule 19, the fingerprint**: a gate artefact built from uncommitted igneum-pow edits ("the pairing is a fingerprint, not a path": every node and miner binary carries the fingerprint of the igneum-pow tree it was built from; the build fails when it differs from the pinned freeze; the read-back prints it beside the commit; the handshake carries it and a node refuses a peer whose fingerprint differs; `tools/ci/pow-fingerprint-check.sh`). Under rotation: rules 16 and 19 are what make "the bank is in every binary" a checked fact rather than a hope (the worker prepares the coming structure, the fingerprint pairs the bank); rule 18 reads the same reference block the layers draw from, so a feed right about the lock is right about the week and the epoch; and layer 2 has none of the four faults' shape by construction (3.3), which is the research lane's proof that the weekly boundary needs no state agreement. + +### 6.4 Two more faults of the crossing day, refused by construction and carried into the crossing test (the coordinator's word, 14:5x UK; the mechanics from the node lane's reading, 15:0x UK, cited here by lane) + +| Fault | What happened (the node lane's mechanics) | The rule | Where it binds in the four layers | What the fast-time crossing asserts | +|---|---|---|---|---| +| (6) The epoch 20 boundary stall (Devnet 3, 13:03:41Z) | the class v5 check (`consensus/pow/src/igneum.rs:156`) refuses a header whose epoch state this node's executor does not hold; (a) the relay flow counts every PoW-check `Err` as a PoW cache strike, so the fleet's nodes, executors behind epoch 19's seed block, banned build-1's seed ("230 PoW cache strikes within an hour (limit 2)", 12:56Z), and in IBD the same refusal is `protocol/flows/src/ibd/flow.rs:1127`; (b) the template needs the same state, so at DAA 72,000 no mining node's executor had passed epoch 20's seed block and no epoch 20 template existed: the chain stood at the last epoch 19 block | a refusal for missing state is never a strike (the `Err` carries a missing-state kind the strike counter skips, the header is parked and retried, the peer keeps its standing); a node's template waits for its executor past the epoch's seed block and says so (a line, never silence). No fix exists yet; the record names it as the next node line's item | every boundary of every layer is a template-build event, the hour included (epoch 20 WAS an hourly boundary), so this is a layer 1 rule first and layers 2 to 4 inherit it; under class v5 every boundary reads state at its reference block | at the epoch cut a node whose executor is held below the cut prints the :156 line, never appears as "PoW cache strikes" or "banned" in its peer's log, and the chain advances on the peers whose executors passed the cut: the absence of a strike in the peer's log is the read; the harness's per-second `getBlockTemplate` keeps answering on every node at every boundary crossed (a failed template call at a boundary fails the run) | +| (7) The cold-restart deadlock (13:25Z) | `igneum/exec/src/service.rs` `follow_once`: a node with nothing executed (its snapshot refused by the 0.3.25 digest stamp) hit the 6 October sink-age guard (sink older than 10 minutes: "waiting for consensus to sync before the executor starts"), retried every pass; with the chain stale (fault 6) every restarted node waited, class v5's check needs the executor, so none could validate or mine and no sink ever freshened: a network-wide deadlock | a node holding the chain from genesis replays whatever the sink's age. Fixed in place: f8da7515 on `release-0.3.25-node` (both mirrors; no digest change): `cold_start_replays(sink_age_ms, holds_chain_from_genesis)`, `Err` (the wait) only for a node that has synced nothing or whose retention root is above genesis, `Ok(true)` when the sink is stale but the node holds the chain from genesis, printing once "exec sync: the sink is N s old but this node holds the chain from genesis ... replaying from genesis whatever the sink's age"; test `cold_restart_tests::a_node_holding_the_chain_from_genesis_replays_whatever_the_sinks_age` (the pre-fix refusal asserted first) | layers 3 and 4 are the only boundaries that touch state, so their crossing test carries the cold-restart case; the prototype's fork branch is fast-forwarded onto f8da7515 | `--cold`: after the era boundary every node is stopped by its pid, left down over 10 minutes, its exec snapshot removed, and restarted from its kept datadir; on f8da7515 each node holding the chain from genesis prints the cold-restart line within its first follower pass and its executor tip climbs; on c9ad753a each prints the wait line every 60 s and the tip stays 0 (the known-failed binary); `--restart` (one node, a young sink) is the lighter case | + +## 7. What each guarantee is (the founder's bar: never claim more) + +| Claim | What it rests on | What that is | +|---|---|---| +| Every node draws the same value at every boundary | the reference-block rule; the stream's fixed order | in-node rule; tests in igneum-pow and the fork (section 9) | +| No week's table leaves the band or exhausts | ring A; the three-block redraw and the genesis table | in-node rule; the fork's two known-failed tests; the census bounds the failing fraction at 1.0e-3 at 95 percent (measured), never a proof | +| Layers 1 and 2 cannot split the chain | they never touch the derivation, the atom or the layout | a design rule the types enforce (the prototype's `EraDraw` has no derivation field) and the record's reading of the four faults (6.3) | +| A family boundary is crossed clean | the self-test, rules 16 to 19, the vectors, the ban clearing | a fast-time crossing per node plus in-node rules; the three-node crossing on the box shows the path once | +| A vote cannot carry one-sided or delay anything | the active and half-of-total tests; no vote while finality is paused; a target past the schedule dropped | in-node rules resting on the finality rule's own guarantee (sim v2: 0 conflicting locks in every partition scenario, measured in the simulator); the 720-index window against the sim is owed (layer4-miner-vote.md section 7) | +| The detector's false-positive rate | the two crossing weeks and the 6 October baseline | measured days, arithmetic; the multi-card-host clique rate is derived and owed (one 8x Vast box for an hour measures it) | + +## 8. The research lanes' recommendations, kept or rejected + +| Lane | Recommendation (its five lines, shortened) | Kept or rejected | Why | +|---|---|---|---| +| layer1-hourly (34f95b6e) | (1) keep the hourly period; (2) close the 64-bit `program_rng` entropy cap with ledger M7's standard-hash stream; (3) add the warp-uniform block select, the register-file width draw and the full-permutation shuffle pattern; (4) never draw per-lane branches, the placement or N; (5) the refusals per failure mode | (1) KEPT; (2) KEPT as a generator change, so it rides a class cut and is named in section 10 as what a release still carries; (3) the shuffle pattern KEPT in the week's draw (slot 7) behind its AMD row; the block select and the register width REJECTED for this document (research, class v6 7c's layers 6 and 7; their censuses are owed); (4) KEPT; (5) KEPT | (2) is the one finding ProgPoW's audit made and it costs zero GPU; (3)'s two extra dimensions move nothing on the identity and their Apple compile footprint is unmeasured | +| layer2-weekly (234c9067) | (1) five draws, never m, W, N or `pos`; (2) the three-ring acceptance with the 32-attempt judgement, three blocks, the genesis table; (3) no state agreement, the one thing that breaks it; (4) seven days; (5) the precedents | ALL KEPT; the mixer multiplier removed from this document's earlier draft of the week's draw | m is the verifier's budget (1.86x per doubling, measured) and a per-family axis; the lane's reading of the four faults is the proof section 3.3 needed; the prototype's chain path folds the week's reference into the era seed, which this round redraws `pos` as well (section 9 says so and what the generator entry must split) | +| layer3-family-bank (fa5482d1) | (1) the bank's count and entry rule; (2) the sequencer core as the chip that survives; (3) the flip as a state-agreement boundary with the self-test, rule 18, rule 19, ban clearing; (4) 180 days aligned to the era, floor steps offset 90 days; (5) a release stays for a family beyond the bank, W = 8, a new derivation; bank refresh at n + 2 | ALL KEPT; this document's earlier "twenty entries" and "R0 derivation variant" corrected to the lane's 18 + 3 + 1 + 3 (there is no R0 in the spec) | the overlap with layer 2 (both draw B = 4 and the shape) resolved in 4.2: the epoch sets structure, the week draws values | +| layer4-miner-vote (c2e8ecd0) | (1) the detector never flips anything; (2) opt-in bring-forward at two thirds of active weight, no veto; (3) its own tag, 720 checkpoints, the half-of-total floor; (4) the flip at the first boundary 14,400 DAA s after the tally; (5) the site line | ALL KEPT; this document's earlier veto, day-long window, frozen-table denominator and 6-sigma trigger withdrawn | a veto is a delay lever handed to the fleet the layer exists to remove; the active denominator is what stops silence blocking; the detector rang on two honest 5090s | +| other-layers (2f986d70) | KEEP the floor's composition rule (the state read at the era cut only; a vote never lowers the floor); HOLD W in {4, 8} behind the PC 1 row; KEEP per-tier census and RISC Zero as genesis instruments only; KILL randomised epoch lengths, a sealed reserve class, VRF or beacon draws, per-block placement, per-tier shadow, the detector-armed hold, a drawn verifier budget, the kernel-fetch tell | ALL KEPT as verdicts; the Qubic read (a captured third blocks only the bring-forward; the 95 percent signal form is blocked from 5 percent of blocks) carried into 5.3 | a sealed class cannot be censused, and an uncensused class is the liveness risk the record measured (0.986 to 0.990 rejection on the per-load form) | + +## 9. The prototype (research class; never a chain path without the switch) + +On the fork branch `class-v6-rotation-node` (worktree `vendor/igneum-node-rotation` from the mirror's `release-0.3.25-node` at c9ad753a, the class v5 freeze tree `igneum-pow-v5` beside it under the untracked paths override) and `class-v6-rotation` (the harness and this document). What is built this afternoon, each piece named by what it shows: + +- **Params**: `rotation_v6_activation_daa` (the switch; `u64::MAX` = never on every network; the digest arm entered only when set, so a binary carrying the field peers with one that does not), `rotation_era_daa` (layer 2: 604,800; 10,080 on the 60x file; 180 in the harness), `rotation_vote_window` (layer 4: 720 checkpoints; 4 in the harness), `rotation_vote_delay_daa` (14,400; 1,440 at 60x; 60 in the harness); each on `Params` and `OverrideParams`, the `From` and `override_params` lines, a key in `override-60x.json`. Layer 3 rides the existing 180-day era (`pow_era_blocks`, 420 in the harness). +- **The schedule as pure functions** (`consensus/core/src/igneum/rotation.rs`): `weekly_index`, `weekly_reference_score`, `fold_era_seed`, `draw_era_params` with ring A's loop and the base table, `draw_family` from the bank, `vote_carries`, `flip_height_admissible`, `era_index_with_flip` and `era_start_with_flip` (the era clock `pow_era_index` and `pow_era_seed_score` now read the installed flip). Tests first, the known-failed ones first: `rotation_era_draw_exhausts_to_base_table`, `rotation_vote_one_of_three_does_not_carry`, `rotation_flip_height_outside_the_window_is_ignored`, then the accepting cases and the determinism cases (ten tests; the box's result in the SUMMARY). +- **The chain path, behind the switch**: the week's reference block folded into the era seed the generator consumes (`fold_era_seed`), so the address draw changes weekly and a kernel of the old week is refused at packcheck and by every node's PoW check; the node's era line and family line at each boundary; the template unchanged in shape (the harness reads `eraIndex` and `eraSeed` from `getBlockTemplate` and the node's lines). Honest limit of this round: the fold redraws M, R AND the interleave `pos` (the week's slot list says M and R only; splitting the stream so `pos` stays with the era is the generator entry the next round adds in igneum-pow, a research build with the freeze check named on its start line); the weights, the shape and the pattern are drawn and accepted in the module and enter the program only through the folded seed until that entry exists. +- **The vote**: the `FlipVote` item (tag 8, the Leave shape, carried last), its ingest with carriers, the tally at every lock (two thirds of active and half of total over the voters whose record has a carrier in the checkpoint's past and an index inside the window), the fold over the last N consecutive locks in `evaluate`, `install_flip` when it carries and the schedule admits the height, the node's flip line; the installed flip persisted in the finality state and re-installed on load (a restarted node would otherwise compute the plain schedule and refuse its peers' blocks: fault 7's class for any schedule state that is not a pure function of the chain); the miner's `IGNEUM_ROTATION_VOTE=` (devnet only, the `IGNEUM_CLASS_SIGNAL` shape) appending the signed item to its vote submissions from a named epoch. +- **The fast-time run** `infra/fast-time/class-v6-rotation.mjs` on build-3 through `tools/fast-time-remote.sh` at normal priority (nice, bounded cores): three nodes, three CPU miners, the 60x file with the week at 180 DAA, the era at 420, a vote from epoch 2 naming 660, window 4, delay 60; one run crosses hourly boundaries, week boundaries, the scheduled era boundary at 420 and the voted flip at 660, and passes only with zero refused blocks on every node, the sinks and counts equal, every node's era, family and vote lines equal, the program ids equal across the three miners at every epoch, a template served on every node at every boundary (fault 6) and, with `--restart`, one node restarted from its kept datadir after the era boundary re-synced to the others by the end (fault 7); the known-failed cases (`--voters 1 --expect flip` must report FAIL; `--expect off` must show no rotation line) first; the four cases run side by side on one box under one `fast-time-remote` run (`class-v6-rotation-cases.sh`, each on its own `--slot` of ports, suffix and data dir, at nice 19). Every process by pid file. The SUMMARY by 18:30 UK with the numbers. + +### 9a. What the prototype's crossing showed (build-3, runs 1 to 4, 15:0x to 16:2x UK; the record under `infra/fast-time/out-v6r*`; every number from the harness's summary or the nodes' own lines) + +The network: three nodes, three CPU miners, the 60x file with class v4 from genesis, the week at 180 DAA (the merge-depth lead 60), the family epoch at 420 (the era's own lead 30), a vote naming 720 from every voting miner's first checkpoint vote, the window 4 locks, the delay 60 DAA; the CPU bits 4x easier than the devnet's so twelve nice-19 miners on a box at load 20 to 40 make about 1.2 DAA a second; four cases side by side, 900 DAA each (16 hourly epochs, 5 week boundaries, 2 family boundaries). + +| Case | Verdict | What it showed | Label | +|---|---|---|---| +| `--expect off` (the switch never) | PASS (run 2; run 4 the same on every check but the timeout line below) | the node prints its off line, no week or family line, 300 blocks on three equal sinks, 0 refused | measured, run 2 | +| `--voters 1 --expect flip` (known-failed first) | FAIL as required (runs 1, 2, 4) | one key of three signs 41 to 50 of 120 weight at every lock ("short" on the tally line), no flip line on any node, the family epochs on the schedule (420, 840), 0 refused by any node, sinks equal, 900/900/900 | measured, run 4 | +| `--voters 3 --expect flip` | the vote carried at lock 15 (daa 449; 11 contiguous passing locks, share 10,000 bps) on all three nodes at the same lock, the family epoch brought forward to 720 (the family line "from reference block ... (daa 690)" on every node), the schedule re-based (the next boundary 1,140, not 840), 0 refused by any node at every one of the 16 hourly, 5 weekly, the scheduled and the voted boundary, sinks equal, 900/900/900; every check PASS but `zero_rejected_by_miners`, whose one line is a miner's submit RPC timeout on the loaded box (run 4) | measured, run 4 | +| `--voters 3 --expect flip --cold` | the cold-restart line of f8da7515 on all three nodes after 660 s down with the exec snapshots removed ("the sink is 669 s old but this node holds the chain from genesis ... replaying"), no wait line; the rest as the flip case (run 2's read; run 4's summary in the SUMMARY) | measured, runs 2 and 4 | + +The three faults the runs found in the prototype, each fixed the same hour and each a rule for the design: (1) the flip tally excluded a key whose latest vote index was above the locking index (the miner votes ahead of the lock): the latest vote counts whatever its index; (2) a flip vote reaches other nodes only inside the block that first carries it, so on every other node a key's record stays at its first index: a carried vote STANDS until the key names another target, the window is the consecutive LOCKS that pass and the carrier-in-past test is the binding (an expiry of one weight window is the next round's item; the finality gossip could carry flip votes like checkpoint votes); (3) the brought-forward boundary lived in a process-wide static and a restarted node would have computed the plain schedule and refused its peers' blocks: the installed flip is persisted in the finality state and re-installed on load (fault 7's class for any schedule state that is not a pure function of the chain). Two facts about the test network, not the design: class v5 at genesis needs every node's executor (the state stream for the PoW check and the prepare), which the fast-time file cannot give, so the crossing runs on class v4; and on the 60x file the merge-depth lead is 60 DAA, so a week's reference block sits a third of a week below its boundary (3,600 of 604,800 on the devnet). + +## 10. The "automated" claim for the site, stated honestly + +Once shipped, the chain changes its own hash on four clocks with no release and no hand: every hour a new program, every week a new table for it, every 180 days a new family set from the bank written into the chain at genesis, and in an emergency the next family set brought forward by a vote the miners carry in the finality votes they already sign. Every change is drawn from a block the chain already agreed on, checked by the same rules on every node, and refused at the boundary by every node if a miner gets it wrong, so none of the four can split the chain by a bad draw; the team holds no key, no switch and no date, and the detector every node shows is a warning light, not a switch. What still needs a release: a family the genesis bank does not hold, a read width or a dataset derivation outside the genesis list, a wider band, a new generator (the 64-bit stream's successor is one); the automation rotates what genesis shipped, and nothing it did not. + +## 11. Unverified and owed + +- Lane D's count of band eras over 32 attempts (the week's redraw rate: under 0.1 percent by the max of 59, the exact figure owed). +- The 720-index window against `sim/finality_v2.py` under the F2 eclipse and the bought-keys case (finality lane); the clique test's false-positive rate on an 8-card rental host (one Vast box for an hour); the 14,400 DAA lead against a family change on AMD and Apple (bench lane, PC 1); the pruning-proof node's tally (node lane). +- The AMD `ds_bpermute` row for the shuffle pattern; the Apple compile footprint of layers 6 and 7. +- The generator entry that splits the week's slots from the era's (section 9); the index fold's form and vectors; the 2,880-era harness case with a restart across a week boundary from a kept datadir. +- Every chip figure is the chip model's; no chip has been measured. diff --git a/docs/design/class-v6-rotating-family.md b/docs/design/class-v6-rotating-family.md index 872ad1e44..7835bca89 100644 --- a/docs/design/class-v6-rotating-family.md +++ b/docs/design/class-v6-rotating-family.md @@ -89,7 +89,7 @@ Reading: layer 2 does not move the chip anyone builds, because a chip buys DRAM ### 3.3 Per tier -The hash lane's VRAM rows (12:0x UK, modelled from the measured 0.4 GiB working set plus about 0.5 GiB of driver and app): the dataset needs 3.2, 5.4 and 9.9 GiB of device memory at the floor, 2x and 4x; a 12 GB card falls off at about 9.5 GiB (year 15 on the 1.13.3 schedule), a 16 GB GPU at about 13.5 GiB (year 23), a 16 GB unified Mac at about 8 GiB (year 12), the 5090 at about 29 GiB (year 54). **The DRAM-read cost per hash on the NVIDIA cards is NOT size-independent at the knee, MEASURED (the hash lane's kit b, PC 1, 12:49 to 12:58 UK, the pinned class v3 program 73bcbfe8 at 2, 4 and 8 GiB against the 1 GiB control 137.65 MH/s at 312.2 W unlocked and 127.39 at 212.6 W at the 1,300 MHz lock; 250 batches per row, fingerprints PASS): unlocked 133.86 at 315.7 W (-2.8 percent), 132.42 at 317.2 (-3.8), 131.75 at 319.2 (-4.3); at the lock 121.14 at 210.3 W (-4.9 percent), 113.06 at 204.5 (-11.2), 109.39 at 201.6 (-14.1); MH/W at the lock 0.599, 0.576, 0.553, 0.543, which is 4 / 8 / 10 percent more energy per hash at 2 / 4 / 8 GiB.** The lane's earlier reading (2 MiB pages keep the TLB's reach past 8 GiB) holds unlocked, where the card hides most of the page-walk term in its slack; the latency-bound regime at the lock exposes it. **The genesis floor itself, 5.5 GiB, MEASURED on a rented 5090 at stock (the fleet hand, RunPod secure, driver 570.195, 15:19 to 15:23 UK, the ca3-ds55 kit's own worker, program 73bcbfe8 in both packs, 250 and 500 x 2^24, every row PASS with 96 of 96 vector lanes): the 1 GiB control 141.48 MH/s at 325.6 W (2.30 microjoules; memory.used peak 1,914 MiB) against ds55 136.56 at 305.3 W busy, 327.6 steady (2.24 busy, 2.40 on the steady watts; peak 6,522 MiB: the 5.9 GB dataset plus the 268 MB cache plus the context), fingerprints stable across both passes (ds55 23ced07a4d28b465 becomes the pin). So the 5.5 GiB floor costs 3.5 percent of the rate at the same watts, about 4 percent more energy per hash, and the non-power-of-two mapping (1,476,395,008 words, 92,274,688 items, loads as (src x words) >> 32) is not a cliff on sm_120. Caveat: this host's 5090 plateaued at 328 W on both packs (a host power cap; another host's 5090 pulled 443 W on class v5 genesis this afternoon), so the microjoules are capped-card numbers and the rate and fingerprints are the row.** Lane 3's reading of it for the schedule (2a61cb46, 15:25 UK): the step lands between the 2 and 4 GiB stock rows (2.8 and 3.8 percent), so the non-power-of-two floors of 5.5 / 8.5 / 11.5 cost nothing beyond the size and the multiply-shift mapping is safe to adopt at the v6 epoch; per tier the 5.5 GiB step costs a 5090 4 percent per hash at stock (measured) and about 9 at its knee (interpolated from the 2, 4, 8 GiB knee rows); the 8 GB tier's fate at that step is the RX 7600 reading from PC 1 (about 16:00 to 16:30 UK, an amendment; its 1.8 GB of headroom is the question), the 5.5 GiB knee row with it; the SRAM store at that step is 3 reticles, USD 1,500, its joules unmoved. So each step of the schedule costs a tuned 5090 about 4 to 5 percent per hash while the chip's joules do not move (floor lane 3: its ticket goes USD 1,500 / 2,500 / 3,000 at 5.5 / 8.5 / 11.5 GiB), and every chip edge against a card at its knee rises by 4 to 11 percent across the schedule; the honest sentence for the schedule decision is USD 1,000 of chip ticket per step for about 1 to 5 percent of the tuned 5090's energy and about a quarter of today's measured cards by count. **On the M5 Max it is not size-independent, measured by this lane at 10:40 UTC under the Mac's measure lock (Metal packbench, the hash lane's class v3 packs at 2^28 to 2^31 words, the same seed and era, 3 batches of 2^24, vectors 3 of 3 and fingerprints per pack): 26.48 MH/s at 1 GiB (footprint 1,664 MiB, the build 32 ms), 23.26 at 2 GiB (-12.2 percent; 2,688 MiB; 54 ms), 21.31 at 4 GiB (-19.5 percent; 4,736 MiB; 94 ms), 20.61 at 8 GiB (-22.2 percent; 8,832 MiB; 193 ms).** The Apple GPU's dependent random read costs more time as the working set grows past its page reach (approximate reading: a TLB-reach effect on unified LPDDR5X; the power channels were not sampled this run, so the joules per hash move by at least the rate's share), which is a real per-tier cost of layer 2 that the NVIDIA model does not show: at an 8 GiB floor the Apple tier mines 22 percent slower per card than at 1 GiB, before any memory limit. The table below carries it. +The hash lane's VRAM rows (12:0x UK, modelled from the measured 0.4 GiB working set plus about 0.5 GiB of driver and app): the dataset needs 3.2, 5.4 and 9.9 GiB of device memory at the floor, 2x and 4x; a 12 GB card falls off at about 9.5 GiB (year 15 on the 1.13.3 schedule), a 16 GB GPU at about 13.5 GiB (year 23), a 16 GB unified Mac at about 8 GiB (year 12), the 5090 at about 29 GiB (year 54). **The DRAM-read cost per hash on the NVIDIA cards is NOT size-independent at the knee, MEASURED (the hash lane's kit b, PC 1, 12:49 to 12:58 UK, the pinned class v3 program 73bcbfe8 at 2, 4 and 8 GiB against the 1 GiB control 137.65 MH/s at 312.2 W unlocked and 127.39 at 212.6 W at the 1,300 MHz lock; 250 batches per row, fingerprints PASS): unlocked 133.86 at 315.7 W (-2.8 percent), 132.42 at 317.2 (-3.8), 131.75 at 319.2 (-4.3); at the lock 121.14 at 210.3 W (-4.9 percent), 113.06 at 204.5 (-11.2), 109.39 at 201.6 (-14.1); MH/W at the lock 0.599, 0.576, 0.553, 0.543, which is 4 / 8 / 10 percent more energy per hash at 2 / 4 / 8 GiB.** The lane's earlier reading (2 MiB pages keep the TLB's reach past 8 GiB) holds unlocked, where the card hides most of the page-walk term in its slack; the latency-bound regime at the lock exposes it. **The genesis floor itself, 5.5 GiB, MEASURED on a rented 5090 at stock (the fleet hand, RunPod secure, driver 570.195, 15:19 to 15:23 UK, the ca3-ds55 kit's own worker, program 73bcbfe8 in both packs, 250 and 500 x 2^24, every row PASS with 96 of 96 vector lanes): the 1 GiB control 141.48 MH/s at 325.6 W (2.30 microjoules; memory.used peak 1,914 MiB) against ds55 136.56 at 305.3 W busy, 327.6 steady (2.24 busy, 2.40 on the steady watts; peak 6,522 MiB: the 5.9 GB dataset plus the 268 MB cache plus the context), fingerprints stable across both passes (ds55 23ced07a4d28b465 becomes the pin). So the 5.5 GiB floor costs 3.5 percent of the rate at the same watts, about 4 percent more energy per hash, and the non-power-of-two mapping (1,476,395,008 words, 92,274,688 items, loads as (src x words) >> 32) is not a cliff on sm_120. Caveat: this host's 5090 plateaued at 328 W on both packs (a host power cap; another host's 5090 pulled 443 W on class v5 genesis this afternoon), so the microjoules are capped-card numbers and the rate and fingerprints are the row.** Lane 3's reading of it for the schedule (2a61cb46, 15:25 UK): the step lands between the 2 and 4 GiB stock rows (2.8 and 3.8 percent), so the non-power-of-two floors of 5.5 / 8.5 / 11.5 cost nothing beyond the size and the multiply-shift mapping is safe to adopt at the v6 epoch; per tier the 5.5 GiB step costs a 5090 4 percent per hash at stock (measured) and about 9 at its knee (interpolated from the 2, 4, 8 GiB knee rows); the 8 GB tier holds at that step on an exact NVIDIA 8 GB card (the RTX 4060, 6,116 MiB resident, measured 16:38 UK, 10.0p) and on a 12 GB card (the RTX 3060, 6,129 MiB), the RX 7600 row for the AMD 8 GB case still owed, the 5.5 GiB knee row with it; the SRAM store at that step is 3 reticles, USD 1,500, its joules unmoved. So each step of the schedule costs a tuned 5090 about 4 to 5 percent per hash while the chip's joules do not move (floor lane 3: its ticket goes USD 1,500 / 2,500 / 3,000 at 5.5 / 8.5 / 11.5 GiB), and every chip edge against a card at its knee rises by 4 to 11 percent across the schedule; the honest sentence for the schedule decision is USD 1,000 of chip ticket per step for about 1 to 5 percent of the tuned 5090's energy and about a quarter of today's measured cards by count. **On the M5 Max it is not size-independent, measured by this lane at 10:40 UTC under the Mac's measure lock (Metal packbench, the hash lane's class v3 packs at 2^28 to 2^31 words, the same seed and era, 3 batches of 2^24, vectors 3 of 3 and fingerprints per pack): 26.48 MH/s at 1 GiB (footprint 1,664 MiB, the build 32 ms), 23.26 at 2 GiB (-12.2 percent; 2,688 MiB; 54 ms), 21.31 at 4 GiB (-19.5 percent; 4,736 MiB; 94 ms), 20.61 at 8 GiB (-22.2 percent; 8,832 MiB; 193 ms).** The Apple GPU's dependent random read costs more time as the working set grows past its page reach (approximate reading: a TLB-reach effect on unified LPDDR5X; the power channels were not sampled this run, so the joules per hash move by at least the rate's share), which is a real per-tier cost of layer 2 that the NVIDIA model does not show: at an 8 GiB floor the Apple tier mines 22 percent slower per card than at 1 GiB, before any memory limit. The table below carries it. | Tier | At the floor (today to year 4) | At a 4 GiB state-driven step | At 16 GiB | Label | |---|---|---|---|---| @@ -443,7 +443,7 @@ The conditions, read off the surface, which are the economic-resistance statemen **The sentence, as the external review words it (10.0f item 5), served verbatim, with one word made honest (the site audit lane's read, 16:5x UK: class v4 and v5 have eight registers per lane and the window is class v6's new core shape, so "retains" is read as "retains across every rotation"):** "Class v6 adopts the 64-register window and retains it across every rotation. Current modelling estimates a 2.2x to 2.4x energy-efficiency advantage for the strongest specialised designs assessed against the GPU tier (2.0x on the GPU's own node). The long-program and select-tree proposals were rejected. Economic resistance depends on development cost, deployment economics and productive hardware lifetime; family transitions receive an obsolescence benefit only where a loss of competitiveness is demonstrated; programmable multi-epoch designs are included in the assessment." -**Where the figures come from (the coordinator, 16:1x UK): the served sentence's numbers are read from the k lane's PLACED GATED rows (17:30 UK; 10.0i), not from 725d2945's close and not from the 16:0x synthesis; until they land the figures sit in 10.0i's bracket, and the serve slips to 18:30 if the rows are late.** The labels on its numbers as first written: "2.2x to 2.4x" is modelled (the GPU side measured: the RTX 5080 at its 1,100 MHz lock 2.06 microjoules per hash and the RTX 5090 at its 1,300 MHz lock 2.33, both on class v4, PC 1 and rented pods, 8 October 2026; the chip side the k lane's synthesised 8-lane sequencer core with the 64-register window on ASAP7, scaled to N3 on TSMC's headline factors, claimed; the chip's memory the chip model's GDDR7 board, modelled; the card's cost of the window measured at stock on a rented 5090 and 4090 at 16:4x UK, within 5 percent per load with the liveness chain, no spill). "2.0x on the GPU's own node" is modelled (the same core node-for-node, k 1.09). Against the 32-lane window core the adversary would build the same figures read about 2.4x to 2.6x a node ahead and 2.0x to 2.2x node-for-node (synthesised, pending the re-optimised row by 18:00 UK); the served sentence's range is kept as the review wrote it and the 32-lane rows sit beside it on the page as the pending row. The window's k is synthesis-derived and not a lower bound. +**Where the figures come from (the coordinator, 16:1x UK): the served sentence's numbers are read from the k lane's PLACED GATED rows (10.0i), not from 725d2945's close and not from the 16:0x synthesis; the placement slipped to about 18:30 UK, so the sentence served at 18:30 carries 10.0i's tightened bracket, "estimates a 2.5x to 3.0x energy-efficiency advantage for the strongest specialised designs assessed against the GPU tier (2.1x to 2.6x on the GPU's own node)", and the placed row narrows it to one figure each on the next landing.** The labels on its numbers as first written: "2.2x to 2.4x" is modelled (the GPU side measured: the RTX 5080 at its 1,100 MHz lock 2.06 microjoules per hash and the RTX 5090 at its 1,300 MHz lock 2.33, both on class v4, PC 1 and rented pods, 8 October 2026; the chip side the k lane's synthesised 8-lane sequencer core with the 64-register window on ASAP7, scaled to N3 on TSMC's headline factors, claimed; the chip's memory the chip model's GDDR7 board, modelled; the card's cost of the window measured at stock on a rented 5090 and 4090 at 16:4x UK, within 5 percent per load with the liveness chain, no spill). "2.0x on the GPU's own node" is modelled (the same core node-for-node, k 1.09). Against the 32-lane window core the adversary would build the same figures read about 2.4x to 2.6x a node ahead and 2.0x to 2.2x node-for-node (synthesised, pending the re-optimised row by 18:00 UK); the served sentence's range is kept as the review wrote it and the 32-lane rows sit beside it on the page as the pending row. The window's k is synthesis-derived and not a lower bound. The lines the page carries beside it, each labelled: - The three statements, separate (10.0g item 1): energy resistance (the figures above); economic resistance (the profitability surface of 10.0f item 2, lane 3's first cut, modelled: p* scales as the project cost over the share times the discounted life, and under 5 percent with the per-joule edge; the cheapest attractive project is a USD 20 M DRAM-board design taking the whole chain for three years at about IGN 0.02 to 0.03, at a third 0.055 to 0.10; the SRAM die at N2 0.22 to 0.73; a fixed-lane chip under rotation needs 4x the price of a programmable one; stated as the conditions under which development is attractive); response capability (a passed rotation boundary proves the rotation works, not that hardware dies; the schedule of 10.0d: hourly, weekly, 180-day family, emergency vote; measured per boundary). @@ -471,6 +471,16 @@ The live-state analysis (`livestate.py`, 64 drawn programs, 1,024 waits): under Two corrections this forces on the served numbers: (1) the honest adversary's base core is the GATED one, k 0.37 at N3 and 0.51 node-for-node, below the 0.56 and 0.78 of 14:0x (those are the GPU-shaped core a maker would not build); (2) placement adds more than the +30 percent estimated at 14:1x: the ungated placed core reads 11.3 pJ against 6.9 synthesised (+64 percent: wires and a 2.5 pJ clock tree). **So until the placed gated rows land (in flight on a rented pod, 17:30 UK) the served figures sit in a bracket, from the synthesised gated rows (4.5 and 6.2 pJ per lane-op: the GDDR7 board 3.3x to 2.9x at the lock at N3, 2.9x to 2.5x node-for-node) to the placed ungated row (11.3 pJ: 2.3x at N3 and 2.0x node-for-node for the base core, the window below it), with the placed gated figure expected near 6 to 8 pJ (approximate): about 2.6x to 3.1x at the lock at N3 and 2.3x to 2.7x node-for-node, the window about 0.3x under the base.** The placed gated rows replace this bracket as the served number when they land, and 10.0h's figures are read from them. +The row to serve at 18:30 UK (the k lane, 17:5x UK; the placement of the gated 64-register core slipped to about 18:30 on a floorplan timing repair, the other five placed rows by 21:00): on the gated 64-register core, synthesis-only, a model never a lower bound (the GDDR7 board at the 5090's 1,300 MHz lock, 2.33 microjoules; E_chip = 0.466 + 102,100 x e_chip; node factors claimed): + +| Figure | Chip pJ per lane-op | E_chip microjoules | The edge at the lock | Label | +|---|---|---|---|---| +| node-for-node (N5, ASAP7 x0.70) | 4.3 | 0.905 | 2.6x | synthesised | +| a node ahead (N3) | 3.1 | 0.783 | 3.0x | synthesised, scaling claimed | +| two nodes ahead (N2) | 2.2 | 0.691 | 3.4x | synthesised, scaling claimed | + +The placed figure runs 30 to 65 percent over synthesis on this flow (the ungated base came in 64 percent over, wires and a clock tree, which gating removes in part), so the placed gated core is expected at 7 to 9 pJ at ASAP7, which puts the served figures at 2.1x to 2.4x node-for-node and 2.5x to 2.8x a node ahead (approximate until the placed row). **So the served bracket of this section holds and tightens to its lower half, and the honest sentence until the placed row is: "estimates a 2.5x to 3.0x energy-efficiency advantage (2.1x to 2.6x on the GPU's own node)"**, the placed row narrowing it to one figure each. The GPU side of the window is measured (no spill, at most 5 percent per load); the connected-state and multi-family lanes' rows agree with this core within 5 percent. + #### 10.0j Amendment after the landing (16:4x UK): the multi-family adversary lane's first core, and a disagreement between two models that the placed rows settle The multi-family adversary lane (a1a9876a88f5a72fc; synthesis only, ASAP7 TC, a gate-level random-input VCD; the SRAM macro energy modelled with a band; node factors claimed; for class v7, but it bears on the served window line): one in-order SIMD core with the 64-register window in a FakeRAM 64 x 256 macro per 8 lanes (one 256-bit access serves eight lanes), the imem in two 256 x 34 macros, every unit operand-isolated, a 5-phase single-port slot (throughput bought with lanes, not ports), every bank entry firmware. The genesis-only variant on the class v4 draw: 5.9 pJ per lane-op at ASAP7 (band 5.1 to 7.7), 4.1 at N5, 3.0 at N3; the card pays 10.3 pJ per op on the same draw at the 1,300 lock, so k = 0.40 node-for-node (N5), 0.29 a node ahead (N3), 0.22 / 0.16 at stock. Per family (k N5 / N3 at the lock): the add class 0.45 / 0.33, or 0.36 / 0.26, mul 0.32 / 0.23, mad 0.55 / 0.40, mulhi 0.12 / 0.09, shfl 0.083 / 0.060, the load with the fold 0.43 / 0.31. The whole-hash shadow 0.42 microjoules at N5 (0.31 at N3), so the GDDR7 board reads 2.6x against the 5090 at its lock node-for-node (2.9x a node ahead) and 2.3x / 2.6x against the 5080. **The lane's reading: a re-optimised core sits 15 percent under the k lane's 32-register flop core and 40 percent under its 64-register flop core at the same node, and the register-window knob buys the card nothing once the adversary puts the state in a macro.** @@ -527,6 +537,30 @@ The advantage, separated (the chip at 0.06): the board over a Blackwell owner 0. **RESPONSE capability:** rotation costs a chip versatility, not life. The 18-family bank costs a chip firmware plus 43 percent of its core cells and 11 percent of its shadow energy, with zero obsolescence credit on any transition in the bank (10.0m); a passed boundary proves the rotation works (10.0d). The window: its form is not the lever (the gated flop file and the macro file agree within 5 percent; the residual over 32 registers 0.3 to 0.4 pJ); its cost to the card is under 1 percent, measured on a 5090 (+0.6 percent) and a 4090 (-0.9 percent) at stock on 8 October (the connected-state lane, replacing "about 0, unmeasured"); and the connected-state class is KILLED (the connected window moves the chip's edge 1.10x and 1.08x against the 1.25x gate on the k lane's re-optimised core; necessity costs a clock-gated file nothing, since it pays per write, not per live register; only the window's width reaches the chip, +0.14 of k). +#### 10.0o Amendment (16:3x UK): the mixed FP32 candidate, KILLED on the GPU budget and the full-board score (`docs/analysis/class-v6/mixed-fp32.md` on class-v6-mixedfp at 255be026; all measured unless marked; for class v7) + +The candidate: the class v6 shape unchanged, four FP32 families (fadd, fmul, ffma, fcvt) drawn in the shadow block beside the ten integer families behind `IGNEUM_FG_FP32` (harness only), every result xor-injected, every operand a masked bitcast with the exponent field confined to 96..159 so no input or result is ever denormal, NaN or infinite; round to nearest even, no contraction, no fast-math, written in the emitter for CUDA, OpenCL and Metal; two weights, fp12 (18 percent of the shadow FP on the seed) and fp24 (30 percent). + +| Reading | The numbers | Label | +|---|---|---| +| Determinism | bit-identical CPU reference against CUDA on Ada and Blackwell: the pack self-test PASS on three rented cards for every pack, the 2^24 fingerprint equal on the CPU and all three cards for ctrl (5203e444a20bc754), fp12 (d9ddef1fa7a7895a) and fp24 (8fdedbb54ad3614f); Metal and the AMD OpenCL row owed | measured (PROVED on CUDA) | +| Census (sub-version 3, build-4, 256 seeds no era and 256 across eras 0 to 7) | both candidates 256 of 256 both ways, 0 exhausted, r 0.65 to 0.81 against the record's 0.67 to 0.83; the bias instruments fire 7x to 19x the record ((c'') 54 and 88 refusals against 8, (c''') 15 and 19 against 1, the era window-bit test 27 and 35 percent of candidates against 14.5); the F8-form read finds hot items (271 and 740 reads against the control's 29) on 1 of 16 and 2 of 16 seeds: an IEEE result's exponent byte carries 3 to 5 bits of entropy and the xor lands it on address bits 23 to 30 | measured | +| The verifier | the quiet core +5.6 percent (fp12), +8.2 (fp24); loaded, fp24 sits on the 10 ms line | measured | +| The card at stock (the class v5 kit worker, 250 x 2^24, nvidia-smi 1 Hz) | the 5090 3.553 microjoules per hash on ctrl, 4.078 on fp12 (+14.8 percent, 140.7 MH/s held, the card at its 575 W cap), 4.034 capped on fp24 (+13.5 with the clock down 108 MHz); the 4090 4.759, 5.664 (+19.0) and 6.022 (+26.5); v5-genesis +1 percent on both. 52 pJ per FP family op on the 5090, four fifths of it the determinism tax (the four integer ops per operand); the 10 percent budget allows about 11 percent of the shadow FP on the 5090, 9 on the 4090 | measured | +| The chip side (modelled on the k lane's method; its synthesised rows owed) | an FP32 FMA lane on its own is the family a chip undercuts least, k 0.4 to 0.5 at the lock against mad's synthesised 0.20 (the hypothesis's grain of truth), but the drawn op is the FMA plus its masking, which is ARX work on both sides, so the blended k of an ffma family op is 0.19 and an fadd's 0.18: the integer families' own | modelled | +| The full board, E_GPU over E_adversary at the 5090's lock | 3.0x on the record, 3.2x under fp12 (3.2x and 3.4x a node ahead): the candidate raises the chip's edge about 7 percent while costing every card 15 to 26 percent | modelled on measured card rows | + +**KILL.** The meaning for v7: FP32 is deterministic across CUDA and the CPU under the stated rules; the determinism tax is the whole economics (any FP form a GPU runs bit-exactly on random registers needs the operand confined, and confinement is integer work at integer k); the exponent-byte bias is a new instrument reading (the F8-form max-item column, 271 and 740 against 29, which no rule reads today) worth a rule in layer 4. The FP32 candidate joins the long program, the select tree, the wide read and the scratchpad in the suite as a negative control (10.0g item 2). + +#### 10.0p Amendment (16:38 UK): the 8 GB and 12 GB tiers at the 5.5 GiB floor, the window on them, and proving beside mining (the fleet hand's v6-coexist rows on exact rented cards; the ds55 kit's own worker; measured; logs in the hand's run.log per row) + +| Card | The 5.5 GiB dataset (ds55, the pinned class v3 program, 60 s rows) | The 64-register window (the v5 kit worker: hl-reg64c, the full chain; hl-reg64) | Proving beside mining (SP1 on the patched floor, the shard fees-v1-shards2 shard 0, 4.7 M cycles) | Label | +|---|---|---|---|---| +| RTX 3060 12 GB (driver 610, a 170 W limit) | 26.82 MH/s at 117.4 W, 6,129 MiB resident, the 5090's fingerprint 23ced07a4d28b465, PASS: **the 12 GB tier holds at the floor** | hl-reg64c 13.47 MH/s at 120.8 W (87 registers, 16 of 24 blocks per SM, fingerprint MATCH); hl-reg64 13.48 at 119.3 W (104 registers): per load (256 against 128 a hash) 3,448 against 3,433 M loads a second, **the window free per load, +3 percent of watts** | the proof alone 13.2 s VERIFIED at a 7,525 MiB peak and 122 W; together 6,129 + 7,525 = 13,654 MiB against 12,288: TIME-SHARING NEEDED (the live attempt filled the card to 11,893 MiB and the prover died in a device allocation after 34 s while the miner held 26.51 MH/s) | measured | +| RTX 4060 8 GB (driver 570, a 115 W limit; the host's power sensor N/A, so no watts) | 18.84 MH/s, 6,116 MiB resident, the same fingerprint, PASS: **the 8 GB tier holds at the floor** (the question lane 3 left open in 3.3, answered on an exact 8 GB card) | hl-reg64c 9.51 MH/s (87 registers, 20 of 24 blocks); hl-reg64 9.57 (104 registers, 16 of 24): per load 2,435 against 2,412, **the window free per load** | the proof alone 8.2 s VERIFIED at 7,532 MiB; together 13,648 MiB against 8,188: TIME-SHARING NEEDED (the live attempt died in the server's tensor allocation at 7,811 MiB while the miner held 18.83 MH/s) | measured | + +What it moves: layer 2's per-tier table (3.3) gains two measured rows at the genesis floor, the 8 GB and 12 GB tiers both holding with the dataset resident (6.1 GB) and the RX 7600 row still owed for the AMD 8 GB case; the window's cost to the card is now measured free per load on Ampere and Ada low tiers as well as on the 5090 and 4090 (10.0e, 10.0n); and the proving statement (10.0f item 4: proving is an opportunity for GPU owners) carries its memory condition: at the 5.5 GiB floor an 8 GB or 12 GB card cannot hold the miner and the SP1 prover at once (13.6 GB together) and time-shares them, while a 16 GB card and up co-resides. Not measured: the core-only beside row (the prove host has no core mode); watts on the 4060. A fault for the floor lane: the served sm_89 tarball (igneum-floor-sm89.tgz) ships the stock SDK server in home/.sp1/bin (the 24 GB gate) while bin/ holds the patched one; the hand copied bin/ over home on the pod, so the 4060 proof rows are on the patched server. + #### 10.0d The rotation schedule the close adopts (the rotation lane, `docs/design/class-rotation-four-layers.md` on class-v6-rotation at bd43f808, build-3, gate green, 14:4x UK; one line per layer; both of this document's constraints held: the 180-day family epoch not shorter, W = 4 not drawn) | Layer | Boundaries a year | What it draws, from where | Exposure per boundary (this document's units) | Chip | Label | diff --git a/docs/design/pool-vote-key-commitment.md b/docs/design/pool-vote-key-commitment.md new file mode 100644 index 000000000..fae1f801b --- /dev/null +++ b/docs/design/pool-vote-key-commitment.md @@ -0,0 +1,245 @@ +# Pool vote-key commitment: the member's key stays with the member, at protocol level + +Design document, Igneum 2.0, "Pools, software and participation", first bullet. Written 8 October 2026 (evening, UK) +by the adversarial seat, from the code and the specification as they stand on the box mirror's master (d6bee526) and +the pool lane's branches (`pool-finish-22` bee1f5f2, the fork's `pool-tags-node` 7455b8d5). Design only: no consensus +code changes here, and the pool lane's 0.3.20 branches are not touched. Status labels follow the specification's: +Implemented (in code on a named branch), Designed (written, not run), Measured (a number with its log). + +The pin this document serves, in one sentence: a miner's finality vote key is committed into every share and every +block the miner's hardware produces, whichever pool distributes the work and collects the pay, so a pool's share of +hashrate never becomes a pool's share of votes unless the miner hands over the key on purpose, and that hand-over is +visible on chain. + +## 1. The current state, from the code + +### 1.1 Where the vote key is bound today + +| Binding | Where | What it says | Status | +|---|---|---|---| +| The header carries the key | `vendor/igneum-node/consensus/core/src/header.rs:174`, `pub vote_key_hash: Hash` | 32 bytes, BLAKE2b under the domain `IgneumVoteKeyHash` of the 48-byte compressed G1 BLS key (spec 03 W1, table row W1). Zero only in genesis; any other header without it is `RuleError::MissingVoteKeyHash` | Implemented | +| Proof of work commits the key | `consensus/core/src/hashing/header.rs:28`, `.update(header.vote_key_hash)` in the header hash | The pre-PoW hash (the `prehash` every job carries) is a hash over every header field but the nonce, `vote_key_hash` among them (spec 02 fork point a5). A nonce that solves one prehash solves no other, so a share or a block is work on exactly one key | Implemented | +| The key is revealed once | `consensus/core/src/finality.rs:31` (`IGNK`), `:259` (`KeyReveal`, W1) | The first block under a key carries `IGNK || pubkey (48) || pop (96)` in the coinbase extra data; the node checks the proof of possession and that its hash equals the header's `vote_key_hash` | Implemented | +| Weight reads the header | spec 03 W2 to W4; the node's finality module (`docs/fork-divergence.md`, "Finality v2") | A key's 30-day weight is the blue blocks whose header names it. Nothing in weight reads the coinbase beyond the reveal | Implemented | +| The miner sets it | `vendor/igneum-node/igneum/miner/src/main.rs:480`, `raw.header.vote_key_hash = id.key_hash`; `:74`, the reveal into extra data | The solo miner writes its own identity into every template it hashes | Implemented | +| A placeholder survives | `header.rs:257`, `placeholder_vote_key_hash(payout_script)` | Devnet v0's stand-in, a hash of the payout script; any non-zero value was accepted "until the finality layer lands". The finality layer landed; the function remains callable | Implemented, to retire (5.3) | + +### 1.2 Where the pay is bound today + +| Binding | Where | What it says | Status | +|---|---|---|---| +| The coinbase names the payee | `consensus/core/src/evm.rs`, `miner_address_extra_data` (`IGNA` + 20 bytes) | The execution layer credits 80 percent of a blue block's subsidy to the coinbase's `IGNA` address (`pool/src/payout.rs:1`), the other 20 percent to the proving pool escrow | Implemented | +| The pool pays the pool | `pool/src/node.rs:32`, `extra_data(member, pool_address)`: the member's reveal plus the pool's `IGNA`; `:42`, `get_block_template(pool.pay_address, ...)`; `:47`, `raw.header.vote_key_hash = member.key_hash` | Pool v0 builds one template per member: the member's key in the header, the pool's address in the coinbase. The chain pays the pool; the pool's ledger (`pool/src/state.rs`, `pplns.rs`) splits it by PPLNS and pays balances at or above `min_payout` in rounds of at most 16 transfers (`payout.rs:198`) from the pool's own key (`payout-key.json`, `payout.rs:20`) | Implemented (pool-0, pool v0) | +| The open pool pays by a split in the block | fork `pool-tags-node` 7455b8d5: `evm.rs` `IGNH` (the share chain's parent) and `IGNW` (the window's split, `count x (address 20 bytes, weight 4 bytes)`), `split_producer`, the switch `pool_split_activation_daa` (never by default); `pool/src/sidechain.rs`, `open.rs`, `p2p.rs` | A share is a real template at the share chain's target with the member's own key and the member's own `IGNA`; a block pays the PPLNS window (2,160 shares) by `IGNW`, computed by every node from the block alone; nobody holds a balance or an operator key (pool.md 10.4) | Implemented on the branch, gated on Devnet 3 (pool.md 10.5: 100 members on 10 daemons, 90 of 90 honest members paid, 0 of 864 honest blocks paying a withheld address, drop proof by `verify-share`); the switch never set on any live chain | + +### 1.3 Where the pool's identity is bound today, and the member's defences + +| Item | Where | Status | +|---|---|---| +| The member names itself by its key | `pool/src/protocol.rs:42`, `authorize {pubkey, pop, label, payout, binding}`; spec 9.3, the `binding` over the TLS exporter (O-9.7, closed on `pool-finish-22` 10.2) | Implemented | +| The member refuses a template that names another key | spec 9.4.1 item 1; `job_refused` code `vote_key` (`protocol.rs`, pool.md section 2 "Member checks") | Implemented on the member side of the fork (`igneum/miner/src/pool.rs`) | +| The member refuses a coinbase that pays a third party or lacks its reveal | spec 9.4.1 item 2; codes `payout`, `reveal` | Implemented | +| The pool holds no key | spec 9.6 item 1; pool.md section 5 "Votes": every member voted through its own node, the pool held no key, 3 keys under one payout address on chain | Implemented, Measured on the devnet | +| Custodial mode exists and is disclosed | spec 9.6 item 5, `welcome.vote_mode` in {`member`, `pool`}; a client defaults to refusing `pool` | Designed; pool v0 does not offer it (pool.md section 3) | +| The litepaper says the opposite | `site/litepaper.html:702`, Governance: "Pools can decline, and vote keys stay with the pool"; ledger G6 (conceded 5 October 2026), O-9.1 | A stated line about the custodial case, written before pool v0 ran with member keys. Under 2.0 it flips (5.2) | + +So the first half of the pin is already true in code: the header commits the key, proof of work commits the header, +and the only pool that exists names its members' keys. What 2.0 adds is the second half (payment aggregation separate +and verifiable by any node, the pool unable to substitute without the member's share failing even against a member who +does not check), and the public words. + +## 2. The design + +### 2.1 Where the commitment lives: the header, not the coinbase + +The member's vote key is committed in the header field `vote_key_hash`, as today, and nowhere else is required. Why +the header and not a coinbase commitment: + +1. Proof of work is over the header. A share is a nonce whose lane hash under the job's prehash is at or below the + share target (spec 9.8 item 1), and the prehash is the header hash with the key in it. A coinbase commitment is + also under proof of work, through `hash_merkle_root`, but only transitively: to check it the member needs the + coinbase bytes and a Merkle path (mode B) or the whole body (mode A), while the header field is one 32-byte + comparison on bytes the member hashes anyway. The cheapest check is the one every client will run. +2. Consensus already enforces the field (non-zero, revealed once, equal to the reveal's hash) and weight already reads + it. A coinbase commitment would be a second place to keep in step with the first. +3. The key is per block, the coinbase is per body. Mode C (declared templates) and the open pool build the body + themselves; the header field is the same in every mode, so the binding does not depend on which side built the + body. + +The coinbase keeps what is not needed per share: the one-time reveal (`IGNK`), the finality section (`IGNF`, the votes +carried), the payee (`IGNA`), and on the open pool the share chain's parent (`IGNH`) and the window's split (`IGNW`). + +### 2.2 The share is the commitment, and the pool cannot forge it + +A share the pool accepts is work on a prehash. The prehash commits to `vote_key_hash`. So for a pool to credit a +member's work while naming any other key in the block, the pool would need a nonce that solves a prehash the member +never hashed, which is a fresh block's worth of work per block. There is nothing to add here for a conforming member. + +The gap is the non-conforming member: a client that hashes whatever prehash it is given. Against it the pool can put +its own key in the header and the member's work becomes the pool's weight. The design closes this at the protocol's +own level rather than the client's: + +1. The share carries the key. The `share` message gains `vote_key_hash` (32 bytes hex) beside `job_id`, `nonce`, + `hash`, and the pool MUST verify the share against a prehash whose header carries that key: the pool rebuilds the + prehash from the template it issued, and a template whose `vote_key_hash` is not the member's authorised key is a + template the pool cannot issue a job on at all (`job` MUST carry `vote_key_hash`, and a conforming member checks + it before any other field). Designed. Cost: 32 bytes on a line that is under 120 bytes today, one comparison. +2. The authorised key is the only key. A session is one key (`authorize`); every job and every share of the session + names it; a pool that issues a job under another key to that session is non-conforming on its face, and the + member's log says so with the code `vote_key`. Designed (spec 9.4.1 item 1 already; the job field makes it + checkable without the template). +3. On the open pool there is no pool to forge: every share is a full template the member built on its own node with + its own key and its own `IGNA`; the daemons check structure, seeds and proof of work (`open.rs`), and a share whose + header names a key other than the one that signed the daemon session is refused before it enters the chain. + Implemented on `pool-finish-22`; the session-key check is to confirm there (5.3). + +### 2.3 Payment aggregation stays at the pool, separate and verifiable + +Two shapes, both kept: + +- The operated pool (pool-0, pool v0): the chain pays the pool's `IGNA`; the pool pays members by PPLNS from its own + balance. The key is the member's, the money is the pool's until it pays. This is the Bitcoin pool shape; it is + allowed and it stays, because a member without a node can join nothing else (pool.md 10.5, "A pool user without a + node cannot join the open pool"). What makes it verifiable: every block on chain carries `(vote_key_hash k, IGNA A)`, + so any node computes, per pool address A, the set of keys that found its blocks and each key's count, which is + exactly each member's share of the pool's income under PPLNS at the block level. A pool that underpays a member by + blocks is caught from the chain; a pool that underpays by shares is caught only by the member's own share ledger + (spec 9.2, "Underpay shares"), which is the operated pool's known limit and the open pool's reason to exist. +- The open pool (no operator): the block's coinbase carries the window's split (`IGNW`) and the chain pays the split + directly to every member's own `IGNA` from `pool_split_activation_daa` on. Aggregation is the split; verification is + every node's execution of the block; no balance exists anywhere. Implemented and gated on Devnet 3; the switch is + never set until the P2 mechanism or the override sets it, as the fee switch was. + +In both shapes the vote key and the payee are different fields written by different parties on purpose: the key is +the member's and only the member's client writes it into a template it will hash; the payee is the pool's (operated) +or the member's own (open). A pool that writes a member's key into its own hashers' templates gains nothing (the +member's weight rises, not the pool's) and loses the blocks' weight for itself, which is why no pool does it. + +### 2.4 The share sidechain's role + +The share sidechain (pool.md 10.4; spec 09 section 9.12 on the branch) is the open pool: shares at a 10-second target, +one parent each, heaviest work wins, a PPLNS window of 2,160 shares, the window's split stamped into every coinbase so +a found block pays the window. Its role for this pin is twofold: + +1. It is the only shape in which payment is verifiable from the chain alone at the share level: a member can prove + a dropped share with `verify-share` (pool.md 10.5, "Drop proof"), and a block's split is computed by every node. +2. It removes the custodian of money as well as of keys, so a home miner's whole relationship with pooling is its own + node, its own key, its own address and a gossip socket. + +What it is not: it is not required for the vote-key pin. The operated pool satisfies the pin with 2.2 alone. The +sidechain is the stronger payment story, with a measured cost: every block's coinbase grew by 48 bytes per window +entry (pool.md 10.5, "The network"), the stale rate was 9.6 percent at 2 shares a second with ten daemons on one host, +and a public chain across the internet loses more to forks (the uncles row, 10.6, open). + +### 2.5 What Stratum V2 job declaration supplies and what it does not + +Stratum V2's Job Declaration Protocol (Braiins and the Stratum V2 working group; the lineage line of spec 09) lets a +hasher build its own block template, declare it to the pool, and be paid for shares on it, so the pool no longer +chooses the transactions. That is Igneum's mode C (spec 9.4.2) and it is in pool v0 as a required mode. + +It supplies: transaction choice, and with it the hasher's own coinbase extra data (so on Igneum a declared template +carries the member's reveal and votes by construction). + +It does not supply: an identity in the header. Stratum V2 has no header field for a voter, because Bitcoin has no +voter; the pool still sets the payout and, in the standard mining protocol without declaration, the whole template. +Job declaration is optional for pools, pools can decline (ledger G6 is right about that), and a pool that declines +puts the hasher back on the pool's template. On Igneum that template still carries the hasher's key in the header +(2.2), so declining job declaration changes transaction choice and nothing about votes. The sentence for the site is +in 5.2. + +## 3. The attack list, as the adversarial seat tried it + +Each row: the attack, what stops it in the design above, how it shows, and whether it survives. + +| # | Attack | What stops it | How it shows | Survives? | +|---|---|---|---|---| +| A1 | Pool substitution: the pool names its own key in the member's header | The prehash commits the key; a conforming member refuses the job (`vote_key`); under 2.2 the job and the share name the key and a share on another key is unverifiable against the issued template | Every block under the pool's `IGNA` names one key; the explorer's concentration page (ledger X14) shows one key with the pool's whole hashrate | No, against a conforming member. Yes, against a non-conforming client by the client's consent: see A5 | +| A2 | Key reuse across members: one key authorised by many sessions, so one voter holds many members' weight | Authorisation needs the proof of possession and the TLS-exporter binding, so only the secret's holder opens a session; several sessions under one secret are one operator's rigs (spec 9.6 item 3), which is the design. A pool cannot reuse a member's key without the secret | Nothing wrong on chain: one key, its own blocks | Not an attack: weight follows the secret's holder, as intended | +| A3 | Split identities: an operator or a pool spreads its hashrate over many keys | W6: keys are free and weight is blocks, so splitting moves no weight; dust (W3, 100 blocks in 30 days) silences the small keys. A pool splitting its own rigs over many keys to look like many members fools a member count, not a weight table | Many keys with the same `IGNA` and the same uptime pattern; cosmetic | Not an attack on votes; a presentation issue for pool pages | +| A4 | Withheld votes: the pool drops a member's votes from relay and carriage | Three roads (spec 9.7 item 5): the member's own node, `submitFinalityVote` on any node, and the pool's template; a member with a verifier signs from it, not from the pool's `checkpoint`; a member without a verifier does not vote at all | The carriage ratio per key against the pool's blocks (9.7 item 6, O-9.6, threshold open) | Survives only for a member whose only road is the pool, which the specification forbids from voting in the first place | +| A5 | Custody by terms of service: a pool whose terms require the member's key, or a modified client that accepts `vote_mode: pool` | Nothing at protocol level stops a holder giving a key away, and the specification allows the disclosed custodial mode (9.6 item 5). What the protocol does: the custodial pool's blocks all name the pool's key, so its vote share equals its hash share and both are public; the official client refuses the mode by default and shows it before the first share | One key under the pool's `IGNA` with the pool's whole hashrate; the ledger's "pools hold their hashers' votes" (spec 03 3.7 item 3) is then true of that pool | YES. This is the cheapest surviving attack: it costs the pool a terms line and a client fork, and it is bounded only by members' willingness and by the public reading of it | +| A6 | Block withholding by the pool: the pool drops a block a member found | The member holds the full block (mode A or C) and submits it to its own node before or beside `solution` (spec 9.5) | The block is on the chain whatever the pool did | Survives for a member with no node (mode A, no verifier): that member loses the block's weight and the pool loses the income, so the pool has no motive beyond harming the member | +| A7 | Pay-to-third-party: the pool's template names an `IGNA` that is not the pool's announced address | Spec 9.4.1 item 2, code `payout` | A refusal in the member's log | No | +| A8 | Induced equivocation: the pool feeds two checkpoint hashes at one index | The member signs only a hash its own verifier reports (9.7 item 2); a verifier-less member does not sign | None | No | +| A9 | Session replay: a captured `authorize` replayed to open a session under a member's key | The `binding` over the TLS exporter (O-9.7, closed on `pool-finish-22` 10.2); a replayed `authorize` on another connection is refused | A refusal in the pool's log | No, since TLS landed; the test that a replay is refused is the one to keep green (5.3) | +| A10 | Share theft between members: a member submits another member's share under its own session | The share names the key and the pool verifies it against the job it issued to that session; a nonce on another member's prehash hashes to a different value (`verify.rs`, "the same nonce on another template hashes differently") | `wrong_hash` | No | +| A11 | The pool mines its own rigs under a member's key to inflate that member | The pool gives weight away and keeps no income advantage; the member's `IGNA` is not paid (the pool's is), so the member sees blocks under its key paid to the pool, which is the normal case | Nothing abnormal | Not an attack: a gift of weight | +| A12 | Open pool: a daemon stamps a share chain parent or a split that favours itself | Every member checks the coinbase before hashing (`IGNH` the chain's tip, `IGNW` the window the member computes itself); a block with a wrong split is a block the honest members never hashed | The withholder's branch on Devnet 3: 0 of 864 honest blocks paid it | No | + +The cheapest one that survives is A5, custody by consent. It is not defeated by cryptography because it is not a +forgery; it is defeated by defaults (the client refuses), by visibility (one key per pool address on the explorer's +concentration page), and by the pool market (a non-custodial pool offers the same income). The design makes custody a +public, deliberate choice rather than the silent default it is on every chain with pooled voting; that is the whole of +what "at protocol level" can mean for a key its owner may give away. + +A note on what was not found: no path by which a pool gains weight from a member's work without that member's client +consenting, before or after 2.2. The weight table reads headers, headers are under proof of work, and proof of work is +per key. + +## 4. The cost on the honest side + +| Cost | Value | Status | +|---|---|---| +| Header bytes | 0 new: `vote_key_hash` is 32 bytes in the header today | Implemented | +| Coinbase bytes | the reveal 148 bytes once per key (`IGNK` 4 + 48 + 96); `IGNA` 24 bytes per block; the finality section per block as today; on the open pool `IGNH` 36 bytes and `IGNW` 4 + 24 per window entry (48 bytes per entry measured on Devnet 3 with the hex framing) | Implemented, Measured for the open pool | +| Share and job bytes (2.2) | 32 bytes hex (64 characters) on each, so a `share` of under 120 bytes becomes under 190 and a `job` of under 300 under 370 | Designed | +| Verification per block | one 32-byte comparison on every block (W1), one BLS proof-of-possession check on a reveal block (once per key); weight accounting as today | Implemented | +| Verification per share, pool side | one 32-lane group evaluation, 0.441 ms per group on one M5 Max core (spec 9.8 item 5, Measured), 1.35 ms in isolation and 2.1 ms under load on a rented 2 vCPU box (pool.md section 5); 2.2 adds a comparison | Measured | +| The home miner's bandwidth, operated pool | one `share` per 10 s and one `job` per template: under 0.1 kbit/s for shares; the template is the cost, a few KB to a few hundred KB per second at 1 block per second in mode A (spec 9.5 sizes, Designed, O-9.5); mode B carries the header, the coinbase and a Merkle path; mode C carries nothing down and one template up per declaration | Designed, unmeasured at a public pool | +| The home miner's bandwidth, open pool | one share per 10 s per member gossiped to every daemon it peers with: at 100 members, 10 shares a second of about one template each; the Devnet 3 gate ran 100 members on 10 daemons on one host, so the internet cost is unmeasured (10.6) | Measured on one host only | +| The accepted-work penalty of home internet against a datacentre link | the second bullet of the 2.0 Pools section; unmeasured here; it is the stale rate's dependence on round-trip time at `stale_grace_ms` 2,000 ms and two block times, to be measured with a member behind a home connection against one beside the pool | Open (6) | + +## 5. Migration note for the pool lane's branches + +### 5.1 Rebase first + +The pool lane's branches on the box mirror against `release-2.0.0` (b891444f, the version bump, 16:29 BST today): + +| Branch | Ahead | Behind | Carries | +|---|---|---|---| +| `pool-finish-22` | 1 | 112 | the open pool's Devnet 3 hour and the daemon's reconnect | +| `pool-mf-row-2` | 3 | 102 | the pool page rows | +| `pool-finish` | 11 | 572 | pool-0, TLS, the share sidechain | +| `pool-v0-rebase` | 4 | 925 | the pool-mode miner on the fork (the three commits the shipper needed for 0.3.20) | +| `pool-v0` | 3 | 1,691 | the original v0 | +| `release-0.3.20` | 0 | 539 | the release line the pool lane landed on | + +The fork side: `pool-tags-node` 7455b8d5 (`IGNH`, `IGNW`, `split_producer`, the switch) and `pool-finish-node`'s own +commits (the binding in `finality.rs`, the params field, the executor's split, the miner's TLS and rung). Every one of +these is rebased onto `release-2.0.0` (and the fork's 2.0 line) before any of this document's items is applied; the +version bump is rule 15's and a branch that carries 0.3.x strings is not landed on 2.0. + +### 5.2 The words + +- `site/litepaper.html` Governance, "Pools can decline, and vote keys stay with the pool" becomes: "Pools can decline + job declaration; the vote key stays with the miner in every mode, named in the header of every block its hardware + finds, and a pool that asks for custody says so and is shown as one key." Closes O-9.1 and the G6 cross-reference in + the ledger. +- spec 03, 3.7 item 3 ("Pools hold their hashers' votes") is rewritten as the custodial case only, with 9.6 item 5 + named. +- spec 09, 9.5: `job` and `share` gain `vote_key_hash`; 9.4.1 item 1 reads "the job's `vote_key_hash` and the + template's are the member's own key"; 9.8 item 5 adds the comparison. + +### 5.3 The code, in order + +1. The pool daemon: `vote_key_hash` on `job` and `share` (`pool/src/protocol.rs`), checked in `verify::check` + against the job's template; the member side (`igneum/miner/src/pool.rs`) checks the job field before the template. + A test with a known-pass (the member's key) and a known-fail (another key on the job) per the standing rule. +2. The open pool: confirm the daemon refuses a share whose header key is not the session's key (`open.rs`), with the + same pair of tests. +3. Retire `placeholder_vote_key_hash` from the fork's template path once no caller remains (today the miner writes the + real hash over it); keep the consensus rule that a zero hash is a `MissingVoteKeyHash`. +4. The explorer's concentration page: keys per pool `IGNA` and the share of blocks each holds, so A5 is visible as the + design intends (ledger X14). +5. The replay test of A9 and the drop proof of A12 stay in the pool crate's tests on 2.0. + +## 6. Open questions, named for main + +| Id | Question | What closes it | +|---|---|---| +| Q1 | Does the share carry `vote_key_hash` (2.2 item 1, 64 more characters per share) or does the job alone (item 2) suffice, the share being bound through `job_id`? The share form lets a pool's log stand on its own as evidence; the job form is cheaper | A decision; the adversarial seat's preference is the share, for the evidence | +| Q2 | The accepted-work penalty for home internet against a datacentre connection (the 2.0 bullet) has no measurement: the stale rate at 2,000 ms grace against round-trip time | One rented member behind a home-class link (a residential proxy or a PC on home broadband) against one beside the pool, an hour each, the stale rates per member | +| Q3 | Mode A template bandwidth per member at 1 block per second on a public pool (O-9.5) | The same hour's bytes on the member's socket | +| Q4 | The open pool across the internet: stale rate and uncles (pool.md 10.6) | The Devnet 3 gate re-run with daemons on three regions | +| Q5 | Whether the custodial mode (`vote_mode: pool`) remains allowed at all under 2.0, or is removed from the specification so that A5 requires a non-conforming pool as well as a non-conforming client | A ruling; removing it does not stop A5 (a fork of the pool is as cheap as a fork of the client) but changes who is non-conforming | +| Q6 | Minimum payouts on the operated pool: `min_payout_ign` is the pool's parameter; the 2.0 bullet asks for "practical" ones, which needs the fee-per-transfer at 2.0's fee level | The execution lane's fee number, then a floor in `share_scheme` | diff --git a/docs/design/proving-payment.md b/docs/design/proving-payment.md new file mode 100644 index 000000000..6b008a6e1 --- /dev/null +++ b/docs/design/proving-payment.md @@ -0,0 +1,28 @@ +# The proving payment: the tip-share discrepancy resolved (Igneum 2.0, D4) + +8 October 2026, 17:5x UK, the research lane, under the founder's Igneum 2.0 decision (`docs/plans/igneum-2.0.md`, D4: "the economics page's tip-share discrepancy resolved; explicit user-funded proving payment with congestion pricing, burn treated separately; hard cap and no development tax kept"). A design decision on text and spec; the one code change it implies is pinned below and is not made here. + +## The discrepancy + +The economics page's fee table says the priority fee (the tip) is 80 percent to the block's miner and 20 percent to the developer registrations, which is what the code on Devnet 3 does (`DEVELOPER_SHARE_PERCENT = 20`, the rest to the miner). Spec 5.2 says the 80 percent goes to "the block producer and provers ... in the proportion the proving protocol defines (forward reference)", spec 5.3 speaks of "the provers' part of the 80% tip share", open item O-5.7 leaves that proportion to phase 2, and the page's own "proving-fee market" paragraph says a card's second income includes "the provers' part of the priority fee". So the page contradicts itself and the spec contradicts the code: the provers are promised a share of the tip that no rule sizes and no code pays. + +## The decision + +1. **The tip stays whole to the block.** The priority fee splits 80 percent to the block producer and 20 percent to the developer registrations, exactly as the code does. No part of the tip reaches the provers. O-5.7 is closed by this decision: the provers' proportion of the tip is zero. +2. **The provers are paid by an explicit, user-funded proving payment with congestion pricing: the proving base fee.** Every transaction already pays `pgas used x f_p`, where `f_p` is the proving base fee that spec 5.1 adjusts per chain block by the EIP-1559 step toward a target of half the proving budget (`B_p / 2`), never below the floor of 5.11. Today that payment is burned. From this decision it is the provers' payment: **90 percent of it is credited to the block's proving pool escrow (`PROVING_POOL_ADDRESS`) and paid out per shard by consensus proving cost under the rules of 5.3; 10 percent is burned.** The price is the congestion price by construction: `f_p` rises when blocks use more than half the proving budget and falls when they use less, so a proving demand spike raises what users pay provers per unit of proving work, which is the signal that brings capacity in (the operator simulation of D4 reads it as its pricing rule). +3. **The burn is treated separately and listed in one place.** Burned: the execution base fee in full (anti-stuffing, unchanged), 10 percent of the proving payment, the unregistered developer share of the tip, and 10 percent of IGN-settled external jobs (5.4). Nothing else. +4. **The hard cap and the absence of a development tax are untouched.** No new emission, no change to the 20 percent proving-pool share of the subsidy (2.5), no address that any team controls. + +Why the 10 percent burn on the proving payment: the burn of the proving base fee was the rule that made wash pgas a guaranteed loss (5.1). With 90 percent of it routed to the block's provers, a miner who is also a prover of its own block could recover part of a stuffed block's proving payment; sortition (eight eligible provers per shard, 5.3) makes that recovery a share of the pool's weight at best, and the 10 percent burn plus the execution base fee burned in full keep stuffing a loss at every weight. The 90 and 10 mirror the external job split of 5.4, so a prover's two incomes carry one rule. + +## What a prover earns, in one line + +Per block: its shards' part of 20 percent of the block subsidy (2.5, 5.3) plus its shards' part of 90 percent of the block's proving payment (`pgas used x f_p`); per job: 90 percent of the external job fee (5.4). Nothing from the tip. + +## The code pin (not made here) + +`igneum/exec/src/executor.rs` (the proving base fee debit at 357 and 360 on Devnet 3): credit 90 percent of `pgas used x f_p` to `PROVING_POOL_ADDRESS` and debit the remaining 10 percent to no one, instead of debiting the whole to no one; the pool's per-shard payout (5.3) then carries it with no further change. Behind an activation constant on the devnet objects like `proving_v1_activation_daa`. Until it lands the economics page says "designed, not in the code" on that row, as it does for the external job split. + +## Where the text changes + +Spec 5.1 (the proving-cost gas row and the burn sentence), 5.2 (the 80 percent recipient and the forward reference), 5.3 (the provers' income), 06 O-5.7 (closed); the economics page's "Where fees go" table (the base-fee row split into the two dimensions, a proving-payment row, the duplicated tip row removed) and its "proving-fee market" paragraph. diff --git a/docs/fud-ledger.md b/docs/fud-ledger.md index aa5b2b13e..a9a3b2fdf 100644 --- a/docs/fud-ledger.md +++ b/docs/fud-ledger.md @@ -1800,7 +1800,7 @@ Evidence: `docs/bench-log.md`, 4 October 2026 "difficulty rule: timestamp attack ### P21. The SP1 proof is not what consensus checks in proving v0 "Your proof records pay provers, and the node pays a record whose statement matches its own execution whether or not the SP1 proof behind it verifies. A prover can sign the native statement without proving anything." -Status: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 11): proving v0 (every producer verifies off the consensus path) through the public testnet; the in-consensus verifier is the execution engineer's plan item for after it; the litepaper sentence labelled Open stands. Was: Open, stated in spec 7.7 item 4 (4 October 2026). Branch `proving` of the fork, `igneum/exec/src/proving.rs`. Sweep (5 October 2026): stated; the in-consensus verifier is a build item (execution engineer). +Status: Fixed in the node behind a named switch (8 October 2026, the enforced-proving lane, branches `enforced-proving` and `enforced-proving-node` on the 0.3.25 node line; `docs/spec/proving-enforcement.md`), after an external review the founder accepted at 16:1x UK: a valid SP1 proof is a condition of payment in consensus. Two rules on one floor, `Params::proof_rule_active_from()`: the body rule of 0.3.16 (a carried record whose proof is not held, does not verify or names another program id invalidates its block) and a new payment rule in the executor (`carried_payouts`, `carried_segment_payouts`: from the floor a record pays only when this node's verifier holds a VERIFIED verdict for its proof; otherwise it is carried unpaid and nothing is marked paid). The switch `verifier_in_consensus` (`OverrideParams` and `Params`, in the digest once set) is false on every compiled object: the live Devnet 3 object stays at never (unchanged by the rollout), igneum-testnet-1 keeps its own floor of 0 (the body rule has held there from block zero; the payment rule joins it on the same floor), the class v6 object carries it true from its block zero. Tests, named per refusal, known-failed first (spec section 3): the consensus side `proving_enforcement_tests::enforced_*` (no proof, a wrong proof, another program id, the honest acceptance, the finding with the switch off, the floor as a boundary) and the executor side `proving::tests::enforced_*` (no payment without a verified proof and the honest record paid once, a replayed record, a wrong network id, an altered payout address, a duplicate of a paid record, the v0 shape below the floor, the verdict source); the executor set green on build-2 at 16:08 UK (7 of 7), the consensus set and the crate suites in the spec's section 6. Cost: spec section 4 and 6. Fast-time case across the boundary: `infra/fast-time/proving-enforcement.mjs`. Was: Decided (6 October 2026, 17:25 UTC, by the owner; decisions item 11): proving v0 (every producer verifies off the consensus path) through the public testnet; the in-consensus verifier is the execution engineer's plan item for after it; the litepaper sentence labelled Open stands. Was: Open, stated in spec 7.7 item 4 (4 October 2026). Branch `proving` of the fork, `igneum/exec/src/proving.rs`. Sweep (5 October 2026): stated; the in-consensus verifier is a build item (execution engineer). Decision owner: the founder, decided 6 October 2026 (`docs/plans/ledger-decisions.md`, outcomes section). Answer: Correct for v0, and by design for now. The consensus check on a carried record is the native-execution veto (spec 7.2 item 5): the statement must equal the node's own 328-byte shard statement for that shard and payout address, so no record can move state or pay for a wrong claim. The SP1 proof is verified off the consensus path by the proof pool's verifier (`igneum-prove-host --mode verify`), and a producer offers only verified records to its templates; a producer that includes unverified records (trust mode, test networks only) can pay a prover who did not prove. The damage is bounded to that prover's payout. What closes it: the aggregated segment record of design 5.4 verified in consensus, which needs the SP1 verifier inside the node (the SDK dependency the node does not carry today) or a bounded in-consensus verification budget. Until then the devnet runs v0 with every producer verifying. @@ -1810,7 +1810,7 @@ Round 2 (5 October 2026, night): the public text now carries the v0 fact, labell ### P22. The rewards and payouts are inputs to the shard proof, not outputs "The shard guest takes the segment's rewards and the prover payouts as data and commits the post-root after them. A host can feed any list and the proof still verifies." -Status: Open, blocked on the phase 2 consensus proof (design 7: the aggregator derives the rewards and payouts from consensus data it verifies, so they become outputs of the proof): next step that consensus-proof work, in phase 2 (Nov 2026 to Jan 2027 per the litepaper roadmap), no earlier date. Was: Open, stated in spec 7.7 item 6 (4 October 2026). Sweep (5 October 2026): stated; nothing runnable. +Status: Open, staged (8 October 2026, the enforced-proving lane; `docs/spec/proving-enforcement.md` section 7 carries the staging table): the closure is four explicit stages, each a claim about one input with the native check that holds it until the next stage, never a self-contained proof of the whole state. Stage 0 (today): rewards and payouts are data in the shard statement and every node's native derivation vetoes a statement that differs; enforced proving adds that the record's proof must verify for that statement (ledger P21). Stage 1: the rewards list checked against a commitment the aggregator carries in its public values, the commitment itself recomputed natively from the mergeset. Stage 2: the payouts derived inside the aggregator guest from the carried records it verifies, `carried_payouts` the native check of the same derivation. Stage 3: the rewards derived inside the aggregator guest from the headers and blue sets it verifies, the consensus proof proper; only here do rewards stop being an input anywhere. Stages 1 to 3 are the phase 2 consensus-proof work (Nov 2026 to Jan 2027 per the litepaper roadmap); no served text says "the rewards and payouts are proven" before stage 3. Was: Open, blocked on the phase 2 consensus proof (design 7: the aggregator derives the rewards and payouts from consensus data it verifies, so they become outputs of the proof): next step that consensus-proof work, in phase 2 (Nov 2026 to Jan 2027 per the litepaper roadmap), no earlier date. Was: Open, stated in spec 7.7 item 6 (4 October 2026). Sweep (5 October 2026): stated; nothing runnable. Answer: Correct, and already true of the rewards since devnet v4 (`BlockFixture.rewards`, `proving_pool_credit`): the shard statement is "from this pre-root, these transactions, these rewards and payouts, the post-root is X". The node checks the statement against its own execution, which used the rewards and payouts consensus derived, so a proof over a different list does not match any node's statement and pays nothing. Closing it in the proof itself means the aggregator deriving the rewards and payouts from consensus data it verifies (the mergeset's blue blocks and the carried records), which is the consensus-proof work of design section 7. @@ -2275,7 +2275,7 @@ Status: Fixed, stated (7 October 2026, night): every mention of the month is gon Answer: The date was the plan of 3 October 2026 and the chain overtook it: the testnet genesis was fixed on 5 October, the three seeds and rpc.testnet.igneum.network are up, and the remaining work is the go checklist. Rows that quoted the month (X3, O-X.2's blocker note, overclaim item 75's replacement text) read the new sentence by reference to this row. -Evidence: `docs/plans/testnet-go.md`; `docs/igneum-testnet` notes (genesis 87617621..., seeds seed1 to seed3.testnet.igneum.network, public RPC). Checked by `tools/ci/ledger-text-check.mjs` (the X3 and X31 rows). +Evidence: `docs/plans/testnet-go.md`; `docs/igneum-testnet` notes (genesis 01294fd3... since the re-cut of 7 October 2026, 87617621... before it; seeds seed1 to seed3.testnet.igneum.network, public RPC). Checked by `tools/ci/ledger-text-check.mjs` (the X3 and X31 rows). ### X32. The roadmap carried calendar months beside a testnet that is weeks away "After X31 the roadmap read phase 4 'Apr to Jul 2027' and phase 6 'Nov 2027' with phase 5 'weeks away' between them, and phases 1 to 3 carried 'Oct to Nov 2026', 'Nov 2026 to Jan 2027' and '20 nodes by Mar 2027'. A reader spots the contradiction at once." diff --git a/docs/plans/counter-asic-3-status.md b/docs/plans/counter-asic-3-status.md index 4920f07b0..b54e92527 100644 --- a/docs/plans/counter-asic-3-status.md +++ b/docs/plans/counter-asic-3-status.md @@ -465,7 +465,7 @@ Reading: the class v4 premium is 145.3 W at the unlocked clock (not the 80 W of | 1,200 | 133.80 | 305.1 | 0.439 | 129.54 | 215.7 | 0.601 | 1,192 | | 1,100 | 122.43 | 287.3 | 0.426 | 118.70 | 209.4 | 0.567 | 1,087 | -The knee by main's rule (more than 1 percent lost against unlocked): 1,300 MHz on both classes (the rate within 1.5 percent of unlocked down to it; v3 falls 5.1 percent at 1,200, v4 10.5 percent at 1,100); the best MH per watt one step past it: v4 at 1,200 MHz (133.80 MH/s, 305.1 W, 0.439 MH/W, 168.6 W recovered for 2.2 percent of rate), v3 at 1,300 (134.62, 223.3 W, 0.603, 106.6 W for 1.4 percent). The v4 premium 143.8 W unlocked, 81.8 W at the best points; the v4 rate 0.25 percent over v3 unlocked and 0.61 percent under at the best points; the residual at the floor is the shadow's ALU work, not the clock. Per tier: a 5090 owner on class v4 locked at 1,200 to 1,300 MHz draws 305 to 313 W instead of 474 for 1.5 to 2.2 percent less rate, MH per watt up 49 to 52 percent; the Ember knob (0.3.24, the hash lane on the engine side, the UI lane's drawing) carries these as its reference rows. A FAULT FOUND AND FIXED: the steps 1,000 down to 300 and the closing reset got no answer from the Power Helper and the card sat at the 1,100 lock for about five minutes after the job (118 to 122 MH/s live); the installed app's own Ember tune on the 5080 wrote the same cmd.txt with higher sequence numbers while the script wrote lower ones, and the helper skips any sequence at or under the last run; the restore job run-ca3-pc1-clocks-restore-20261007 (exit 0 at 20:45:58Z) put the 5090 back at 2,865 MHz; the fix 45f9497f on the mirror (the sequence base from helper.log and cmd.txt, re-based after a timeout, an unanswered lock stops the grid, the task restarted before every reset); the rule for the knob: it takes its sequences from the engine's counter and no script shares the file with a running tune. The driver's floor below 1,100 is unmeasured. THE PC 1 QUEUE after the shipper's 0.3.23 host job (main, 21:5x UK): the 5080 full grid with the fix; the research lane's SM-sparse kernel job (the hash on a fraction of the SMs, several chains per thread, the rest clock-gated; the research lane hands the kernel to the hash lane); the third 5090 pass from 1,100 down to the driver's floor at the tail; then the 9070 XT G1 and ladder, the v5 AMD bench, item 6 on AMD, the 5080 and 9070 XT tunes, the L2 cache-policy hot table; each exit line to the shipper and the coordinator; the honest site sentence (the premium at the knee and the floor it buys, labelled measured, the Ember knob named as how a user gets there) once the 5080 reads. THE DERIVATION FINDING FIXED (the hash lane, 15008aca and 0f45c8be on the mirror): one byte recipe (generator::IdRecipe) builds the id and the printed text; program.json states the generator 4 suffix and the rung form; spec 1.4.6 corrected (class v5 = generator 5, no suffix); tests/derivation.rs re-derives all 18 pinned packs from their own text (the plain text gives 8aa9f185d63f269e for the devnet v4 pack, the known-failed case); 38 packs' program.json re-exported with ids, kernels and fingerprints byte-identical; the full igneum-pow suite green on box 2. CLASS V5 FROZEN: class-v5 1c420786 on both box mirrors at 21:53 UK (the (c''') floor with its number; section 14 with seven of seven live hot sets refused at 0.9821 to 0.9919, seed 170 at 0.9880 the seventh, and the three mild residuals at 0.9992 to 0.9997 named at about 1.0004x; the pinned pack unchanged; the flip-stale harness PASS on the matched binaries at 21:03 UK; the AP-F4-1 first form and the AP-F1-1 shadow rule, the latter's measured trigger 11 permille maximum over 6,000 first draws against the 30 bound, 0 redraws; the igneum-pow suite green on box 2: 73 unit, packs 20, derive 7, mixer 4, recheck 2, scratch 7; the gate GREEN at 58 checks). The kits lane: the 0.3.24 kit is packs-ca3-v5-20261007T183921Z.zip sha256 e6c088bb34fecdc3ff297dbb06438a14ade7d8c55273357726d28f7a1334a25e, byte-identical to the frozen 1c420786 (state.igsd1 included), fingerprint 82b19cbde8557ea5 on Metal, Apple OpenCL and a CUDA 4090; AMD on PC 1's queue, Intel deferred; the shipper has the line. The attack-pass lane runs F8 at 2^24, F9 at 10^5 and F1 on 1c420786 under class v5. The v5 lane's next commit on the freeze: AP-F4-1 in the agreed form (cost at most 205 against the median 226, w32 without the position-32 digit, k >= 1 and all-ROT-equal rejected, the known-failed day 29,337 = 2050-04-28) and the verified last resort (part (a) repaired by re-sourcing stale loads, then the whole rule over a 256-candidate scan, known-failed first on adv-accept-3's adv3/steer/2); both move the stream only on days and seeds the chain never reaches. THE FOURTH EXCEPTION ON THE RESTART STEP (the fast-time lane's held-miner run on the third pair 63524e28, 20:4xZ): the IBD catch-up's body sync anchored on the node's own sink and moved only on a whole chunk's successful join, so with the honest headers arriving as one chunk failing on its v5 tail it fetched nothing and the executor never reached the seed block; the relay hold-off and the mining hold from the earlier fixes read green on that run. FIXED by the node lane at f0c56f50 (the refused chunk split by consensus's own record, the anchor moved to the highest validated header, the honest v4 prefix through the seed block, only the unvalidated headers deferred; kaspa-p2p-flows 38). PAIR 4 = v5-object-0323 c8f9b383, re-archived from the frozen 1c420786 (generator.rs and accept.rs moved since ab6f980b, memhard.rs not), building on build-1 at gate priority since 20:54:32Z with the line's gates beside it; the restart step's PASS must come from pair 4; the object commit lands the minute it does, with dn3-g1's DAA at the cut plus 7,200 rounded up to the 3,600 boundary and its UTC clock named; the testnet lane told to pair its re-cut with 1c420786. The crossing clock is not yet a reading: about 22:15Z (23:15 BST) at the earliest if every line reads green on its first pass. The site audit lane: no other "12 days" form served; its row-17 edit keeps main's outside-check clause and adds the 5090 efficiency numbers. THE CHIP TEXTS, THE X9 WORDING RETIRED (main's order from the counter-asic-4 research file d7721ebe, 22:0x UK): the withdrawn Antminer X9's claimed ratio ("a third of a CPU's energy per RandomX hash") is against a CPU core (about 100 pJ per instruction, Horowitz and Dally, claimed), not a GPU lane (6.5 to 10.4 pJ measured), so a chip three times better than a CPU is worse than a GPU lane per op and the X9 is not a pessimistic chip core against us. The served texts (the home line, the litepaper's lead, chip table, ladder sentence and chip bullet, /claims through it, the miner line, evidence row 17) now give the floor and the premium as measured numbers at the 5090's knee: the chip at 2.1x per joule with a core as good as a GPU lane (k = 1) and 3.4x with one three times better (k about 0.33), no core below about 1.8 pJ per op in the model's range, the shadow's premium 81.8 W at the best points (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W against class v3 at 1,300 MHz 134.62 at 223.3 W, 7 October 2026), Ember Tune's core-clock knob named as how a user gets there; the ledger text check's pins X35 and X36 moved with the wording; no "3.9x" remains on any served page. One number stated against main's wording: main's line read "2.9x with one three times better", which in the research file is the figure for the RE-WEIGHTED op mix (row 3, held by the coordinator until the SM-sparse read); today's mix at a core three times better reads 3.4x in the same file, so the served text carries 3.4x and the 2.9x waits for the re-weight to ship. THE RESEARCH FILE's TWO ORDERS: (1) the texts as above; (2) one zero-code measurement at the PC 1 tail after the third 5090 pass: the 5 October hot-table packs (packs-ca2-hot, 32 and 64 MiB) with the worker's `--variant ldcs` (dataset loads streaming, evict-first; the hot loads plain and L2-resident) against base on the 5090, the rate ratio g and the watts (the 5 October rows without the hint g 0.84 to 0.87); the one class where a chip's cost per op (a 64 MiB SRAM read, 0.2 to 0.5 nJ approximate) may exceed the GPU's (an L2 hit, 0.1 to 0.3 nJ); Metal has no such hint. The shadow stays at rung 0; the op-mix re-weight waits for the SM-sparse read (the research lane's worker variants sp170/85/43/21/11-w32, one block of 32 warps per SM, run through the hash lane's efficiency script in its ca4 mode at 4f3a064e; the no-prompt and sequence rules hold by the same code). THE 0.3.24 PAIRING RULED (the shipper, 22:1x UK): the v5 object commit pairs with the frozen class-v5 1c420786 as it stands (the gates and the attack-pass lines run on it); the post-freeze fix 8ca66afa is 0.3.25's pairing. 0.3.25's FIRST ROW: class-v5 8ca66afa (both mirrors, 22:10 UK, on 1c420786): (1) AP-F4-1 in the agreed form (decc7c17): the day's draw rejected when cost A = 64 + sum(w32(MUL_i) - 1) is at most 205 against the median 226, w32 over bit positions 0 to 31 (the position-32 carry digit dropped), any MUL with w32 at most 3 rejected (k >= 1), the eight ROT all equal rejected, a rejected block redrawn whole from the continuing stream; known-failed first on chain day 29,337 (2050-04-28): the sub-version 3 block of that day read cost 203, rejected at 205 and redrawn under class v5. (2) Class v5's verified last resort: the rewrite, then repair_stale_loads (a stale load re-sourced to the lowest register written since its last load, to a fixpoint), then the whole rule over a 256-candidate scan from the cap; the unchecked fallback past the scan under 1e-300; known-failed first on adv-accept-3's adv3/steer/2 (the sub-version 3 rewrite fails part (a) at instruction 47 reading r3; the repair restores (a) moving only load sources; class v5's last resort passes at attempt 256, id 9b29c9481f6941d4; steer 11, 33, 56, 58 and 77 pass too); sub-version 3's path untouched. The stream moves only on days and seeds the chain never reaches: the pinned v5 packs byte-identical, the fingerprint 82b19cbde8557ea5 and the epoch-0 id e5a4ac5978462156 unchanged; the igneum-pow suite green on box 2 (74 unit, packs 20, derive 7, mixer 4, recheck 2, scratch 7), the gate GREEN at 58 checks. The harness's class-walk case (v4 floor 0, v3 never) read FAIL on the unfixed fork 546fe4b5 (the known-failed shape, 22:08 UK) and runs on pair 4. THE IN-HOUSE PASS, THE EIGHTH HOT SET (adv-accept, 22:06 BST, the wider sweep over 88,051 accepted programs): seed 122960 (id 4be7393ab6c84802, the lowest 256-unit ratio at 0.9885) reads live at 2^24 X_f +0.111 percent, X/f 1.11, 1.54x the window model, with the heaviest single item measured tonight (0x81ad88 at 475,616 reads, 0.022 percent of all reads, 16x 100767's hottest) from an all-ones source at instruction 4 (writer shfl at 3); site 12's saturated-source share 0.353 percent, a third of (c')'s limit; the other four lowest 256-unit proxies clean live, so the 256-unit proxy is noise at its own extreme and the 2^20 ratio is the selector; the tally 8 hot sets in 30 tail seeds against 0 in 20 random; the price unchanged (0.34 percent of reads on 1 MB, 1.002x); its minimum-site ratio at 2^20 against the 0.995 floor OWED (ordered first), deciding whether the freeze record reads eight of eight refused or names the first hot set the floor misses. THE 5080 AT STOCK (run-ca3-pc1-v4-eff-5080-20261007-b, exit 0 at 21:03:02Z, the card alone, 60 s, both fingerprints matched): class v4 71.43 MH/s at 255.1 W (0.280 MH/W, sm 2,958, mem 14,801 MHz); class v3 71.30 at 170.7 W (0.418); the v4 premium 84.4 W (49 percent over v3's draw), the rate 0.18 percent over v3; against the fleet's rented 5080 (71.16 MH/s at 143.4 W on class v4, driver 580) the rate agrees to 0.4 percent and the watts do not (255 against 143), a question to the fleet lane (its sampler, a cap on the rented card, the memory clock) before either row enters the public table; the lock grid did not run in -b (a PowerShell function defined below its first call left the script without the helper path; nothing set, nothing to restore), republished as -c at 21:07:10Z with the full grid (unlocked to 300 MHz, about 58 minutes). The site audit lane's row 17 and litepaper paragraph carry the 1,400 MHz rows labelled measured, with the best-points clause asked beside the 88 W at 1,400. THE 0.3.24 OBJECT COMMIT AND PIN: v5-object-0323 774f16c9 (21:26:35Z, both mirrors; the fork 432ea3d6 + f0c56f50 + 9ad1d9c6 + 294e3670 + the pool lane's 95ae3e50), paired with the frozen igneum-pow 1c420786: program_class_v5_activation_daa 28,800 (the Devnet 3 seed node at virtual DAA 16,208 at 21:22:24Z; the publish minute 22:30Z = DAA 20,264; plus 7,200 = 27,464; the next 3,600 boundary 28,800, epoch 8), byte 6 counted exactly, the window 86,400; the crossing on Devnet 3 by height about 00:52Z on 8 October (01:52 BST) at 1.0 DAA/s; the constant holds while the publish DAA stays at or under 21,600 (22:52:16Z), past which the node lane re-reads dn3-g1 and re-cuts to 32,400; chain id 4463 below the floor and 4464 from it; the three heights stay, the pool split never. Its gates: core 155 of 155, miner 28 of 28, pow 19 of 19, p2p-flows 38 of 38, exec 46 of 46, consensus 126 of 126 on the gate-priority rerun at 21:44:24Z (the earlier one red at 205 ms on the latency bound under a box load of 127, the known load class); the canary set on build-1 (21:29:38Z to 21:31:18Z): the digest moves to 4a284b1d on igneum-devnet-3 as the v5 arm requires, "this node stamps object version 6 into its headers (block version 1538)", the override file refused, two empty nodes handshake on 4a284b1d, the shared-devnet node refused on network mismatch, a 0.3.23 node refused on the digest both ways; every Devnet 3 node restarts inside one minute at the fleet's named clock on pre-placed binaries. release-0.3.24-node OPEN at 774f16c9 on both mirrors (21:45:19Z, the shipper's word), artefact /srv/artefacts/0324-774f16c9/node-lane (igneumd ed36f246...); the testnet staging 47b9b229 on the pin all green (consensus 134, core 175, exec 47, miner 28, p2p-flows 38, pow 19, digest b2e856ed). THE FAST-TIME GATE CLOSED: SUMMARY PASS (cross-c8f9b383-2) at 21:36:35Z on the matched pair c8f9b383 (igneumd f1b5b32c..., igneum-pow 1c420786), every check green, none skipped: class v4 sub-version 3 from genesis at rung 0; rung 1 by signal from epoch 6 at 21:29:39Z; class v5 by signal at byte 6 counted exactly from epoch 8 (DAA 480) at rung 1 at 21:31:33Z on 4 of 4 nodes, 9,985 bps, before the floor; the second rung at epoch 12 the rule's earliest allowed; 11 of 11 program ids equal to the CPU verifier's; 0 PoW rejections on the honest nodes; the stale node 69 of 69 refused; the restart step: n2 stopped at DAA 455, restarted on its own datadir at DAA 500 at 21:31:56Z, no lock fault, no IBD refusal, "class v5 catch-up done: 19 deferred headers validated after 6 s", nothing of its own accepted during the catch-up and 75 after, at n0's sink 12.1 s after its start; four sinks equal at 660; the digest-compat PASS from 20:08:30Z stands; records on v5-fasttime 4419e8d3. The three earlier pairs (959b57c9, 63524e28, 432ea3d6) each failed the restart step on a node defect fixed in the next (the IBD refusal, the catch-up's anchor at the node's own sink, the node mining while its catch-up waited). THE FLOOR READS EIGHT OF EIGHT (adv-accept, 22:41 BST): seed 122960 (the deepest live hot set) reads minimum site 12 at 0.9824 at the acceptance's 2^20 sample (live 0.9822), REFUSED by (c''') at 0.995 (its site 12 puts 1.31 percent of its reads on word indices read 8 or more times, the largest repeated-index share measured; 100767's site 6: 0.17); every live hot set by X_f at or above f found in the tail of 88,051 accepted programs is refused (minimum sites 0.9821 to 0.9919) against 0 hot sets in 20 random programs; the floor misses the three mild concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x; the v5 design's section 14 and the ledger's AP-F8-1 carry the line. THE 0.3.24 CUT waits on the attack-pass verdicts on 1c420786 alone (F8's two halves on build-2 since 21:17:41Z, about 22:20 to 22:35Z; F9 at 10^5 and F1 on build-1); the lease pool now pre-empts adv holders at any size for a v5 or release waiter after 120 s (lease ce30e357). PC 1 EXCEPTION: the Power Helper task dies within seconds of each start since 21:08:34Z (six starts, zero commands, the task Running while no helper process exists; the last good command the 20:45:52Z rgc, its idle exit clean at 21:05:52Z); the suspect the shipper's 0.3.23 host job at 20:51Z replacing the install folder's exe under the registered task, the second a panic in the helper's start path; a read-only diagnostic plus a 20 s unelevated probe placed; the locked grids (the 5080 full grid, the third 5090 pass), the SM-sparse job and the tunes wait on the helper; the lock-free jobs run (the 9070 XT G1 and ladder from 21:27:41Z, then the family run and the v5 AMD bench); nothing raises a prompt to get round it. THE 5080 AT STOCK (two runs agreeing, -b and -c): class v4 71.42 MH/s at 254.5 W (0.281 MH/W, sm 2,960, mem 14,801), class v3 71.30 at 170.8 W (0.418), the premium 84 W; against the fleet's rented 5080 (71.16 MH/s at 145.4 W busy mean, cap 350 W not binding, 1 Hz power.draw instantaneous on Linux driver 580, bench batches with host gaps) the rate agrees to 0.4 percent and the watts do not (110 W apart, the sampler field on Blackwell under two drivers or the load shape); the public table carries the method per row and takes neither as the card's figure until both power fields are sampled on both sides (the fleet's re-measure, PC 1's next NVIDIA pass). THE CA4 SECOND PASS (bca23f96, sections 15 to 19): the tensor-tile k column (2.1x at k = 1, 1.6x at k = 1.5, the k 0.3 column removed for a tensor shadow; a design candidate needing a SIMD byte-dot verifier) and the capex column (the f = 1 GDDR7 chip USD 2.8 per MH/s, at most 4.3 with the hot table, the shadow core and an interposer; capex-dominated 7x; the break-even cap moving only through the project cost) carried into chip-model-v3 as section 5.11. THE PUBLIC TEXTS (main's two orders, 22:3x UK): the served sentence "the one outside check is staged and waits on its escrow and the publish word" read as an escrowed prize to a reader and is replaced everywhere it is served (evidence row 17, the litepaper and /claims through it, the public text file) by "no outside review has run yet", the in-house pass sentence kept; the forbidden-strings gate gains the phrase class ("outside check", "waits on its escrow", "staged and waits", "the publish word"; the bare words stay allowed, since the proving pool's escrow and a staged build are ordinary). THE /miners DESIGN PASS is on the mirror's ca3-coord at e88edae4 with the full gate GREEN (the overlap check clean at 390 to 1600 px after two fixes: the phone grid gives every cell its own area; the desktop row is six columns with the class v4 cost and the date as the muted second line under the card name, the card layout below 1,100 px, the wrapper scrolling as a safety); the 1440 and 390 dark captures go to main for the word on the look; nothing deploys from the branch before it. The in-house pass: four lanes complete (adv-cache, adv-accept-2, adv-cache-3, adv-mixer; adv-mixer's Q1 BOUND on the commutation probe at 0 in 1,454,080,000 over 1,024 days, its SAT row a solver-reach bound at the one-hour cap); adv-mixer-2 one row from complete; adv-accept, adv-accept-3, adv-cache-2 and adv-mixer-3 sweeping to 00:00 BST. F8 ON CLASS V5: PASS (the attack-pass lane, 22:03Z; the frozen igneum-pow class-v5 1c420786, binary sha256 0f5c98dc41a1b3aa...; the pairing bit for bit on 66 validation lines, the library drawing Devnet 3's epoch-0 program as e5a4ac5978462156; 64 seeds p2 to p65 at 2^24 nonces each, chain path, the v5 dataset from v5-dn3-epoch0's state.igsd1 on day 20,733, window-model control, build-2 under lease pool class v5 as two halves of 32, ended 21:58:43Z and 22:03:21Z): 61 of 64 under 1.2x of the window model (0.9919x to 1.144x, p75 1.0024x); 3 over, all inside the named four-seed residue and none new: p10 1.5047x (hottest item 0x4018f5 at 346 reads of 2^31, no predicted source), p8 1.3787x (419 reads), p4 1.2166x (363 reads); p34 reads 0.9997x under the (c''') floor; every strong seed of sub-versions 1 and 2 at 0.9997x to 1.0001x (p23 1.0000, p19 0.9997, p15 0.9998, p18 1.0001, p56 1.0000); seed for seed the ratios equal sub-version 3's within 0.001 except where the floor moved a draw: the state leaves change the words, not the read addresses. F9 (10^5 exhaustion) and F1 (10^5 redundancy) on 1c420786 and F4's 2^24 on 8ca66afa hold or wait in build-1's pool as strengthening lines. THE 0.3.24 NODE PIN MOVED on the shipper's word to 47b9b229 (the object 774f16c9 plus the testnet re-cut 34892a36) after the Devnet 3 canary set read clean on its own binary (21:59:04Z to 22:00:43Z: digest 4a284b1d, byte 6, the override refused, shutdown 725 ms, the handshake, the shared-devnet dialler and a 2720d8d2 node refused); release-0.3.24-node at 47b9b229 on both mirrors (22:01:05Z), igneumd 6bc18ac2..., pairing 1c420786; the build-server lane builds the pairs and the hive from it; the Devnet 3 digest 4a284b1d, the testnet b2e856ed; the floor 28,800 and its slip rule, the dn3-g1 re-read armed for 22:30Z. THE AMD HALF OF G1 PAID (run-ca3-pc1-v4-sub3-amd-g1-20261007, exit 0 at 21:46:14Z, the RX 9070 XT alone): 14 of 14 fingerprints equal to the Mac's Metal and Apple OpenCL and to the 5090's (the control, the seven sub-version 3 packs, the five ladder packs), self-test PASS on all; the ladder rows flat within 2.3 percent from 930 to 330,700 ops per hash (18.8 to 19.2 MH/s; the installed worker's control cross-check 18.96), the card latency-bound on the whole ladder; the watts row owed (the ADLX sampler read 0 samples in the per-pack windows). THE HELPER FAULT READ: not the shipper's; the task's exe is the install folder's 0.3.20 (mtime 12:24:42Z, sha256 0443ae17..., untouched by the host jobs); the helper's code path runs (an unelevated probe answered a dev line in 4 s); the scheduler refuses the ELEVATED instance from a non-interactive start (Last Result 0x800710E0, the task's logon mode interactive only); at 21:41:32Z the 0.3.20 engine's own tune took its legacy "task not registered" branch (the old sweep.rs helper.ps1 written, cmd.txt truncated), the prompt path, so whether a prompt stood on the desk is for the founder's screen in the morning; the class (the engine's registered() check and its fallback, the scheduler's logon mode) is the update-return lane's for 0.3.24; the locked PC 1 jobs stay parked. THE CA4 PROTOTYPES (the research lane, counter-asic-4 6404f62b): two experimental classes behind the pack, no consensus change: +shlx (the shadow's 256 instructions and 27 passes split into 16 sub-blocks of 16, each run after its load) and +mm (R int8 mma u8 tiles per iteration after the shadow; CUDA native PTX, the shuffle reference on Metal and OpenCL; the verifier scalar plus AVX2, SIMD pinned equal to scalar on 64 seeds); the suite green (64 + 7 + 4 + 19 + 2 + 7), the pinned packs byte-identical; packs exported with every OVERALL PASS (mx8_sh256x27 control, mx8_shl256x27, mm128, mm512, mm1430 at 11,440 tiles per hash); their card rows on PC 1 behind the helper; by construction neither lowers the premium (the per-load placement moves the chip's capex, the tile block its k floor). THE LEDGER CLOSE landed the chip rows on the mirror's master at b94a77ad (22:56 BST): X35 and X36 restated, AP-F8-1 with the eight-of-eight sentence, X37 new (the class v4 premium: measured, levers in flight). THE RECORD LANDED (23:24 BST): the regroup 2336a3c5, the outside-check rewrite and chip model 5.11 (6c19c790) and the status 015cc839 picked onto ca3-coord-record from the mirror's master and merged as ddfaf7a7 through the gate (GREEN, 7 checks in 30 s on f252b514); the first pick hit the audit lane's best-points clause in the litepaper, claims and evidence pages and the resolution keeps master's text with only the escrow sentence replaced by "No outside review has run yet." (main: the right sentence); the design pass stays on ca3-coord for its own landing on main's word after the captures. ADV-ACCEPT-3 CLOSED (the v5 lane, 23:12 UK): 8ca66afa closes its class as stated (the 9.0 percent of rewritten 256th-attempt programs the rule refuses are repaired for part (a) and re-drawn under the 256-candidate scan; the known-failed test on adv3/steer/2, five more steer rows passing); ledger row AP-F8-3 written (sub-version 3's last resort recorded unreachable and unverified, class v5's verified) at class-v5 7f58af97 with the v5-kits branch merged (the OpenCL, NVRTC and Metal hosts with the leaves upload, the kit scripts); the kit zip rebuilt from the merged tip, /srv/artefacts/packs/packs-ca3-v5-20261007T221001Z.zip sha256 4aaf9b9edfad0e466f6b6b59051250afad6a8e0a340728ec068bec48113c0fc9, the packs and the fingerprint 82b19cbde8557ea5 unchanged; Metal, Apple OpenCL and CUDA agree; AMD and Intel fingerprints owed. A GAP: tools/ledger-page.mjs renders only [A-Z]\d+ ids, so no AP-* row (AP-F8-1 to AP-F8-4) reaches /ledger; the site audit lane widens the regex tonight as its own commit with a known-failed case. THE SPEC SPLIT: the site audit lane holds 1.4.3, 1.4.6 and 1.13 (the acceptance-rule rewrite on spec-accept-23) and builds tools/ci/spec-constants-check.mjs, a constants table in the spec parsed against the crate's pub consts (known-failed first) with the class v4 test vectors stated in 1.4.6, since the attack-pass lane has no read-back test and writes none; the hash lane sent it the file and line of every constant from 017e7037 (= master's igneum-pow byte for byte, cf7d6ccb) plus ACCEPT_TAG, the window cap literal in distinct_ratio_pass and the full Devnet 3 genesis hex, no wrong values, one text quirk: the (c) reject prints "limit 163" while MAX_SATURATED is 164 (the first refused count); main's ruling: the spec words the constant, the message string is corrected on the post-freeze line, never in the frozen 1c420786. The v5 lane's 1.4.7 and 1.8.6 are on both mirrors at class-v5 73daadc2 (23:23 UK; full gate GREEN 58 checks at 066c9cbb): class v5's load class, generator 5 and the id, (c''') with the 0.995 floor and the census, the verified last resort, AP-F4-1 and AP-F1-1, the activation object byte 6 and the seven-window 95 percent signal, the test vectors (the three pinned packs, seed 100767, day 29,337, adv3/steer/2), 1.4.7.6 the constants table in the audit lane's shape (Constant, Value, Where); the state leaves (IGSD1 stream, leaf derivation, keyed sample, the leaf line before M_0, the per-epoch refresh and the witness, the measured cost). THE ERA-DRAW MECHANISM (the crypto lane's adv-cache-2, 6e34ebe3, 23:1x to 23:3x BST; report-chained-cache-2.md section 2.3, the 61-program table: 2 real, 27 drawn-era with epoch and era hex, attempt, id, R, site and ratio, 32 devnet-era controls): the mild residual class has its mechanism; a product's biased low bits (P(bit 0) = 1/4, measured exactly) survive the odd stride multiplier and the stride rotation places them at address bits R and up, inside the 28-bit item index unless R is 28 or more; the devnet era draws R = 29 and cuts them off, so 2 of 32 devnet-era programs carry a site over 1.04x while 13 of 27 drawn-era programs (R 3 to 22) do, 8 over 1.2x, worst era-drawn-28 site 15 at 1.7451x and era-drawn-25 site 11 at 1.3571x; under the 2 GiB genesis dataset (D = 29) R = 29 would show it too; the devnet's cleanliness is an era-draw accident, the chain prevalence is the drawn-era figure. The price to a partial-store chip stays under 0.1 percent of a hash's reads per site, so no chip number moves. Disposition: the class v5 (c''') census was already across drawn eras (each of the 4,600 f8 seeds carries its own era bytes), so the 2.435 percent and the eight of eight stand; the pointed reading runs on box 2 (the v5 lane, about 20 minutes from 23:3x): the 2^20 floor read on the 27 drawn-era programs plus era-fixed-20 and four devnet controls, reporting how many of the eight over 1.2x and the band 1.04x to 1.2x the 0.995 floor refuses; the value-level question (biased product bits feeding an address, independent of the distinctness ratio) and the era draw's R range go to the CA4 file as a named requirement with this reading as its evidence, and the research lane's per-load census gains a drawn-era split; nothing in class v4 or v5 moves without main's word. THE ATTEMPTS CENSUS on the frozen sub-version 3 rule (adv-accept row 90, 23:24 BST, 10,000 seeds): 21,119 rejected candidates, by first failing part (a') unfresh 83.3 percent, (a) stale 11.7, (b) no injecting write 3.1, (c'') low-entropy site 1.1, (c) constant bit 0.4, (c) saturated 0.3, (c') 0.1, the distinct-address floor 0.04, lane-constant and bias 0; per-candidate rejection 0.6787, flat at 67.5 to 68.7 percent over attempts 0 to 3 (independent draws); accepted-attempt mean 2.112, max 24; 0 exhaustions; P(256 consecutive rejections) 8e-44 per seed, so the last-resort draw is unreachable by chance and the attempt index is no lever for a seed-steering attacker; accepted programs' distinct-item mean 127.95 of 128, minimum 123.67; spec 1.4.6's 5.14 percent (the class v3 census) is stale against it, the audit lane rewrites; the second 10,000 queued on build-1. Also PASS: the line census at 2^35 + 3 x 2^33 and the 16,384-day weak-day scan. THE PC 1 QUEUE TONIGHT (the hash lane): run-ca3-pc1-amd-family-20261007-e exit 0 at 22:09:25Z (the 9070 XT alone, gfx1201, driver 3683.0, 32 CUs, three runs every row exact against the alu chain; step costs as a ratio to alu 741 G steps per second: rotr 1.05, shflx 0.89 (bperm native), shl 0.92, shr 0.99, bfe 1.03 native and 0.83 C sequence, andn 0.93, perm 1.21 emulated (perm_amd refused), popc 0.85, clz 0.83, sel 0.72, shfla 0.77 (bperm), dot4 0.75 native (dot4_khr refused), mm8 1.20 (gfx12 path, unverified); the khr and intel shuffle builds refused as on 6 October); the shipper's 0.3.24 host slot holds PC 1; on its "slot closed": fetch-ca3-v5-kit-20261007 (the 4aaf9b9e zip), then run-ca3-pc1-v5-amd-bench-20261007 (the v5 lane's script, the 9070 XT by name, beside the miners, about 3 minutes), lock-free and non-elevated, quiet. The Intel fingerprint: main first routed it to PC 1, the hash lane's device lists (the 22:09Z --list, the kit README) show no Arc on PC 1, and main's second word places the Arc B580 as PC 2's eGPU (tonight's PC 2 crash was an Intel driver install over that card while it mined); the job (tools/class-v5/pc1-intel-v5-bench.ps1 at a4b08245) moves to PC 2 by job after the shipper's 0.3.23 take 3 smoke and the update-return lane's scheduler proof have reported on that box, never concurrent with an install or a build there, the same lock-free class; a fingerprint that differs from 82b19cbde8557ea5 holds that card's v5 kit out of 0.3.24 and the crossing time is stated on its page row. PC 2 carries the RTX 5080 since about 15:00Z (tonight's stock row is that card). THE HASH LANE'S LANDING (the derivation fix, the no-prompt rule, the PC 1 job scripts, the Ember core-clock knob 74585c91: the ladder below 45 percent in 100 MHz steps to a 20 percent floor, the stop rule at the knee or on a faulted row, lock_result and the card's lock_* fields, 18 Ember tests and the app crate's 158 green on box 2, the 1 percent tolerance landing the 5090 at 1,854 MHz on tonight's rows and 1.5 percent at 1,300, the tolerance the manifest's; ledger row AP-F8-4) went RED once on the pre-public scrub (the founder's name in a ledger row and two script comments), fixed, the mirror's master merged in again, the gate rerunning from 23:2x; the merge commit follows. THE FLOOR'S FULL TALLY (adv-accept gap-deep4, 23:25 BST): the four deepest remaining 256-unit seeds all read under 0.995 at the acceptance sample (148927 at 0.9814, 150347 at 0.9896, 34501 at 0.9929, 29307 at 0.9912); the first three clean live (0.9998x to 1.0028x), 29307 at 1.29x on one item from a non-saturated source, no hot set by X_f. Over everything the lane read at 2^20: 8 of 8 live hot sets refused; 6 clean-live programs refused (false refusals) and 1 clean passed among the 9 deepest 256-unit seeds; 3 mild residuals missed at about 1.0004x. The lane's reading of why both sides exist: (c'') counts repeated word indices on the stand-in, which the live set usually spreads thin rather than concentrating, so a low ratio is not a hot set; that is the 2.4 percent clean rejection the floor pays, and a true hot set needs the value-level source test to be caught without it (the CA4 requirement). THE SPEC REWRITE committed on spec-accept-23 (the audit lane, 23:3x UK): 1.4.3 and 1.4.6.1 to 1.4.6.6 to the shipped rule at 017e7037, the shadow block in 1.7, the ninth era draw in 1.13.1, ledger AP-F8-5 (the stale spec text) with the public ledger regenerated, the two tables in the check's shape (Constants of the shipped rule: Constant, Value, Where, 17 rows; Pinned program ids: Seed, Attempt, Id, Note, 6 rows with Devnet 3's full genesis hash and the three must-differ ids); the full gate running; it merges the mirror's master after the hash lane's landing so the check and the text arrive together. THE PER-LOAD FIX (the research lane, counter-asic-4 2f718001, pushed 22:24Z; the fixed pack mx8_shl256x27_v2 22:29Z, attempt 3, id bd64b207a30413fb, the first export 854050a4293f0615 kept as the known-failed record): known-failed first at 22:16Z (tests/ca4_trace.rs on build-2): the first export derived 10,728 distinct items of 12,288 over three units (the class v4 shape 12,286), 1,482 same-iteration duplicate lanes at sites 8, 10 and 15; the mechanism from the 64-seed census (29 of 64 seeds failing, up to 620 duplicate lanes a seed, sources collapsed to 1 to 17 distinct values in 32 lanes): a lossy base writer (mulhi, mul, or) followed by 27 passes of the 16-instruction map collapses the register before the next load, so the static last-writer rule catches only part of it. The fix in two layers: the static redraw (a sub-block writer of the next load's source drawn from the injecting families when it is mul, mulhi or or) and the dynamic acceptance test stepping the per-load sub-blocks in the order the class executes (accept.rs alu_step inside run_unit) with a new rejection DuplicateLanes (any load reading one address in two lanes of a unit), a rejected candidate redrawing the attempt. After, 22:23Z: 12,287 of 12,288 and 0 duplicate lanes on the genesis seed; the census (64 seeds x 2 units on a second dataset, 16,384 load rows) 1 duplicate pair in all (seed ca4-census/49 site 3, the chance floor of a 2^24 index space, about 0.5 pairs expected; the class v4 shape's own trace shows 2 of 12,288 from the same floor); the suite 64 + 2 + 7 + 4 + 19 + 2 + 7 passed on build-2. Owed: the Metal fingerprint (the Mac, one at a time under the measure lock), the F8-form uniformity on the fixed export through the attack-pass harness, the drawn-era split of the census (R 3 to 22 against 28 to 31) and the biased-low-bits requirement row from adv-cache-2, the PC 1 card row on both exports. Nothing in class v4 or v5 moves. THE "LIMIT 163" FIX (the hash lane): the one-line fix on a post-freeze branch off the mirror's master, pow-reject-text-24 at 79c5c07d (pre-push GREEN): the (c) saturated reject text prints its limit as MAX_SATURATED - 1 and names 164 as the first refused count, with the test the_saturated_reject_text_prints_its_limit_from_the_constant reading the printed limit back (green on box 2); the frozen 1c420786 line untouched; it lands with 0.3.25's line. The derivation fix's landing: the second gate run RED on the public-ledger check (AP-F8-4's last paragraph must start with one of the six status words), the row now closing "Status: Fixed (7 October 2026, night)" and docs/ledger-public.md regenerated; the third gate run from 23:3x UK. PC 2's Intel job prepared as run-ca3-pc2-v5-intel-bench-20261007 (the kit fetch to PC 2 first) behind the shipper's "PC 2 clear"; the CA4 packs job on PC 1 runs both per-load exports (dir and id on every row). THE FLOOR RE-CUT (main's ruling, the shipper 23:3x UK): the 28,800 floor lost to the clock (the pairs, the hive kits, the fleet's fetches and the ten minutes after the last FETCHED cannot land before 23:52 BST, past the 22:52:16Z slip point), so the node lane re-cuts program_class_v5_activation_daa to 32,400 (epoch 9) on release-0.3.24-node, the same object otherwise (pairing 1c420786, chain id 4464 from the floor, the testnet re-cut inside); the new pin and its gates about 25 minutes from 23:3x; the crossing on Devnet 3 by height then about 01:52Z on 8 October (02:52 BST) at 1.0 DAA/s; the move minute after F9 and F1 PASS and the last FETCHED. THE ERA READING ON THE FLOOR (the v5 lane, box 2, 23:3x BST, igneum-pow at 73daadc2, the 2^20 acceptance sample): 0 of 29 of adv-cache-2's programs are refused by the 0.995 floor at their listed attempt, and the class v5 draw lands on the same attempt as class v4 for all 29; the six over 1.2x read minimum sites 0.9965 to 0.9997 (era-drawn-15's 1.51x site 14 at 0.9965 the lowest), the 1.04x to 1.2x band 0.9986 to 0.9998, the clean ones 0.9999 to 1.0000, the devnet-era controls 0.9996 to 0.9999. So the floor's statistic does not reach adv-cache-2's class: the distinct-index count at 2^20 reads concentration on FEW items (adv-accept's hot sets put 3 percent of a site's reads on 512 word indices, moving the collision count by thousands), not a diffuse excess over the top 0.1 percent of items (era-drawn-15's 1.51x is about +0.08 percent of the site's reads spread over 16,384 items, a few hundred collisions, inside the clean spread). Two classes, two instruments: the floor closes the few-item hot sets (8 of 8); the era-stride diffuse class needs the per-site item-share test at live scale or a draw rule on R and the shadow block's last write (the next class's row); its chip value is bounded by its own diffuseness (a 1 MiB hot table of the top 0.1 percent of items serves about 1.0024x at the worst site read so far, under the AP-F8-1 bound by an order). The v5 design's section 14 gains this paragraph with the 61-row log (era-drawn-25 to -28 and the 32 controls running; era-drawn-28 at 1.75x the one to watch) and its bound sentence corrected (the "top-0.1-percent share under about 1.3x" form, never served, lived in section 14 only); a ledger row for the miss asked. Nothing in the freeze moves. MAIN'S ROW WORDING for Devnet 3: a 0.3.23 node that has not updated falls off at the digest move minute (the fleet's named minute, about 00:52 BST at the latest), not at the 02:52 crossing; the row reads "update before or the node stops following Devnet 3; class v5 begins at DAA 32,400, about 02:52 BST". F4 ON CLASS V5 PASS (the attack-pass lane, 8ca66afa, build-1 under class adv, 379 s, ended 22:3x UTC; the agreed w32 convention, median 226, 2^24 chain days from 20,729): M1 0 of 2^24 days over 1.1x, the minimum cost 206 (day 27,016, 1.097x), so the bound holds with no margin and no day over the line, mean 225.79, sd 6.07 (the pre-rule census 5.69e-4 over, min 203); M2 0 days with k >= 2; day 29,337 redrawn under the rule (203 to 228), day 20,729 at 219 unchanged; AP-F4-1 FIXED-AND-PASSED; F9 and F1 under class release on build-1, lines within the hour. THE CA4 FILE (the research lane, 22:3x UTC, sections 20.2a and 20.2b): the drawn-era split of the per-load census: 16 eras over the fixed class, 2 units each, R under 28: 12 eras, 3,072 rows, 0 duplicate pairs; R 28 and up: 4 eras, 1,024 rows, 0 pairs; every era accepted at attempt 3; the adv-cache-2 reading written as a named requirement (value-level bit-bias of the index at a product-sourced site, judged across drawn eras split by R, owed for every CA4 class and the same item as class v5's acceptance; the per-load dynamic rule covers distinctness, not bias). Metal fingerprints (22:30 UTC, M5 Max under the measure lock): the fixed per-load pack ee5d7c71180e5ea7, vectors 3 of 3, 26.88 MH/s against the control's 27.01 (the placement costs Apple nothing); the tile packs bit-exact against the Rust verifier on the Metal reference path (mm128 270e4ae36b37e9a1, mm512 a1c1ff3148d775d1); the Apple cost is the finding: 1,024 tiles per hash take 35 percent of the M5 Max's rate, 4,096 take 78 percent, so a tile shadow at the ALU shadow's premium would take the Apple tier out unless Metal gains an integer matrix path; the tile class moves from rank 3 to beside rank 5 until that path is measured. Main's rule: no served number mentions the per-load fix before its F8-form uniformity and drawn-era split (the split now read; the uniformity owed). THE PUBLIC SENTENCE ON THE FLOOR (main's wording, 23:3x UK): "eight of eight hot sets refused; the diffuse era-stride excess, bounded under 0.1 percent of a hash's reads per site, is not caught by the floor and is the next class's test", the same words on ledger row AP-F8-1 (landing from ca3-coord-record 6d09d96e with the two-instrument reading and the AP-F8-6 pointer), on AP-F8-6 and in the v5 design's section 14 (the v5 lane, class-v5 54e52b8a at 23:36 BST carrying AP-F8-6, F4's PASS in the attack row and its clock corrections: build-2 prints CEST, every page time re-read to BST); no served page carries a hot-set sentence tonight, so the sentence reaches readers through the ledger once the AP-* regex fix lands. F4's no-margin hold (the minimum accepted cost 206 against the 205 bound at day 27,016) is a record sentence, not a served number. ADV-MIXER-2 CLOSED (the crypto lane, 2a632579 on build/adv-mixer-2, 23:37 BST; 0.31 box-hours, 0 pod-hours): the redraw rule (continue the stream and redraw all 40 draws when the LUT cost A is 205 or less, or a 2-adder MUL, or all ROT equal) over 2^24 and 2^28 days leaves 0 days over 1.1x; 6.0e-4 of days redrawn once, 3e-7 twice, never three times; the mean cost unchanged; verdict BOUND for every chip, GPU and the verifier (gain 1.0 every day at 9,360 ops per item), FINDING on the per-day FPGA LUT-area reading only (2^-10.8 of days over 1.1x, worst 28 April 2050 at 1.113x), closed by the redraw rule or by the spec's O-1.10 day derivation; five lanes closed (adv-cache, adv-accept-2, adv-cache-3, adv-mixer, adv-mixer-2), four to the 00:00 reading (adv-accept, adv-accept-3, adv-cache-2, adv-mixer-3). THE HASH LANE'S BRANCH ON MASTER: da2fc101 at 23:37 BST (ca3-v4-amend a7ff10a2; the full gate GREEN, 69 checks in 351 s): the derivation fix with AP-F8-4 and the regenerated public ledger, the no-prompt rule (publish-jobs.sh refuses --elevated; playbook-quit-check rule 3), the PC 1 and PC 2 job scripts, the Ember core-clock knob for 0.3.24 (ember.rs, state.rs, engine.rs; 18 Ember and 158 app tests green on box 2), the ca3-v4-uniform parallel census; igneum-pow against 017e7037 differs in generator.rs (the recipe refactor, every id and pin unchanged), emit.rs (the one print) and tests/derivation.rs only; the shipper's tip for 0.3.24's engine work is this master. THE 0.3.24 NODE PIN RE-CUT (the node lane, every gate green at 22:39:31Z): c9e385eb on release-0.3.24-node (47b9b229 with Devnet 3's class v5 floor at 32,400, epoch 9, the same object otherwise; pairing 1c420786): build 22:34Z rc 0 (igneumd 7a841b20..., /srv/artefacts/0324-c9e385eb/node-lane), consensus 134 at gate priority, core 175, exec 47, miner 28, p2p-flows 38, pow 19; the Devnet 3 canary set with the new digest d0d6a4754f3bfc4a173aeaddbab0e151583047283932b70cbb8e27878c115e91 (byte 6, override refused, handshake, the shared-devnet dialler and a 2720d8d2 node refused); the testnet canary on b2e856ed unchanged. The floor from the 22:30:17Z read (DAA 20,268, 1.0 DAA/s): about 01:52:29Z on 8 October (02:52 BST), holding for a move minute up to a publish at DAA 25,200 (23:52:29Z, 00:52 BST). The fast-time SUMMARY on c9e385eb asked; the fleet lane asked whether its hub or any reader depends on build-1's three old-object Devnet 3 nodes (the seed on 27632, the observer node, node1), whether they join the move or retire, and which 0.3.24 node the DAA is read from after it; the crossing read at 32,400 and the TESTNET_PARAMS v5-at-0 re-cut follow on that node. THE FAST-TIME GATE ON THE RE-CUT: SUMMARY PASS (cross-0324-c9e385eb) at 22:49:32Z (23:49 BST) on the shipped 0.3.24 re-cut c9e385eb (igneumd 7a841b20..., igneum-miner 1e209b9e..., igneum-pow at the freeze 1c420786), build-1 under lease pool class v5, 22:36:25Z to 22:49:32Z, every check green: rung 1 by signal at epoch 6 (22:42:54Z), class v5 by signal at byte 6 from epoch 8 at rung 1 (22:44:54Z, 4 of 4, 9,985 bps), 11 of 11 ids equal to the CPU verifier's, the stale node 86 of 86 refused with 0 accepted after the first refresh, the restart step across the boundary on a kept datadir resynced in 28.1 s with the catch-up done after 10 s and 0 of its own blocks during it, four sinks equal at 660, honest nodes 0 PoW rejections; record on v5-fasttime 76276be6, docs/design/class-v5-harness/fasttime/cross-0324-c9e385eb.json. The 0.3.24 move's gates left (the shipper's correction of this record): not F9 and F1's full 10^5 PASS (landing about 00:40 BST, too close to the 00:52 ceiling) but an F9/F1 interim line from the attack-pass lane read inside the five minutes before the minute showing 0 exhausted, 0 panics and 0 redundancy failures over everything drawn so far (16,003 seeds at 23:35 BST, max attempt 25), any non-zero holding the move, the full 10^5 the record line after; the minute named by the fleet on the last FETCHED plus ten once the build-server lane's c9e385eb pairs land. THE 61-ROW ERA READING (the v5 lane, box 2, 23:4x to 23:5x BST, docs/design/class-v5-harness/v5-listed-adv-cache-2-full.log): 0 of 61 refused by the 0.995 floor at the table attempts (the two real programs, 27 drawn-era, 32 devnet-era controls), every class v5 draw on the class v4 attempt; era-drawn-28 (id 5e9eb01efbbf653e, attempt 6, R 15, the worst of adv-cache-2's census at 1.7451x) reads its biased site 15 at 0.9969, over the floor by 0.0019; era-drawn-25 (1.3571x, R 21) site 11 at 0.9994; the eight over 1.2x span 0.9965 to 0.9997 while the eight few-item hot sets sat 0.003 to 0.013 under the line. Main's sentence opens AP-F8-6 and section 14 verbatim with the two-instrument reading under it. THE CLASS V5 ATTEMPTS CENSUS for 1.4.7 (1,000 f8 seeds through the chain draw, v5-attempts-census-1000.log, the crypto lane's form): 3,219 candidates, 2,219 rejected, per-candidate rejection 0.6893 (sub-version 3: 0.68), accepted attempt mean 2.219, 0 exhaustions, P(256 consecutive) 4.4e-42; first failing part (a') 83.4 percent of rejections, (a) 10.7, (b) 3.0, (c'') 1.2, (c''') 1.0 (0.7 percent of candidates, one in 140: the floor's own share, 0.045 on the attempt mean), (c) 0.7 together, (c') none; the 5.14 percent of class v3 that 1.4.6 quotes is the audit lane's to replace. Both on class-v5 at 3b1dffd6 with main's sentence (891dd008), the mirror's master merged (e0471019: AP-F8-1's update and AP-F8-4 taken, the program-id recipe form with the state tag, no conflict), the design page's pre-public scrub (the founder's name six times, gone), M35's status word and the regenerated public ledger; the push waits on the full gate and the pinned-packs test on the merged tree (the proof that e5a4ac5978462156 and the other ids still derive under master's recipe form). THE 00:00 BST READINGS (the crypto lane; the verified roll-up of all nine lanes in section 13 of in-house-pass.md on crypto-engage, every branch tip read from the mirror and igneum-pow identical to 017e7037 on each). adv-accept, tip a7c49399 (about 5.5 box-hours, 0 pod-hours): 182,646 distinct accepted programs drawn (18 percent of the 10^6); eight pass every part of the frozen rule and flag the live hot-set test at 2^24 (X at 0.1 percent +0.102 to +0.221, 1.54x to 2.24x), all in the lowest 34 stand-in-ratio seeds against 0 in 20 random; each about 1 MB of items holding 0.26 to 0.41 percent of reads, 1.002x at the largest; the mechanism a near-saturated source at one site mapped by the era stride to one fixed item (plus two lesser shapes); the exemplar reads the same under the class v5 dataset. Against the class v5 floor: 8 of 8 refused; 3 mild residuals missed (adv-cache-2's rotation class, a load_index question not a floor question); 6 clean programs refused among the 9 deepest (the 2.4 percent). Q2 BOUND (54 programs plus 17 reads, 0 disagreements). Row 90: 0.6787 per candidate, (a') 83.3 percent, 0 exhaustions, P 8e-44. Partial named: 18 percent of seeds, 54 live rows, row 90 at half; a longer pass adds rows of the same shapes, not a different answer, unless a seed reads a hot set over 1 percent of reads, which 182,646 draws did not produce. THE PER-LOAD CLASS CLOSED (the research lane, for main; clock readings UTC): the per-load shadow fix held for distinctness and then met the value-level requirement from adv-cache-2, and the construction did not survive it; the per-load 16 x 27 class is dead as a chain class. 22:44 the attempt verdicts on four seeds (igneum-genesis 0 of 32 accepted); 22:47 the 64-seed census under the full rule (duplicate lanes at a load row plus the one-count of every index bit per site over the 64 units, 6-sigma band): 22 of 1,621 candidates accepted (1.4 percent), 42 of 64 seeds exhaust the chain's 32 attempts (an epoch without a program); the first failing test per candidate: biased index bit 775, duplicate lanes 643, the base rule 110, (b) 43, (a) 28; candidate 0 of the class carries index bit 0 set in 40 of 1,024 addresses (z 29.5); 22:52 the suite green (64 + 5 + 7 + 4 + 19 + 2 + 7); the acceptance rule with BiasedIndexBit for this class and the tests pushed as the record, the file's 20.2a closed. The structural reason: 27 passes of a 16-instruction map right before a load is an iterated small function and collapses or biases the load's address register before any base instruction re-randomises it; the class v4 shape has 64 base instructions and 16 loads between its block and every load. Both exports were accepted only because the rule did not model the placement; their PC 1 rows stay as an energy reading of the placement, labelled unsound. Rank 4 and the USD 200 M capex row rest on a construction not shown to exist (chip model 5.11's clause marked so in this landing); the sound form is one pass of a 432-instruction sub-block per load (a program segment, not an iterated map), a new class to draw, accept and measure, not tonight's. Replicated by a second instrument: the class v4 shape on this pre-amendment generator carries the adv-cache-2 product bit at address bit R exactly in 14 of 17 drawn eras (one-count 250 or 780 of 1,024, z 15 to 19), 0 duplicate pairs across the eras. What stands from the two prototypes: the tile block (bit-exact on the Metal reference, the AVX2 verifier at 0.047 us per tile, the Apple emulation cost 35 to 78 percent) awaiting its 5090 rows; the per-load placement closed. THE SPEC REWRITE ON MASTER (the site audit lane, 8b834634 at 23:56 BST; gate GREEN on 64e2a91b, 71 checks; the igneum-pow suite green on the box for that commit with derivation.rs and spec_readback.rs): spec 01 sections 1.4.3 and 1.4.6.1 to 1.4.6.6 rewritten to 017e7037 with the 20-row constants table (ACCEPT_TAG, the window-cap literal, MAX_SATURATED as the first refused count with the 163 message noted) and the 6-row pinned-ids table with Devnet 3's full genesis hex; the shadow block in 1.7; the ninth era draw in 1.13.1; tools/ci/spec-constants-check.mjs in the gate (known-failed first, every Constant | Value | Where table, pending rows skipped while absent); igneum-pow/tests/spec_readback.rs (ids derived through the crate, each class v4 row drawn to its attempt); ledger AP-F8-5 after AP-F8-4; the ledger-page fix (both heading forms, the pass as its own section, known-failed self-test in the gate; AP-F8-1, AP-F8-4 and AP-F8-5 render on /ledger); the fud-ledger's two prize clauses and "paid independent cryptanalysis" removed at the source so the regenerated page carries neither (commit 90424d5a, merge 64e2a91b). A HARDWARE FACT IN DISPUTE, for main: tonight's 5080 efficiency rows came from PC 1 jobs (run-ca3-pc1-v4-eff-5080-20261007-b and -c), the audit lane's record reads the RTX 5080 and the Arc B580 on PC 1, the hash lane's 22:09Z device list on PC 1 shows the 5090, the 9070 XT and the 4070 only, and main places the 5080 and the B580 on PC 2; identity-check.sh's "PC 2" substitution text names cards and is left card-free until the PC 2 job's own --list settles which cards sit where. THE IDENTITY CHECK'S PC 2 TEXT (the CI steward, 00:05 UK on 8 October): tools/ci/identity-check.sh rewrites "PC 2" card-free as "the second Windows rig" (commit 40f2be54, merge 0d2cf334, gate GREEN 71 checks, identity grep 0 hits over 306 export files and 52 served pages); line 69's PC 1 list untouched; the reason recorded in a bash comment above the perl call. THE 32,400 FLOOR LOST (the node lane, 00:0x UK on 8 October): dn3-g1's chain read DAA 25,126 at 23:52:03Z and 25,169 at 23:52:38Z, so the publish DAA passed 25,200 at about 23:53:09Z with no 0.3.24 move made (build-1's three Devnet 3 nodes last restarted about 21:31Z on the 0.3.23 move; the old seed holds 38 peers on ba75bf6f; no move minute was named). The next boundary is 36,000 (epoch 10), about 02:52Z on 8 October (03:52 BST) at 1.0 DAA/s, holding for a publish up to DAA 28,800 (about 00:53Z, 01:53 BST). Two routes put to the shipper and main: the same re-cut script on release-0.3.24-node (program_class_v5_activation_daa 36,000, nothing else, the same gate set, about 20 minutes to the pin line), or the fleet names its minute first and the floor is cut from it in one go (publish DAA plus 7,200 to the next 3,600) instead of a fourth chase; the pin c9e385eb stands meanwhile. THE FLOOR RE-CUT FROM A NAMED MINUTE (the shipper, 00:1x BST on 8 October, under the slip rule main set with the object commit): the floor re-cuts once more to 39,600 (epoch 11, about 04:52 BST) from a move minute the shipper named: 02:00 BST on 8 October, or the fleet's last FETCHED plus ten if later but before 02:53 BST (DAA 32,400, the ceiling); the node lane's pin line in about 20 minutes with the new Devnet 3 digest; the F9/F1 interim read at 01:55 BST; the publish minute equals the move minute (the apps' entries at or after it); the fast-time SUMMARY PASS reruns on the new pin as part of its gate set; the cause of the lost floor named: the c9e385eb pairs and the two PC jobs unreported for forty minutes, so the fleet had nothing to point its move file at. "slot closed" on PC 1 still waits on the host job's exit. THE 0.3.24 NODE PIN AT 39,600 (the node lane): dfbd1e10 on release-0.3.24-node (both mirrors, 23:54:13Z) = c9e385eb with program_class_v5_activation_daa 39,600 (epoch 11), nothing else; pairing igneum-pow 1c420786; every gate green at 00:01:52Z (build 23:56Z rc 0 at gate priority, igneumd 4870ccf2..., igneum-miner aa8c2978..., /srv/artefacts/0324-dfbd1e10/node-lane; pow 19, consensus 134, p2p-flows 38, exec 47, core 175, miner 28); the Devnet 3 canary set (23:56:33Z to 23:58:13Z): digest b1ba78229b069dc395fa666638a686a66615eb760d251798adfa6a654a415f82 on igneum-devnet-3 from ba75bf6f, object version 6 stamped (block version 1538), the override file refused, shutdown 2,015 ms, two empty nodes handshaking on it, the shared-devnet dialler rejected, a 2720d8d2 node refused on the digest both ways; the testnet canary b2e856ed unchanged (byte 7, a live old-object testnet node refused). The cut's read: dn3-g1 at DAA 25,169 at 23:52:38Z (1.0 DAA/s), the publish DAA at the named minute 01:00Z about 29,211, plus 7,200 = 36,411, the boundary 39,600 about 03:53:09Z on 8 October (04:53 BST), holding for a publish up to DAA 32,400 (about 01:53:09Z, 02:53 BST). The one gate running: the fast-time pair on dfbd1e10 (about 13 minutes from its start). c9e385eb is void as a pin; the F9/F1 interim read armed at 00:55Z. THE TWO PC QUEUES AT 01:03 BST (the hash lane): PC 1's "slot closed" has not come (the shipper's 0.3.24 host job, the build-server lane's, took the slot at 22:13Z for an expected two to three minutes; nothing reported in 110 minutes); nothing of the hash lane's has run on PC 1 since 22:09:25Z; the v5 kit fetch and the 9070 XT v5 bench are prepared and unpublished (tools/ca3-v4-amend/pc1-publish-20261007.sh, steps v5-kit and v5-amd), so no 9070 XT class v5 fingerprint exists yet; the lock protocol holds unless main says the lock-free pair goes ahead of the silent host job. PC 2's "clear" has not come either (the 0.3.23 take 3 smoke and the scheduler proof unreported by either lane); the Intel job is prepared and unpublished. THE HARDWARE FACT, read from tonight's PC 1 lines: nvidia-smi on PC 1 lists GPU 0 RTX 5090 (bus 01:00.0) and GPU 1 RTX 5080 (bus 0D:00.0); its OpenCL list carries the RX 9070 XT (gfx1201) and the integrated gfx1036 and no Intel platform; so the 5080 is on PC 1 (the audit lane's record right, the 22:09Z device-list summary short by one card) and the Arc B580 is not, which agrees with main's word that it is PC 2's eGPU; the kits row, the bench notes and identity-check's card-free PC 2 text stand on that. The locked PC 1 jobs stay parked (the 5080 full grid, the third 5090 pass, SM-sparse, the microbench and packs knee states, the two Ember tunes, the hot-table ldcs rows); the lock-free CA4 rows queue after the v5 bench on the same "slot closed". THE 00:00 BST READINGS, THE OTHER THREE (read by the crypto lane from each branch's report on the mirror at 01:03 BST; the roll-up section 13 of in-house-pass.md at crypto-engage c84ba51b with adv-accept's reading at 1b4e07ff; all nine branch tips read back from the mirror and igneum-pow IDENTICAL to 017e7037 on every one: adv-mixer d2ba3134, adv-mixer-2 2a632579, adv-mixer-3 4ebe2455, adv-cache 555c3e42, adv-cache-2 9384ee09, adv-cache-3 9452c0bf, adv-accept a7c49399, adv-accept-2 92168536, adv-accept-3 0c150e3c). adv-accept-3 (exhaustion or steering of the draw), tip 0c150e3c, every sweep ended 23:05 BST, about 3.3 box-hours, 0 pod-hours: Q1 exhaustion BOUND (per attempt accept 0.323, reject 0.677 ((a') 0.568, (a) 0.079, (b) 0.022, dynamic parts about 0.009), geometric histogram, P(exhaust) 0.677^256 = 4.6e-44, 0 of 16,337 seeds at the cap); Q1b the last resort FINDING (correctness; the mirror fired at cap 256 byte-identically; of 3,000 last-resort programs the real rule rejects 271, 9.0 percent: 251 by (a), 14 by (b), 6 by (c) distinct sum; handed out unchecked; unreachable; closed in class v5 by 8ca66afa, AP-F8-3); Q2 steering BOUND (45 of 48 planted rows fired, the real rule rejects every effective plant by (a'); 975 seeds at the first part, min ratio 0.998, 18 of 18 chain re-draws equal); Q2b the price of a seed property at 1 in 10^6 tries is a shadow block with 38 multiplies of 256 against a mean 74, about 2 to 3 percent of the f = 1 chip's energy per hash, the load critical path worth nothing at the memory activate ceiling; Q2c the 256-unit ratio is noise as a selector; Q3 program id FINDING (documentation: the "sub/" || 3_le16 suffix omitted from program.json and spec 1.4.6; a text-derived implementation computes 30956569d8f3d8d7 for Devnet 3 against the pack's fce15bf61030be57; 0 collisions over 10^7 pairs; fixed as AP-F8-4 at da2fc101); Q4 determinism DONE (the (c'') f64 compare never disagrees with the integer rule on any of the 2^20 + 1 values, margins 0.32 to 0.44 counts; a second interpretation agrees on 5,748 of 5,748 verdicts of 1,792 seeds); Q5 the era lever BOUND (400 eras, no stride under NAF weight 7, all 31 rotations, 354 distinct interleaves; epoch 0's accepted attempt is 3 under every era, so the era moves the address map, not the program). Partial named: the steering sweep at 975 of a planned 10^5 seeds (about 8 box-hours more at 32 cores). adv-cache-2 (the hot-set attack), tip 9384ee09 at 23:52 BST, about 2.2 box-hours by wall times threads over 96 (the boxes at load 400 to 600 for the first two hours), 0 pod-hours; two shards still queued at 00:00 (lines-2e30-s2c, warps-devnet-2e25-v2), named partial: Q1 the line index PASS (pooled 16 days; segments max +4.84 sigma against a control's +4.24, lines +5.61 against +5.35, chi2/dof 0.99937, top 0.1 and 1 percent of lines 1.0003x and 1.0002x of control; the 2^35 + 3 x 2^33 census all PASS; 0 mirror mismatches); Q2a the real programs PASS on the hot-set test (devnet at 2^26 1.0002x; Devnet 3 at 2^26 items 1.0071x, lines 1.0000x) with the FINDING at Devnet 3 site 0; Q2b all 64 programs done, every one clear on the hot-set test (items 0.9993x to 1.0075x of the windowed control) but the site class as recorded above (13 of 27 drawn-era over 1.04x, 8 over 1.2x, worst 1.7451x; the v5 floor refuses 0 of 61; AP-F8-6); Q3(1) steering by t PASS (worst cell 3.95 sigma in 2 x 2,112 cells); Q3(2) the weak-day scan PASS over 16,384 days (2^30 derivations in 707 s; worst per-day max bucket +8.13 sigma against the control's +7.78; the plant fired at +1,090); Q3(3) the window layer: the exact distribution matches the 4,096-program census to four digits (top quarter mean 0.3382, top half 0.5811), with a FINDING against the chip model's table: the f = 0.25 and f = 0.5 partial-store rows overstate the recompute share by up to 1.8x at f = 0.5, the full-store (f = 1) verdict unchanged (a correction owed in chip-model-v3's partial-store rows; no served number rests on f under 1); Q4 the prices: the only measured excess over f is the window layer's and the line reference multiplicity (a hottest-lines half store hits 57.8 percent instead of 50 at a higher miss cost than the stride). adv-mixer-3 (the statistical distinguisher and round margin), tip 4ebe2455 at 00:41 BST, still RUNNING at 01:03 (Q3 and Q4 at k = 8 on day 20729, queue 07 in the pool, the SAT ladder at k = 3 timed out; the total box-hours the lane's to give): Q1 the exhaustive round-0 line-index census over all 2^32 t PASS to k = 8 on days 20729 and 20733 and at k = 2, 3, 4, 8 on 20730 (z within 1.5); Q2 single-bit avalanche FINDING at k = 1 (354 and 266 holes, 130,000 cells beyond 6 sigma, the known one-application diffusion), PASS from k = 2 at 2^24 (0 holes, worst z under 5.3 through k = 8); Q2b the t-bit avalanche the same shape; Q3 differential multiplicity over 576 low-weight differences FINDING at k = 1 (695 and 537 deterministic output bits), PASS k = 2 through 7, k = 8 running; Q4 and Q4b linear correlations PASS from k = 1 (worst c 0.00046 to 0.00062, z under 5.1); Q5 rotational-XOR PASS from k = 1; Q6 SAT: k = 1 SATISFIABLE in 137 s (t = 0x49880000 verified through the real code), k = 2 and 3 TIMEOUT at the one-hour cap. The round margin as it stands: no statistic survives 2 of the 8 applications between reads; a chip gets nothing from the k = 1 findings because every read sits behind 8. The lanes' own lines go into section 13.1 as they arrive. THE LANES' OWN 00:00 LINES (adv-accept-3 and adv-mixer-3, 01:0x BST, in section 13.1 of in-house-pass.md): adv-accept-3's P(exhaust) refined to 1.0e-43 per epoch seed from 62,240 full-rule candidates plus 3.0e6 static candidates; Q2 steering BOUND over 19,975 full-rule and 1e6 static seeds, no property buying over about 1.03x at 1 in 1e6 tries; a second documentary FINDING: an implementation written from the spec text (not the code) at 017e7037's spec differs on 264 of 400 epoch programs, the same text-against-code gap as the id suffix (the audit lane's rewrite 8b834634 with spec_readback.rs is the fix; the proof that it closes this is a re-run of the text-derived implementation against the rewritten text, asked); a plant note: the floor-0.97 known-failed variant did not fire because the (c'') ratios are bimodal (accepted 0.989 to 0.999, rejected 0.814 to 0.966), replaced by a single-pass (a) variant that did; 3.3 box-hours, nothing running. adv-mixer-3: about 3.0 wall-hours of sweep plus 4 single-core CaDiCaL hours; the round margin stated as 6 of 8 applications between reads and 70 of 72 per item on every measured statistic, the k = 1 effects one mechanism (the lowest-set-bit trail through one application, dead once both addends carry a difference), nothing saving one application against 9,360 ops per item; still running at 4 cores on build-1 (2^27 and 2^28 avalanche rows, finish about 03:00 BST) and the day-20733 SAT ladder on build-2 (about 03:45 BST); not attempted: multi-bit linear masks and a MILP trail bound. adv-cache-2's own line still owed. ADV-CACHE-2'S OWN LINE (01:05 BST, tip 3f50d6c4; section 13 of in-house-pass.md now carries every lane's reading in its own words plus the verified roll-up): the drawn-era prevalence read on the SAME 32 base programs is 2 of 32 under the devnet era against 16 of 32 under drawn eras (8 over 1.2x, worst 1.75x), the mechanism carried by rotl(x times M, R) into the item index unless R is 29 or 30 (2 of 31 rotations), with a sub-class of warp-uniform sources once in 16,000 warps; the window layer's price restated: a chip holding the hottest f of items serves 0.4219, 0.7188 and 0.8907 of reads at f = 0.25, 0.5 and 0.75, so the chip model's partial-store rows overstate the recompute share by up to 2.3x on these programs, the f = 1 verdict unchanged (the correction to chip-model-v3's partial-store rows is the coordinator's next commit); partial named (the drawn-era windows census of 4,096 and one line shard in the pool); the longer-pass line: the biased-site rate per era in closed form (the R in {29, 30} rate 2 in 31) and a 2^28 read of the worst site. Nothing of the pass stands between the pool and a higher-class job except two pre-emptable shards on box 2. THE SPEC-TEXT RE-DERIVATION ORDERED (01:06 BST): adv-accept-3 re-derives its 400 epoch programs from the rewritten spec text alone at master 8b834634 (1.4.3 to 1.4.6 grown from 79 to 198 lines with the constants and pinned-ids tables), lease pool 16 --min 8 class adv, row Q4c in its report; the expected reading 0 of 400, any non-zero naming the diverging sentence to the audit lane; the proof that AP-F8-5 closed the text-against-code gap. THE CHIP MODEL'S PARTIAL-STORE ROWS carry a second correction (section 5, 8 October 2026) from adv-cache-2's window-layer reading: a chip holding the hottest f of items serves 0.4219, 0.7188 and 0.8907 of reads at f = 0.25, 0.5 and 0.75, so the uniform-store rows overstate the recompute share by up to 2.3x; the f = 1 row, the SRAM column and the full-store verdict unchanged, no served number on f under 1. THE CLASS V5 PACKS TEST ON THE MERGED TREE (the v5 lane, 01:0x UK): the job ran on box 2 the minute two adv-accept holders ended (65 cores; no lease fault, plain starvation before); 19 passed, 1 FAILED: v5_pack_is_the_v4_program_over_the_state_leaves (tests/packs.rs:977), the byte-for-byte compare of every pinned pack file with the crate's export. The ids are EQUAL (v4-genesis exports a217c7f698880830 as pinned; the state tag rides in master's recipe form unchanged); what differs is the program_id_derivation TEXT in program.json, which master's export (the hash lane's AP-F8-4 read-back form) now writes as "... || attempt_le32 || 'sub/' || sub_version_le16" for generator 4 while the pinned packs carry the pre-suffix wording. Disposition: the three pinned packs re-exported from the merged crate (text only; the ids, kernel texts, leaves and the fingerprint 82b19cbde8557ea5 must come out byte-identical, proved by the same test); the CLI rebuilding on build-1 from 51aa5bc4, the export from the box's IGSD1 streams, the packs test and the full suite on box 2 at 16 cores, then the push; readiness about 01:35 UK. The 0.3.24 kit zip (packs-ca3-v5-20261007T221001Z.zip) carries the old derivation text in its program.json files: a text field only, no id, kernel or fingerprint change, so the kit stands for 0.3.24 and the shipper is told; the re-exported packs go in the next kit. THE ONE 0.3.24 KIT, NAMED for the shipper (01:1x BST): packs-ca3-v5-20261007T183921Z.zip, sha256 e6c088bb34fecdc3ff297dbb06438a14ade7d8c55273357726d28f7a1334a25e, byte-identical to the frozen 1c420786 the pin pairs with; the fleet keeps placing it. The 23:11 zip packs-ca3-v5-20261007T221001Z.zip (sha256 4aaf9b9e..., /srv/artefacts/packs/ on build-1, from class-v5 7f58af97) carries the same packs, ids, kernels, leaves, fingerprint and derivation text and differs only in the merged kit host code and scripts beside the packs; it is the bench lanes' kit for the fingerprint jobs. The coordinator's earlier line naming 4aaf9b9e as the 0.3.24 kit was wrong and is corrected here. THE SPEC-TEXT READ-BACK RUNNING (adv-accept-3's Q4c, 01:11 BST on build-2, lease pool 16 --min 8 class adv): the same 400 epoch seeds re-derived from the spec text at master 8b834634 alone (1.3, 1.4.2, 1.4.3, 1.4.6, 1.6, 1.7, 1.13.1; a fresh text interpretation), compared field for field with the chain draw; the count about 01:21. One sentence already named divergent before the count: 1.4.6 part (c) cites dataset_elem(idx, S[0], S[1]) "of verify.rs" without stating its six operations, so part (c) cannot be computed from the text alone and the derivation takes that one function from the crate; the audit lane is to state the closed form's six operations in the text or the constants table, else 1.4.6 stays code-dependent on that line. A NINTH LIVE HOT SET (adv-accept, 01:12 BST): seed 228763 (id 2c4be0f6dc44c423, stand-in 0.9820) at 2^24 (X at 0.1 percent +0.118, 1.82x the window model), its single hottest item 0xe2cc96 at 1,218,380 reads, 0.057 percent of ALL reads, the largest single item of the pass (40x 100767's), from a NON-saturated source r0 at site 9 (the sel register), saturated-source share 0.000: the third shape at scale, a value-level concentration neither (c') nor a saturation test can see by construction; its 2^20 ratio against the 0.995 floor lands in minutes and decides whether the floor's instrument reaches it (if missed, the exemplar for the next class's non-saturated case). 638990 reads 1.51x beyond the gate with one item at 0.027 percent (r0, no saturation), no hot set; 623492 clean. Tally: 9 hot sets in 37 tail seeds against 0 in 20 random, 269,250 programs drawn; the price unchanged at 1.002x (0.27 percent of reads on 1 MB; one item 64 bytes). The public sentence's "eight of eight" moves to "nine of nine" or gains the first miss when the ratio reads. THE FLOOR REACHES THE NON-SATURATED SHAPE (adv-accept gap-tail3, 01:13 BST): seed 228763 reads minimum site 9 at 0.9809 at the 2^20 sample, the lowest of the pass, REFUSED; 638990 site 2 at 0.9872, REFUSED; 623492 (clean live) site 0 at 0.9922, REFUSED, a seventh false refusal. Final tally over everything the lane read at 2^20: 9 of 9 live hot sets refused (0.9809 to 0.9919), both single-item programs refused, 7 clean-live programs refused and 1 passed among the 12 deepest 256-unit seeds, 3 mild residuals missed at about 1.0004x. The reading: the distinct-index ratio reads any few-item concentration whatever its source, saturated or not, and misses only the diffuse era-stride excess; the class v5 floor closes the hot-set class entire at the 2.4 percent clean-rejection cost; the next class's value-level test is for the diffuse class alone. The public sentence reads "nine of nine hot sets refused" from here (the v5 lane's follow-up cfce57ea rides its push; AP-F8-1 on master updates with the next record commit). THE FAST-TIME GATE ON dfbd1e10: SUMMARY PASS (cross-0324-dfbd1e10) at 00:12:57Z on 8 October (01:13 BST), the shipped re-cut's binaries (igneumd 4870ccf2..., igneum-miner aa8c2978..., igneum-pow 1c420786), build-1 under lease pool class v5, 23:58:56Z to 00:12:57Z, every check green: rung 1 by signal at epoch 6 (00:05:37Z), class v5 by signal at byte 6 from epoch 8 at rung 1 (00:07:46Z, 4 of 4, 9,985 bps), 12 of 12 ids equal to the CPU verifier's, the stale node 95 of 95 refused, the restart step across the boundary on a kept datadir resynced in 36.2 s with the catch-up done after 11 s (4 IsInIBD refusals of its own miner during it, 0 of its blocks accepted), four sinks equal at 661, 0 PoW rejections on the honest nodes; record on v5-fasttime 0a09eb78, docs/design/class-v5-harness/fasttime/cross-0324-dfbd1e10.json. Every gate on the pin is green; the move waits on the pairs on the dl host, the last FETCHED plus ten, and the F9/F1 interim read. THE RE-EXPORT READ (the v5 lane, box 1 with the merged crate ac285733): the three pinned packs' only difference was program.json's program_id_derivation text (generator 4 now "|| 'sub/' || sub_version_le16", generator 5 the class recipe "igneum-program-rw/ ..."); ids, kernel texts, leaves.bin, vectors and the fingerprint 82b19cbde8557ea5 byte-identical; the pinned packs carry the merged text; the full gate and the full igneum-pow suite with the packs test and spec_readback running on that tree, the push and commit string about 01:45 UK; main's sentence at nine of nine on AP-F8-6, section 14 and spec 1.4.7.2 at class-v5 b5d6368d (nothing with eight of eight reached the mirror). AP-F8-1's two eight-of-eight lines on master move to nine in this record commit. THE MOVE'S SOURCE (the shipper's ruling at 01:05 BST, corrected to this record at 01:1x): the 02:00 BST move does not wait on the build-server lane's pairs; that lane is dark (nothing published since 23:05 BST, nothing answered since 00:17), so the fleet moves EVERY Devnet 3 node from the node lane's dfbd1e10 pair at /srv/artefacts/0324-dfbd1e10/node-lane on build-1 (igneumd 4870ccf2, igneum-miner aa8c2978, the pair every gate ran on, native glibc 2.39 on every fleet box), the way dn3-g1 and g2 moved at 22:30; the fleet's puller fetches from build-1, not the dl host. The move waits on the fleet publishing the dfbd1e10 move file and naming the minute (asked 01:05) and the F9/F1 interim at 01:55. The hive and the Windows pairs are the dark lane's loss for tonight unless main gives the shipper the word to build them (asked 01:06); the Mac entry publishes at the minute regardless; if the fleet has not published the move file by 01:40 BST, main and the coordinator hear it with the clock. THE PC 1 LOCK VOID, THE V5 AMD BENCH PUBLISHED (the hash lane, 01:1x BST): the shipper's 0.3.24 host job was never published to the jobs file, so the slot was void (the shipper's "slot void" at 01:05 BST); the v5 kit fetch landed on both PCs at 00:12:06Z (919,273 bytes, sha256 ok); run-ca3-pc1-v5-amd-bench-20261007 published 00:14:19Z (the 9070 XT by name, about 3 minutes, lock-free), its start line printing app_version, so the 0.3.20 or 0.3.23 reading of PC 1's app comes with the fingerprint; PC 2's Arc job needs only the shipper's "PC 2 clear". PC 1's app had NOT taken the 0.3.23 kit as of the last reads (every job log through 21:46Z app_version 0.3.20; the install folder's exe igneum-app 0.3.20, mtime 12:24:42Z, sha256 0443ae17...). The update-return lane (a22d765a2e0355a9f) last spoke at 23:0x BST: the helper workaround for 0.3.20 scripts (truncate cmd.txt, restart the task, wait for helper.alive, then write; or four leading " dev " padding lines), the locked jobs held as they are, power-helper-24 b9a72b9b merged into release-0.3.24 (daa7427b: a silent change becomes a logged line, the helper writes its exit reason), install-close-23 4ad6c199 for 0.3.23's take 3, the re-probe job when PC 1's app has taken the 0.3.23 kit; nothing since. THE SPEC-TEXT READ-BACK PASS (adv-accept-3 Q4c, 01:11 to 01:15 BST on build-2 at 16 cores; report section 6.5 on build/adv-accept-3, log 983-textderive-8b834634.tsv, pushed): the spec text at master 8b834634, implemented fresh without the crate's generator or rule, reproduces the same 400 class v4 epoch programs as the code with 0 of 400 differences (every instruction, the chosen attempt, the id, the rejection sequence); the 264-of-400 divergence against the text at 017e7037 is closed, so AP-F8-5 reads fixed on a measurement. The one remaining gap: 1.4.6.4 names dataset_elem "of verify.rs" without its six operations, so parts (c), (c') and (c'') still take that function from the crate; the audit lane's one-sentence closed form (asked 01:1x) closes it, and the read-back re-runs on the new text. THE AMD CLASS V5 FINGERPRINT (PC 1's RX 9070 XT, gfx1201, beside the miners, lock-free): 82b19cbde8557ea5 at 01:16:14 BST, equal to the kit e6c088bb's on Metal, Apple OpenCL and CUDA, self-test PASS, the v4-genesis control 892b6d55a7ddcfcb PASS; the 0.3.24 kit stands on four platforms; Intel waits on PC 2 (held until main's word, since the 0.3.23 take 3 never ran there); PC 1's queue continues with the CA4 unlocked rows. The kits row reads: Metal, Apple OpenCL, CUDA, AMD equal; Intel not measured tonight. THE UPDATE-RETURN LANE'S THREE READINGS (01:17 BST, from the live manifest and the intake): (1) 0.3.23 take 3 (install-close-23 4ad6c199) never reported; the live manifest igneum-app-latest.json reads 0.3.23 published 20:37:44Z with platforms = {mac} only, NO Windows entry, so neither PC has anything to take through its update path; PC 2's app run is still take 1's relaunch from 21:08:43Z (997 uploads, last 00:16Z); (2) PC 1 will not take 0.3.23 unattended tonight for want of a Windows entry; its run win-ae432dc7-20261007-160110 (0.3.20) never restarted (2,376 uploads, last 00:16Z), mining 18.96 MH/s on the 9070 XT; when a Windows entry is published the 0.3.20 engine's OTA takes it with no hand; the 21:41:32Z helper.ps1 write was not the prompt path (0.3.20 writes that file unconditionally), so no screen is owed in the morning for it; (3) the re-probe job (relay/playbooks/pc1-helper-reprobe.ps1 on power-helper-24 69f3c733) waits only on PC 1's exe becoming 0.3.21 or later; the 0.3.20 workaround is cleared to run tonight as a lock-free job so the locked grids go ahead: per grid job, before the first command, empty sweep\cmd.txt, Stop-ScheduledTask and Start-ScheduledTask 'Igneum Power Helper', wait until helper.alive is within 4 s, then write the lines with climbing sequences (in 0.3.20 the skip is the line count at the helper's start, fixed for its life); the helper idle-exits 20 minutes after its last command and the next start must begin over an empty file again; never pad after a command. The coordinator's order to the hash lane on it: the locked grids proceed in the earlier order (the 5080 full grid, the third 5090 pass to the driver's floor, SM-sparse, the two Ember tunes, the hot-table ldcs rows), each with its restore step, under the no-prompt rule; a Start-ScheduledTask that reads the 0x800710E0 refusal again stops the job and reports, nothing escalates. THE LOCKED GRIDS UNDER THE WORKAROUND (the hash lane, 01:2x BST; commit 24f9858e on the mirror): the three lock scripts carry the cleared sequence (empty sweep\cmd.txt, Stop- then Start-ScheduledTask 'Igneum Power Helper', helper.alive within 4 s with a 60 s cap, then dev + command with climbing sequences; repeated before any write when helper.alive is older than 10 s; a refused start 0x800710E0 or no heartbeat stops the lock path with the text on RESULT lines, nothing escalates; no padding; each grid job ends with rgc through the same sequence and the applications clock read back). PC 1's app_version on the v5 bench's start line: 0.3.20 (no Windows 0.3.23 published, nothing to take). The CA4 SM-sparse job run-ca4-pc1-ca4sparse-5090-20261007 runs since 00:20:40Z on the earlier padded script (unlocked rows first, then its 1,300 knee attempt; about 25 to 50 minutes); then in order on the shipper's acks: the 5080 full grid as run-ca3-pc1-v4-eff-5080-20261007-d, the third 5090 pass (1,100 MHz down), the microbench and the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows; the 5080 grid's knee and best points to the site audit lane for row 17 as read. THE ATTEMPTS CENSUS COMPLETE (adv-accept row 90, 01:34 BST, 20,000 seeds, closing the partial named at 00:00): 42,711 rejected candidates; (a') 83.5 percent, (a) 11.6, (b) 3.0, (c'') 1.1 (459 candidates), constant bit 0.4, saturated 0.3, (c') 0.05, distinct 0.04, lane-constant and bias 0; per-candidate rejection 0.681, flat across attempts 0 to 3 (the halves agree to a tenth of a percent); accepted-attempt mean 2.136, max 28; 0 exhaustions; P(256 consecutive rejections) 2e-43 per seed. The number for spec 1.4.6: under sub-version 3 the per-candidate rejection is 68.1 percent and the expected attempt 2.1. adv-accept's shards run on in the pool's gaps under the mechanical yield; the box-hours cross 8 later tonight. CLASS-V5 LANDED ON BOTH MIRRORS (the v5 lane, 091a0758 at 01:40 UK): the full pre-push gate GREEN at 71 checks (stamp on 48d38493, the last code change); the igneum-pow suite on box 2 (74 unit, derivation 2, derive 7, mixer 4, packs 20 with the three pinned packs byte-identical to the merged crate's export, so e5a4ac5978462156, 7c54302b487340a1, a217c7f698880830 and 82b19cbde8557ea5 hold under master's recipe form, recheck 2, scratch 7, spec_readback 2); spec-constants 28 rows agreeing; identity grep 0 hits. Carried since 61588347: main's sentence at nine of nine on AP-F8-6, section 14 and spec 1.4.7.2; the 61-row era reading and the class v5 attempts census on the spec, the page and the ledger; AP-F8-3; spec 1.4.7 and 1.8.6 with the constants and id tables; the AMD fingerprint row; the kits branch and master merged; two corrections the proofs found: master's program_id_derivation text lacked the class v5 rung-0 arm (the v5 packs' text named the class recipe while the id was the plain form; the arm added to the TEXT, re-exported, ids unchanged; a post-freeze change on the class-v5 line, so 0.3.25's pairing, never 1c420786's), and the public-export scrub (the founder's name six times on the page, the zone name in three files; gone). Incoming to the page: the Arc fingerprint, F9 and F1. THE MOVE FILE NOT PUBLISHED (the shipper, 01:41 BST): build-1's /fleet/move.json still names commit 2720d8d2 with the 22:30 BST minute; no FETCHED count, no named minute; the fleet lane (ac055d60427caab99) has answered nothing since its 22:4x report (asks at 01:05, 01:16 and 01:41; its task output last written 22:21 BST, its last action a hand read of dn3-g1's proven share), the second dark lane beside the build-server lane (last written 22:36 BST). So 02:00 BST cannot hold; the 02:53 BST ceiling (DAA 32,400) stands only if a signed move file lands at once and the 34 pullers fetch inside forty minutes; main has the clock line with the two options (wake or replace the fleet lane; or a fourth re-cut from a morning minute, the Mac entry standing down with it). The publish record's shape stands: the Mac entry at the minute (staged, DMG 1aa301cc, both folders, armed); the hive and the Windows pairs on main's word; the pairing 1c420786, 091a0758 0.3.25's. Every other gate on dfbd1e10 green and recorded. THE RUNG-0 ARM CONFIRMED (the v5 lane, 01:4x UK): 987e90e8 touches only Program::program_id_derivation, the text in program.json; Program::program_id untouched (the v5 rung-0 plain-form branch since the freeze); the crate at 091a0758 and 1b5684ec (master 35602b30 merged, pushed 01:41 UK) derives every pinned id byte for byte (packs 20 on box 2 comparing all three pinned packs' files including program_id and leaves.bin; spec_readback 2); the shipper told 091a0758 and 1b5684ec are 0.3.25's pairing, 0.3.24 on 1c420786. THE SM-SPARSE JOB (run-ca4-pc1-ca4sparse-5090-20261007, exit 0 at 00:41:53Z, 1,171 s, the 5090 alone, every fingerprint matched, the Power Helper answering every command on the padded write, the card left unlocked at 2,855 MHz): the SM-sparse reading does NOT exist; the research lane's worker ran its base kernel on every variant row (its race line "race 0 ms variant base" on all 48 rows, no NVRTC compile text), so --bench never honoured --variant sp-w32; the sparse rows equal base in rate and drift in watts with the card's heat only; the rerun waits on the research lane's exe honouring the flag. What stands: a repeat of the efficiency pass at two states, 32 s rows, the card alone: v4 unlocked 137.07 MH/s at 465.5 W (0.294 MH/W), at 1,300 MHz 134.26 at 309.9 W (0.433; 155.6 W back for 2.05 percent of rate); v3 unlocked 136.71 at 331.6 W (0.412), at 1,300 134.03 at 219.4 W (0.611; 112.2 W back for 1.97 percent); the v4 premium 133.9 W unlocked, 90.5 W at the knee; the three power fields agree within 0.2 W on every row (power.draw = instant = average on driver 617.14), which settles the field question on PC 1's side and leaves the 5080's 110 W gap to the fleet's rented card's sampler. Next on the shipper's ack: the 5080 full grid (-d) through the cleared helper sequence, the third 5090 pass, the microbench, the seven packs, the two tunes, the hot-table ldcs rows (kit and job at 292fcc75). THE --variant FAULT FIXED (the research lane, counter-asic-4, UTC clocks on 8 October): 00:44 the fix (a --bench with --variant runs the pinned race and installs the named kernel; the RESULT line carries variant=, sparse_blocks=, block_warps=; a served kernel other than the requested one prints variant_not_installed); 00:46 the known-failed test on build-1 against the real class v4 pack, no card (base: race off, 524,288 blocks of 32, "variant base"; sp43-w32: race on, 43 sparse blocks of 32 warps, the rewritten kernel with the nonces argument and the unit function, 43 blocks of 1,024; PASS; before the fix both read the base shape); 00:46 the Windows exe igneum-worker-cuda-ca4sparse3.exe sha256 0ba97edcd5c46a302a7ff5ddd1bbb1e493ca15f64d0757820ed645972df3bb56, mingw exit 0; the commit after 2d0013d1; the hash lane has the sha, the test's lines and the rerun's job shape (the same 48 rows, the race line per row); the op-mix re-weight stays behind the SM-sparse reading, the served 3.4x standing; the clean efficiency repeat in the file's 20.3a (6.6 pJ per counted op). THE SPEC'S LAST CRATE-DEPENDENT SENTENCE CLOSED (the site audit lane, master 56eebc0d at 01:49 BST, gate GREEN on c2c92eab, 71 checks; spec_readback now 3 tests): 1.4.6.4 states dataset_elem in full (the eight operations, the three constants, 32-bit wrapping) with two pinned vectors (dataset_elem(0x00000fed, 0x9E3779B9, 0x7F4A7C15) = 0x5c7dabd2; dataset_elem(0x0fffffff, 0, 0) = 0x7662c1ec) that spec_readback.rs reads from the text and checks against the crate, so part (c) computes from the text alone (34845c47); 1.4.6.5 names the class v2 figures as class v2's and carries the shipped rule's own census sentence (20,000 seeds, 68.1 percent rejected per candidate, the per-part shares, mean attempt 2.1, max 28, 0 exhaustions, 2e-43). The text-derived re-run on this text is the proof it is sufficient end to end (asked of adv-accept-3). THE MOVE FILE STAGED (the shipper, 01:5x BST): id mdfbd-1, commit dfbd1e10, want_digest b1ba7822, both pair slots on build-1's served tarball dfbd1e10-node-lane.tgz (e59ed0e6), at_epoch 0, signed with the fleet key on the Mac and verified against the fleet's public key in the puller's namespace; the read-back on placing it: the served file's id by curl and the first FETCHED on the relay intake; the 34 pullers fetch inside their one-minute timers (27 MB from build-1), the last FETCHED about five minutes after the file, the earliest minute ten after that. THE REAL LATEST-PUBLISH CLOCK: the file alone halts every miner on the restart, because each box's pack gate PAIR_MINER_SHA16 lacks aa8c2978 and the puller does not carry the file's miner sha into the restart environment; so route (A) also needs one ssh line on each of the 34 boxes before the minute with the fleet's tooling (the fleet lane's, or the shipper's on main's word). Absent main's word by 02:15 BST the shipper stands the Mac entry down under the ceiling rule (no app alone on b1ba7822) and 0.3.24 becomes a morning minute with a fourth re-cut. ROUTE (A) STAGED TO ONE COMMAND (the shipper, 01:5x BST): the gate script r0324/move/pair-gate-aa8c2978.py in its scratch (dry run by default, apply on the literal argument, the fleet's own Box helper and label list, nothing restarted); the dry run read 33 of 35 boxes, every one carrying the old gate list with fb147dd1 last and aa8c2978 absent, no env-last override; unreachable dn3-relay and p2-4090-1b (dead Vast proxies; they fall off at the move and rejoin by the pull); the apply about 90 s for the 33 with each gate read back and counted. THE F9/F1 INTERIM (the attack-pass lane, read at 01:5x BST): 71,292 seeds, 0 exhausted, 0 panics, max attempt 30; F1 0 failures at 2 h 23 min; the move's gate reads clear. On main's (A): apply 02:00, the file placed 02:02, the last FETCHED about 02:05, the minute 02:15 BST; main has the clock. Nothing applies before the word. THE SPEC TEXT SUFFICIENT END TO END (adv-accept-3 Q4d, 01:52 to 01:57 BST on build-2 at 16 cores; report section 6.6 on build/adv-accept-3, log 984-textderive-56eebc0d.tsv, every row equal to its Q4c row): the spec text at master 56eebc0d, implemented with nothing from the crate (text.rs: 0 igneum_pow imports; dataset_elem from 1.4.6.4, its two pinned vectors checked at start), reproduces the same 400 class v4 epoch programs as the code with 0 of 400 differences on every field; no sentence of the generator or acceptance sections needs the crate; the documentary finding (AP-F8-4, AP-F8-5) closed in full on two measurements; the lane at its end, 3.35 box-hours in all. F9 AND F1 AT 00:59Z (class v5 at 1c420786, pairing e5a4ac5978462156, build-1): F9 73,691 of 100,000 chain-shaped seeds written, 0 exhausted, 0 panics, 0 past attempt 31, max attempt 30; the attempt histogram 23,119 / 15,981 / 10,805 / 7,547 / 5,181 / 3,415 / 2,439 / 1,653 / 1,119 / 744 / 529 / 389 / 258 / 152 / 113 / 72 / 54 / 40 / 31 / 14 / 15 / 5 / 2 / 6 / 2 / 4 / 1 at 26 / 1 at 30, r about 0.69; the 10^5 about 01:30Z (02:30 BST). F1: the 10^5 redundancy census at 2 h 28 min under its lease with no end marker (18 minutes on an idle box; under tonight's load no minute named); its panic path live and empty, 0 failures the honest reading. Both land as record lines, then the board's close per item on sub-version 3 and class v5. AP-F8-5 ON TWO MEASUREMENTS (the site audit lane, commit 116e6055, master 5c77a7ac at 02:05 BST, gate GREEN 71 checks): the row carries Q4c (8b834634, 0 of 400 with one crate function, section 6.5, log 983) and Q4d (56eebc0d, 0 of 400 with no crate import, section 6.6, log 984); the public ledger and the ledger page regenerated; nothing open in the spec or the ledger on the audit lane's side. THE 5080 FULL GRID (run-ca3-pc1-v4-eff-5080-20261007-d, exit 0 at 01:54:00Z, 4,118 s; PC 1's dock card alone, driver 617.14, app 0.3.20, mem 14,801 MHz throughout; every lock through the cleared helper sequence, every command answered first time, every fingerprint matched, clocks reset and read back): the knee as a reading: the rate holds within 0.3 percent of unlocked down to 1,000 MHz on both classes (v4 71.19 of 71.41 MH/s; v3 71.11 of 71.28) and falls 5.2 percent at 900 MHz on v4 (67.66), where the 75-minute budget ended the grid (v3's 900 and below not taken; the drift check skipped); so the 5080's knee sits between 1,000 and 900 MHz, a third of its 2,963 MHz boost, lower than the 5090's 1,300 (84 SMs at 2,960 MHz have more compute headroom per unit of its 960 GB/s than the 5090's 170 SMs per unit of 1,792 GB/s; the memory wait hides the shadow down to a lower clock). Best MH per watt within the 1 percent rate tolerance: v4 at 1,100 MHz, 71.20 MH/s at 146.6 W (0.486 MH/W; 106.5 W recovered for 0.29 percent of rate); v3 at 1,000 MHz, 71.11 at 103.7 W (0.686; 66.0 W for 0.25 percent). The v4 premium 83.4 W unlocked (253.1 against 169.7), 41 W at the best points (146.6 against 105.6 at 1,100). Per tier: a 5080 owner on class v4 locked near 1,100 MHz draws 147 W instead of 253 for 0.3 percent less rate (MH/W up 72 percent) and the shadow's residual cost is 41 W. Rows (lock: v4 MH/s / W / MH/W ; v3): unlocked 71.41/253.1/0.282 ; 71.28/169.7/0.420 (sm 2,963/2,977); 2850 71.41/229.5/0.311 ; 71.29/155.3/0.459; 2700 71.41/209.6/0.341 ; 71.29/149.2/0.478; 2550 71.41/193.0/0.370 ; 71.29/134.4/0.531; 2400 71.41/176.0/0.406 ; 71.29/128.7/0.554; 2250 71.41/165.6/0.431 ; 71.28/117.3/0.608; 2100 71.38/157.7/0.453 ; 71.28/112.3/0.635; 1950 71.37/154.0/0.463 ; 71.26/111.6/0.639; 1800 71.35/150.3/0.475 ; 71.24/113.4/0.628; 1650 71.33/151.4/0.471 ; 71.22/109.7/0.649; 1500 71.30/149.2/0.478 ; 71.19/110.6/0.644; 1400 71.27/149.6/0.476 ; 71.16/107.0/0.665; 1300 71.24/147.9/0.482 ; 71.14/107.7/0.661; 1200 71.20/149.4/0.477 ; 71.12/104.4/0.681; 1100 71.20/146.6/0.486 ; 71.11/105.6/0.673; 1000 71.19/149.0/0.478 ; 71.11/103.7/0.686; 900 67.66/137.8/0.491 ; not taken. Throttle reason 0x400 (the power governor) on every row, never the clock lock, so the draw floor of about 147 W (v4) and 104 W (v3) from 1,500 MHz down is the memory system plus idle, not the SMs: the clock lever is spent by 1,500 MHz on this card. The three power fields agree within 0.2 W on every row. The site audit lane has the knee and best points for row 17; the bench table's 5080 row takes "71.4 stock (71.2 tuned)", "146.6 tuned (253 stock)", class v4 cost "+83 W unlocked, +41 W at the best points", hive core 1100 (the mem clock unchanged) once the fleet's rented-5080 sampler question is closed. Next on the shipper's ack: the third 5090 pass, the SM-sparse rerun on the fixed exe, the microbench, the packs, the two tunes, the hot table. THE NIGHT'S MOVE OUTCOME (the shipper, 02:58 BST): main's word on (A), (A') or (B) did not come (asked 01:41, 01:50, 01:53, 01:56 by the shipper and 01:42, 01:52, 01:5x, 02:00 by the coordinator); the gate script not applied (the dry run's 33 of 35 the only read); the move file not placed (build-1's /fleet/move.json serves m2720-1, 2720d8d2, the 22:30 minute, by curl at 02:56); no move minute; the stand-down under the ceiling rule holds from 02:15 (the shipper's stand-down line at 02:15 was not sent, its miss, the state unchanged); the Mac entry standing, not published (staged on DMG 1aa301cc in both folders, the live manifest at 0.3.23). A FINDING: build-1's Devnet 3 seed (the process on 26631 with JSON RPC 27632, the node lane's DAA reader) is DOWN (no such process; node1-dn3 26671 and the observer 26651 run on 2720d8d2; the node lane's 0.3.24 reader on 28690 runs but answers no DAA by the envelope tried), so the node lane's DAA reads since 25,169 at 00:52:38 BST may have stopped with it; at 1.0 DAA/s the DAA passed 32,400 at about 02:53 BST, the 39,600 floor is lost, and the fourth re-cut is from a morning minute main names (before 12:50 BST, or the three heights move with the floor). Every Devnet 3 node is on the 0.3.23 pin 2720d8d2, digest ba75bf6f (the 22:30 move; dn3-j1 behind its proxy unverified since); nothing of 0.3.24 is on any box or in any manifest. The night's 0.3.24: every gate green on dfbd1e10, the kit on four platforms, the move unmade for want of one word and two dark lanes. THE ATTACK-PASS BOARD'S CLOSE (lane (d), 01:58Z on 8 October; record docs/analysis/attack-pass-2026-10.md on the mirror's attack-pass; box-hours approximate: build-2 about 7 h, build-1 about 9 h plus about 6 h of F6 batches and F2 solvers earlier in the day). F9 so far: 89,301 of 100,000 chain-shaped seeds, 0 exhausted, 0 panics, 0 past attempt 31, max 30 (the tail 20: 20, 21: 6, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1; r about 0.69), three chunks on their cores to about 02:20Z; F1 the 10^5 redundancy census at 3 h 22 min on 17 threads, healthy, no end marker, 0 failures on its live panic path. The board: F1 shadow redundancy PASS on sub-version 3 (max 5.078 percent at honest-compiler parity; AP-F1-1 on the v5 list at 3.0 percent), running on v5; F2 mixer round margin PASS effort-bounded (no trail under weight 20 to 24 at 2 applications, 29 to 35 at 3, 39 to 47 at 4), not re-run on v5 (the mixer unchanged); F3 chained cache j+1 PASS, not re-run; F4 weak-day census PASS on v4 on the DSP-bound metric with AP-F4-1 reconciled with adv-mixer-2 (median 226, 15 days a century, worst 2050-04-28 at 1.113x), on v5 PASS at 8ca66afa (0 of 2^24 days over 1.1x on both metrics, AP-F4-1 FIXED-AND-PASSED); F5 chip-model sweep FIXED-AND-PASSED (the F2 hour skipped by decision), not re-run; F6 verifier worst case PASS (worst of 10^5 at 8.708 ms half-core; O-1.14 closed, i7-9700K 6.334 ms), not re-run; F7 era draw PASS on all three (0 of 6 re-rolls), not re-run; F8 uniformity FIXED-AND-PASSED on sub-version 3 (60 of 64 under 1.2x; AP-F8-1, 2, 3 closed), PASS on v5 (61 of 64, worst 1.50x, the residue p4, p8, p10; p34 under); F9 edges, hot set, grinding PASS on sub-version 3 (34 of 105,064 edges bounded; grinding +0.004 percent), the exhaustion count running on v5; F10 ladder signal PASS, not re-run (node rule). Findings of the pass, all in-house: AP-F1-1, AP-F4-1, AP-F5-1 (the X9), AP-F8-1, AP-F8-2, AP-F8-3; two operating hazards fixed (AP-H1 the box clean, AP-H2 the shared binary path). The open tail (p4, p8, p10, and p34 on sub-version 3) is named in the public report; no outside party holds it (the attack-pass lane's close wrote "disclosed to the firms", stale wording from before the in-house ruling; its record file is to say "named in the public report"). THE SEED'S DEATH AND THE DAA NOW (the node lane, 03:0x BST): build-1's Devnet 3 seed log /home/build/dn3seed.log ends at 01:09:05Z at DAA 29,732 mid-stream with no stop, shutdown or panic line, so it was killed abruptly (it ran under nohup from a shell, not a unit; no journal names the killer; the OOM record needs sudo the lane lacks); its datadir /home/build/dn3seed/igneum-devnet-3/datadir is intact (13 GB) and it stays down until the shipper says; the lane's reads 25,169 at 23:52:38Z and 28,906 at 00:55:09Z came from it while it lived. The DAA now from node1-dn3 on 28670: 32,659 at 01:57:50Z (the observer 32,660), both on 2720d8d2; the chain passed 32,400 at about 01:53Z, 39,600 lost. The fourth cut in one line: the script on release-0.3.24-node reads the DAA from 28670, sets the floor to the morning minute's publish DAA plus 7,200 rounded up to the next 3,600, commits, pushes both mirrors and dispatches the gate set (about 20 minutes to the pin line, then the fast-time pair about 14); the latest minute before the three heights move with the floor is about 11:50Z (12:50 BST), where the floor reaches 79,200; nothing is cut until main names the minute. A morning item for the box owner: a process on build-1 was killed at 01:09:05Z without a log line while the box carried a load of 400 to 600; the killer (OOM or a sweep's cleanup) is to be read from the journal with sudo before anything long-lived runs there again under nohup. THE BENCH LOG ENTRY (the hash lane): docs/bench-log.md "7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080" (both cards' full tables, the knee per card, the best MH per watt points, the premiums at the lock, the lever's limits, the job ids and clocks, the rented-5080 watts note) on the mirror's master as merge 773b93a8 at 02:04:47Z (commit 11c698ad); the audit lane writes row 17's sentence from it. PC 1: the third 5090 pass run-ca3-pc1-v4-eff-5090-floor2-20261007 (1,100 MHz down to 300) since 01:57:03Z, about 28 minutes; then the SM-sparse rerun. ROW 17 AND THE 5080 BENCH ROW (the site audit lane, master 2c5c7f52 at 03:19 BST, gate GREEN on 6eb6fd9b, 71 checks): docs/evidence.md row 17 carries both cards' efficiency passes from the bench-log entry (the 5090's knee, best points and premium; the 5080's 71.41 MH/s at 253.1 W unlocked, 71.20 at 146.6 W at 1,100 MHz, v3 at 1,000 MHz 103.7 W, the premium 83.4 W to 41 W, the knee between 1,000 and 900 MHz, the per-tier reading, the Ember Tune lever), a what-moved table for 8 October, /evidence rebuilt (865a0a5e); site/miner-bench.json's RTX 5080 row states the team's pass as the card's figure ("71.4 stock (71.2 tuned)", "146.6 tuned (253 stock)", "+83 W unlocked, +41 W at the best points", hive core 1100 with the memory stock, driver 617.14, the bench-log entry as the source) and keeps the rented-fleet sampler reading with its 110 W gap as the open question; /miners rebuilt at 35 rows (6eb6fd9b); 0 identity hits; nothing deployed, the deploy the morning hand-off. The design pass on ca3-coord (015cc839) now sits behind this master and rebases onto it before its own landing on main's word. THE DESIGN PASS REBASED (the coordinator, 03:2x BST): ca3-coord rebased onto master 2c5c7f52 as the three site commits only (f5b7140c the design pass, 8cc4cbc6 the phone grid, 9ad3fdc9 the six-column row; the two commits already landed through the record branch skipped), site/miners.html rebuilt at each from the merged miner-bench.json so the page carries the 5080's new row ("71.4 stock (71.2 tuned)") under the design; the diff against master is build.mjs and miners.html only; pushed to the mirror (pre-push GREEN); it lands on main's word after the captures, one gate run. ADV-MIXER-3's LINE (read from its report at tip e02297ae, 03:18 BST): queue 17 finished on build-1 at 01:3x BST; Q2 single-bit avalanche at 2^27, k = 2 and 3 on day 20729: 0 holes, 0 cells beyond 6 sigma at band 0.00026, PASS (the k = 1 finding stands as the single-application diffusion); Q2b t-bit avalanche on day 20733 at 2^28: 0 cells beyond 6 sigma at band 0.00018, PASS (k = 2, 3, 4 on 20729 at 2^28 the same); Q3 at k = 8 NOT run (killed at 20:20 BST under the lease rule, not re-queued; k = 2 to 7 clean with 0 deterministic bits on both days), named partial; Q6 the day-20733 SAT ladder: k = 2 and 3 TIMEOUT at the one-hour cap, k = 4 on one build-2 core since 03:05 BST, its cap about 04:05; one pre-emption in its ledger (23:58 BST, 21 minutes of a 2^27 row lost, re-queued); box-hours about 3.0 wall-hours of sweep (build-1 1.9, build-2 1.1) plus about 4 single-core CaDiCaL hours, about 7 with the 20733 ladder. The pass's close with the per-lane table and totals at about 04:05 BST; section 13 on crypto-engage (docs only) merging the current master and going through the gate to the mirror's master so the record cites a master commit. Box 2 at 03:20: adv-accept 87 cores in four shards with three waiting, adv-mixer-3 one core; build-1 load 34, no adv lease. THE DESIGN PASS'S OVERLAP ON THE BOX (the CI steward, 03:33 BST): the 1440 and 390 dark captures of /miners from ca3-coord 9ad3fdc9 taken on build-2 under lease pool 4 (Playwright chromium 1194, the recorded feed; /srv/artefacts/captures/ca3-coord-9ad3fdc9/miners-1440-dark.png 1440 x 4280 and miners-390-dark.png 390 x 9779); the overlap sweep on the same checkout, 390 to 1600 px, light and dark: RED, 3 findings on the change itself: at 1280 px dark and 1600 px light and dark the date span in the lead cell's class v4 line is COVERED by the rate cell (4 of 5 sample points under td.big); 390 to 1024 pass. Cause: the branch's last gate ran on the Mac, which has no browser, so the sweep skipped and read GREEN; on the page the row rule's white-space:nowrap outranked the lead cell's normal by specificity, so the class v4 line ran under the rate cell from 1280 px up. FIXED at ca3-coord 2ca45001 (the lead cell's rule at the row rule's specificity, max-width 360 px, the class v4 line wrapping with overflow-wrap), rebuilt, pushed; the sweep and the captures re-run on the box before main's word. THE IN-HOUSE PASS'S PATH TO MASTER (the crypto lane, 03:2x BST): adv-accept's box-hours crossed 8 before 02:00 BST and sit near 10 (87 cores in four shards; it sweeps on under the mechanical yield, its reading unchanged); crypto-engage merged master 56eebc0d at 342b6730 (one conflict in funding.md, the pre-public scrub against the rewrite, resolved to the in-house pass with the scrub applied; the founder never named in in-house-pass.md or funding.md), the full gate running, merge-to-master on GREEN; section 13.3: master's igneum-pow moved after the freeze in four files (src/emit.rs and src/generator.rs, the derivation string and its recipe helpers, ids unchanged; tests/derivation.rs and tests/spec_readback.rs), none the hash, so the object the pass bounded is unchanged in every operation the hash performs. THE PASS IN ONE LINE (the crypto lane, 03:2x BST): eight of nine lanes closed, adv-mixer-3 on one SAT timeout (about 04:05 BST), adv-accept sweeping to its 16 box-hour line (9.2 now, the reading saturated at the 1.002x class), adv-cache-2 on one line shard; no break of class v4 sub-version 3; the acceptance's hot-set class closed by the class v5 floor (9 of 9) and its diffuse era-stride class routed to the next class; the weak-day FPGA tail reconciled and closed by a measured redraw rule; the attempts census complete; the spec text proven sufficient by two read-backs; one pod at USD 0.33 in the whole pass, none originated by the lane. THE THIRD 5090 PASS BELOW THE KNEE (run-ca3-pc1-v4-eff-5090-floor2-20261007, running at 02:34Z on its 500 MHz step; the steps lengthen as the rate falls since the batch count was sized from the unlocked rate, about 155 s at 500 against 60 at 1,100; the helper answering every command on the cleared sequence, every fingerprint matched, the 5090 alone). Rows (lock: v4 MH/s / W / MH/W ; v3): unlocked 137.09/456.7/0.300 ; 136.79/320.0/0.428 (sm 2,858/2,862); 1100 120.98/275.9/0.439 ; 117.32/198.6/0.591; 1000 110.03/254.9/0.432 ; 106.73/180.2/0.592; 900 97.43/232.7/0.419 ; 94.33/174.5/0.541; 800 86.00/216.3/0.398 ; 83.41/166.6/0.501; 700 75.98/202.7/0.375 ; 73.58/156.4/0.470; 600 65.30/178.2/0.366 ; 63.25/153.3/0.413; 500 53.03/166.5/0.319 ; v3 running. Reading: below the knee the rate falls about 10 percent per 100 MHz on both classes (compute-bound: the shadow and the base program no longer fit the memory wait) and MH per watt falls with it from 1,100 down, so the best point stays where the second pass put it (v4 at 1,200, v3 at 1,300); the driver took every lock down to 500 (the SM clock within 10 MHz), so the floor is below 500 MHz and is not where the optimum lives; the v4 premium below the knee 77 W at 1,100, 75 at 1,000, 58 at 900, 50 at 800, 46 at 700, 25 at 600 (the ALU work shrinking with the clock as the rate does). The exit line, the 400 and 300 rows, the drift check and the restore at its close; then the SM-sparse rerun on the fixed exe (each sparse row reading served= and sparse_blocks=, marked variant_row=FAILED if served as base). F9 AND F1 AT 02:34Z (class v5 at 1c420786, build-1): F9 98,945 of 100,000 seeds, 0 exhausted, 0 panics, 0 past attempt 31, max 30 (the tail 18: 39, 19: 19, 20: 24, 21: 8, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1); the last three chunks within minutes of their ends; F1 at 4 h 02 min under its lease, no end marker, 0 on its panic path. The pass record's wording fixed on the mirror's attack-pass at 9474cea8 ("named in the public report"; no "firm", "firms", "escrow", "prize", "paid review" or "Lot" line in the pass record or the ten row records; identity grep 0 hits); the section's merge to master after the two record lines, through the full gate in a detached worktree. THE SECOND SWEEP ON THE DESIGN PASS (the CI steward on 2ca45001, 03:38 BST): the desktop widths pass; RED at 390 px dark only, three findings on the lead cell (the card name and the class v4 line covered by the rate cell), the cause the new 360 px max-width on the phone grid; FIXED at ca3-coord 5158276c (the lead-cell width rule scoped to widths above 1,100 px, the phone grid's lead cell with no max-width), rebuilt, pushed; the sweep and captures re-run on it. F9 PASS ON CLASS V5 (the attack-pass lane, class v5 at 1c420786, pairing e5a4ac5978462156, build-1 under lease pool class release, the last chunk written 02:34:54Z): 100,000 of 100,000 seeds drawn through the chain path (era-composed class), 0 exhausted, 0 panics, 0 past attempt 31, max attempt 30; histogram 0: 31,454, 1: 21,460, 2: 14,660, 3: 10,263, 4: 7,047, 5: 4,701, 6: 3,297, 7: 2,256, 8: 1,532, 9: 1,027, 10: 702, 11: 509, 12: 365, 13: 216, 14: 153, 15: 103, 16: 80, 17: 56, 18: 39, 19: 20, 20: 24, 21: 9, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1 (first-draw acceptance 0.3145; the mean attempt index 2.185, so 3.185 draws per seed on average; 4,862 seeds, 4.86 percent, at index 8 or above and 255, 0.255 percent, at 16 or above; the 256-attempt cap and the deterministic last resort never reached; the lane's first line read 1.993, a slip it corrected); the exhaustion gate holds for the 0.3.24 move; record docs/analysis/attack-pass/f9-grind.md and the lane (d) section on the mirror's attack-pass. F1 still running (4 h 05 min, 16 cores, 0 on its panic path, no end marker). F9's record on the mirror's attack-pass at 2bcb7e08 (the lane (d) row and f9-grind.md section (d); feature gate GREEN); F1 the one open item before the lane (d) merge to master. THE DESIGN PASS GREEN ON THE BOX (the CI steward on ca3-coord 5158276c, 03:4x BST; build-2 under lease pool 4): the overlap sweep 390 to 1600 px, light and dark, GREEN, 0 findings (the known-failed fixture fired first); the 390 px capture byte-identical to 9ad3fdc9's (the phone shape that passed before), the desktop widths carrying the wrap at 4,640 px tall; the four dark whole-page captures on build-1 under /srv/artefacts/captures/ca3-coord-5158276c/: miners-390-dark.png (sha256 9eec8f27..., 509,158 bytes), miners-1280-dark.png (1b6e636d..., 438,541), miners-1440-dark.png (87387e14..., 445,402), miners-1600-dark.png (d53973cd..., 448,545); the run log /srv/builds/bs-ci-steward/cap-out/run-5158276c.log on build-2. The branch's gate record: a full gate on the Mac skips the sweep (no browser), so the box line is the sweep's verdict for 5158276c; the branch waits on main's word on the look and lands in one gate run. THE IN-HOUSE PASS'S RECORD ON MASTER (the crypto lane): crypto-engage dab0c89f (gate GREEN, 71 checks) landed through merge-to-master.sh --remote build at 03:50 BST as master 00b8cd1b: docs/plans/cryptanalysis/in-house-pass.md section 13 (the roll-up, every lane's reading, the frozen-object note) and funding.md's in-house row and brief, scrubbed under founder-strings-check.sh. AN EXCEPTION OWNED (03:39 to 03:50 BST): the lane's first merge call used the tool's default path, which reads CI on GitHub with gh run list; GitHub is suspended and the rule says never poll it; the tool polled 21 times (each 403, nothing pushed, nothing read); the run's process outlived the task stop and the lane ended it by its pid at 03:50 BST, then used --remote build; the breach is the tool's default against the rule and the lane's for not passing the switch; no state moved on GitHub's side. The coordinator's order on it: merge-to-master.sh's default remote must refuse GitHub while the suspension stands (the CI steward, a gate-side fix with a known-failed self-test), so the rule does not rest on every lane remembering the switch. THE THIRD 5090 PASS CLOSED BY ITS CAP (run-ca3-pc1-v4-eff-5090-floor2-20261007, ended by the 45-minute cap at 02:42:05Z during the 300 MHz step, exit -1, its own finally block never ran; every row taken matched its fingerprint, the 5090 alone): the 500 row's v3 side 51.37 MH/s at 136.4 W (0.377); 400: v4 42.62/152.5/0.280, v3 41.32/131.3/0.315 (sm 390); 300 not taken; no unlocked-end drift check; the driver took every lock down to 400 (the SM clock within 10 MHz), so the floor is at or below 400 MHz. The reading: below 1,300 the rate falls about 10 percent per 100 MHz on both classes and MH per watt falls from 1,100 down (v4 0.439 at 1,100 to 0.280 at 400; v3 0.592 at 1,000 to 0.315), so the optimum stays at the second pass's points (v4 1,200 MHz, v3 1,300) and nothing below 1,100 is worth the knob's time; the v4 premium below the knee shrinks with the clock (77 W at 1,100, 46 at 700, 21 at 400). AN EXCEPTION OWNED: the 5090 sat at the 400 lock (390 MHz, 127 W mining) for four minutes until run-ca3-pc1-clocks-restore-20261008 (02:45:20 to 02:46:30Z, exit 0) started the helper over an empty cmd.txt and sent rgc ("All done"), the card reading 2,880 MHz after; the cause the batch count per step sized from the unlocked rate, so the low steps ran 2.5x longer than planned; the fix in the scripts: the budget check ends the grid with the restore inside the cap, and a probe dev line answered in helper.log counts as the helper up when its heartbeat file stays stale (the restore answered at once with helper.alive stale past 60 s). THE SM-SPARSE RERUN: fetch-ca4-sparse3-exe-20261008 landed 02:49:57Z (sha256 0ba97edc...), run-ca4-pc1-ca4sparse-5090-20261008 published 02:51:15Z on the hash lane's own order (the shipper's acks were for the void host slot); each sparse row reads served= and sparse_blocks= and is marked variant_row=FAILED if served as base; the close about 03:15Z (04:15 BST). THE STEP-BUDGET FIX ON MASTER (the hash lane, merge 9fd8b1d8 at 03:02:03Z on 8 October, commit 0b00c42e, the full gate GREEN): the efficiency pass keeps four minutes of its cap for the restore (every step and lock guarded by the deadline minus four minutes) and sizes each step's batch count from the last rate read for the pack, so a 60 s step stays 60 s as the rate falls; a probe dev line answered in helper.log counts as the helper up when the heartbeat file stays stale (all four lock scripts); the gate check tools/ci/pc1-step-budget-check.sh with the known-failed case first (under the old rule a lengthening grid ends on the cap with no restore; under the new it ends with the restore at 1,500 s of 2,700), wired into pre-push.sh and checks.txt (74 checks). The 5080 Ember tune, the 9070 XT tune pass and the hot-table ldcs rows publish behind the SM-sparse rerun, the microbench and the packs. THE SM-SPARSE RERUN FAILS THE SAME WAY, NOW NAMED (run-ca4-pc1-ca4sparse-5090-20261008, the fixed exe ca4sparse3, started 02:52:48Z): every sparse row served=base sparse_blocks=0 variant_row=FAILED, the worker's own line "RESULT variant_not_installed requested=sp43-w32 served=base race=... variants 1 base only, no race (no other variant named)", no "compile:" text, so NVRTC never saw a rewritten kernel: the variant name is parsed into the request but never added to the race's variant table in this exe; the research lane's emulation test checked resolve and rewrite, not the race list the bench builds (a test of the wrong layer; the known-failed case must be the bench's own race line reading "variants 2"). The rows are base runs; no reading. The queue goes on: the microbench at the rerun's exit (about 03:15Z), the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows; the SM-sparse question's fourth row stays with the research lane, an exe whose card-free check shows "variants 2" in its race line getting the slot within the minute. CLASS-V5'S F9 ROW PUSHED (the v5 lane, class-v5 1d5e5d23 on both mirrors at 04:04 UK): the page's F9 row (100,000 seeds, 0 exhausted, max index 30, first-draw acceptance 0.3145, mean index 2.185, F9 PASS, the record file named), F1 stated as running with 0 failures (its own commit to follow), the Intel row not measured tonight; master merged twice (2c5c7f52 gated at 5f5e0a5c, full gate GREEN 71 checks at 03:45 UK; 9fd8b1d8 auto-merged and pushed on the hook's light gate, the full gate running on 1d5e5d23); the generated ledger files and the spec-constants check clean on the tree. THE THIRD --variant FIX (the research lane, 03:04Z on build-1 under lease, with the hash lane): the cause of the 02:52Z rows: the race's push looked the pinned name up in the empty order list through the variant lookup, whose on-demand sp path answers for any list, so the sparse variant was "found" and never pushed; the order is now a pure function with membership by name; --list-race prints, with no device, the race order the worker's own option handling builds and whether the rewrite applies: with the job's exact flags "variants=2 names=base,sp43-w32" and "sparse_blocks=43 block_warps=32 rewrite=applied bytes=22261 nonces_arg=1 unit_fn=1" (before the fix variants=1); exe igneum-worker-cuda-ca4sparse4.exe sha256 84846396559004a8df61881c15ecb42fa3fc1010ad99074e0c0b53e81bb1ca3b, the commit on the mirror after 7e9d52a6; the third rerun on the hash lane's queue at the next slot; the two failed runs stay the night's SM-sparse state, the op-mix re-weight held, the served 3.4x standing. THE GITHUB GUARD ON MASTER (the CI steward, tip 2f702735 at 04:05 UK; merges 53773860 and 2f702735, full gate GREEN 71 checks each): fa7e98fe adds the tracked marker tools/ci/github-suspended (suspended-since 2026-10-07T17:02:00Z, removed by main at the cut-over) and two refusals: merge-to-master.sh refuses a GitHub remote (origin by default, or any remote whose URL carries github.com) with one line naming the switch and exit 2 before any gh or git call; the pre-push hook refuses any push to a GitHub remote the same way (the hook reads the remote URL, so a bare git push origin is refused too); known-failed first in both self-tests; the live read on the Mac: merge-to-master.sh --remote origin exits 2, nothing contacted; two follow-ups (9484b988, a08423d4) fix the tool's own --self-test under the real marker. The rule no longer rests on any lane remembering the switch. F1 READ AT 03:05:58Z (the attack-pass lane; the census process itself, not the lease wrapper): state S with 17 threads, 15 cores busy over 45 s, 2 d 19 h of CPU banked over 4 h 30 min of wall, RSS 0.8 to 1.0 GB; computing, not hung. No rows can exist before the end: the harness collects every Report in memory under thread::scope and writes census.csv in one go at the end (no progress print), named as a harness gap in the record. Why fifteenfold against the v4 reference: under class v5 every candidate draw runs the (c''') distinct-index floor over 2^20 (about 1.8 core-s per candidate under the night's load, times 3.2 draws per program, about 5.8 core-s per program before the analysis), so 10^5 programs at 15 busy cores is about 10.7 h of wall, the end about 09:00Z (10:00 BST), nearer the early side as the load fell to 21. Ruling: not killed (a kill loses 4 h 30 min with nothing on disk); the lane (d) section merges to the mirror's master now with F9 and the F1 row reading "running, 03:06Z reading, projected end about 09:00Z", F1's record line in a second merge when it writes; the harness gains a progress line before its next 10^5 run. THE IN-HOUSE ADVERSARIAL PASS CLOSED (04:08 BST on 8 October; an internal adversarial pass, not an independent review; section 14 of in-house-pass.md at crypto-engage c099e818 landing on master through --remote build; every tip read from the mirror at 04:07 with igneum-pow identical to 017e7037 on all nine). Per lane (tip; box-hours; verdict; partial): adv-mixer d2ba3134, about 0.6 plus 1.8 single-core SAT hours, the algebraic structure BOUND, none; adv-mixer-2 2a632579, 0.31, BOUND for every chip, GPU and the verifier with the FPGA LUT-area FINDING (2^-10.8 of days, 15 a century, worst 2050-04-28 at 1.113x) closed by the measured redraw rule, none; adv-mixer-3 981bfff2, about 5.0 wall-hours plus 8 single-core SAT hours, Q1 BOUND (2^32 t uniform at k = 1 to 8, both days and 8 random days), Q2 and Q2b FINDING at k = 1 only and BOUND from 2 to 8 at 2^24 to 2^28, Q3 FINDING at k = 1 and BOUND 2 to 7, Q4 and Q5 BOUND from k = 1, Q6 SAT BOUND (k = 1 in 137 s, k = 2 to 4 timeout), the round margin 70 of 72 per item, partial Q3 at k = 8 not run, multi-bit masks and a MILP bound not attempted, GPU blocked; adv-cache 555c3e42, 0.55, the recompute shortcut BOUND on every row, none; adv-cache-2 91ca5ce1, about 2.25, the line census PASS at 2^35 + 3 x 2^33, the real programs PASS with the Devnet 3 site-0 FINDING, the diffuse era-stride class named (16 of 32 base programs biased under drawn eras against 2 of 32 under R = 29, 8 over 1.2x, worst 1.75x, under 0.1 percent of reads per site, 0 of 61 refused by the v5 floor, AP-F8-6), steering and the 16,384-day scan PASS, the window layer exact and the chip model's partial-store rows overstated up to 2.3x with the verdict unchanged, partial the line shard s2c waiting on build-1 since 23:09 BST; adv-cache-3 9452c0bf, 0.23, the chain-break or skip BOUND on every row with the pebbling optimum under the hold-every-k curve, none; adv-accept c8a98e46, about 9.2 at 03:25 BST running to its 16-hour line, the bypass FINDING confirmed and bounded (9 few-item hot sets in the tail of 408,067 accepted programs, 0 in 20 random, 1.002x at the largest; all 9 refused by the class v5 floor, 7 clean programs falsely refused among the 12 deepest, 3 mild residuals missed), the stand-in gap BOUND, distinguishers BOUND, the attempts census complete, partial the sweep at 408,067 of 10^6; adv-accept-2 92168536, about 9.0 core-hours and 0.3 pod-hours (the one pod), header grinding BOUND by card measurement (+0.09 percent on an A6000) and by tail (3e-7), one 0.1 percent repeat class for the rule's owners, none; adv-accept-3 7826d2b2, 3.3, exhaustion BOUND (P 1.0e-43), the last-resort path FINDING (correctness, unreachable; closed in class v5), steering BOUND (no property over 1.03x at 1 in 1e6 tries), the program id BOUND with the derivation-string FINDING (fixed on master and in the packs), determinism BOUND, the spec text proven sufficient by two read-backs, the era lever BOUND, partial the steering sweep at 975 of 10^5 full-rule seeds. Totals: about 30.4 box-hours of run across the nine lanes (lease waits excluded) plus about 9.8 single-core SAT hours; pod-hours 0.3 on one RunPod A6000, USD 0.33 in all, rented and destroyed by the fleet lane. The verdict: no lane broke the frozen object; the acceptance rule admits two residual classes of address concentration, both under 1.002x to a chip: the few-item hot sets, closed entire by the class v5 floor (9 of 9) at a 2.4 percent clean-rejection cost, and the diffuse era-stride excess the floor does not reach, routed to the next class with its lever; the weak-day FPGA tail reconciled and closed. Already changed by the pass: the derivation string in the shipped packs, spec 1.4.3 to 1.4.6 rewritten and proven text-sufficient, the chip model's partial-store and pebbling baselines corrected, the last-resort path flagged and closed in class v5. Still to come: adv-cache-2's s2c row and adv-accept's final count, appended when they land. CLASS-V5 GATED (the v5 lane): the full gate on 1d5e5d23 GREEN, 72 checks in 347 s (04:1x UK); class-v5 4a162aba on both mirrors at 04:12 UK with the page's F1 line stating the 04:06 reading (computing, not hung; census.csv only at its end; projected end about 10:00 UK); nothing of the lane's pending on a box or a watch. THE LANE (d) MERGE ON MASTER (the attack-pass lane, 399f8c4d at 03:16:35Z, 04:17 BST; attack-pass 4150f66d, full gate GREEN 45 checks on the branch): F9 PASS on 1c420786 (row and f9-grind.md section (d)), the F1 row as ruled (running, the 03:06Z reading, projected end about 09:00Z, 0 on its live panic path, the harness gap named), the in-house wording kept through a conflict with master's older copy, one founder-strings scrub the gate caught on the pass record (the attribution now "The founder's word"). The harness item: the progress line every 1,000 programs and the flushed partial census.csv (temp file and rename) committed on attack-v5-frozen at 18a9c04a, built on box 2, its known-failed test (a 4,000-program census killed by pid at the 2,000 line, 2,000 rows expected) running under lease pool class adv; the verdict and the push follow. THE SM-SPARSE QUESTION, THE THIRD RUN (run-ca4-pc1-ca4sparse-5090-20261008-b on ca4sparse4, 03:23:45 to 03:48:45Z, exit 0): the card-free check on the card's own exe listed the sparse variant (variants=2 names=base,sp43-w32, rewrite=applied), the race ran it, and NVRTC refused the rewritten kernel on every sparse row: "kernel_bound.cu(370): error: identifier "d" is undefined | igneum_hash_bound_unit(d, ou, baseNonc, mas, i, gid);" (the same for sp170, sp85, sp21, sp11), so the race installed base and every sparse row reads served=base variant_row=FAILED. The hash lane's reading to the research lane: the wrapper's call carries the kernel's parameter names cut by one character (d, ou, baseNonc, mas for ds, out, baseNonce, mask), which points at the rewrite's name capture against the PC's CRLF pack text (the Linux check reported a different byte count for the rewritten kernel): the first card test of the rewrite, the finding kept. The base rows a third repeat of the knee pass (v4 137.06 MH/s at 449.7 W unlocked, 134.23 at 301.4 W at 1,300; v3 136.79 at 329.8, 134.05 at 218.0), the card restored each time. The slot returns to the research lane on an exe whose card-free check compiles the rewritten text through nvrtc for sm_120 (on CRLF input). The queue: the microbench run-ca4-pc1-microbench-5090-20261007 since 03:52:14Z (20 probes of 60 s unlocked, then at the 1,300 lock; about 50 minutes), then the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows. THE CLOSE'S MASTER COMMIT (the crypto lane, sent 04:55 BST for a 04:14 landing, the forty-minute gap its own): crypto-engage c099e818 (full gate GREEN, 71 checks) landed as the mirror's master 2882352c at 04:14:50 BST; the record cites the roll-up and every lane's reading at 00b8cd1b and the close (section 14) at 2882352c; further landings only for adv-accept's final count and adv-cache-2's s2c row. THE FOURTH --variant FIX (the research lane, 03:55Z on build-1 under lease): the cause was not the line endings: the rewrite's parameter capture wrote the substring length as end minus start where the last index needs plus one, so every argument lost its last character on any input; CRLF would have missed the anchors entirely; the rewrite now strips \r first (the same rewritten bytes from LF and CRLF, 22,266 on both) and the capture is right; the card-free check through NVRTC on LF and a CRLF copy, identical lines: variants=2 names=base,sp43-w32; rewrite=applied; call="igneum_hash_bound_unit(ds, out, baseNonce, mask, iw, gid)" params=6 args=6 names_match=1; nvrtc=libnvrtc.so.12 arch=sm_120 compiled=1 image_bytes=36256; the failed case the 03:23Z card line. Exe igneum-worker-cuda-ca4sparse5.exe sha256 a4550202b301faf22f5329c2ab4fa1c0aa6695dbdaf31c974f316dca2524d7d6, with the hash lane; the commit on the mirror after 3ac5d20a; the slot after the microbench and the packs. The three failures gave three repeats of the knee pass (the v4 premium 133.9 to 145.3 W unlocked, 90.5 W at 1,300 MHz) in the file's 20.3a. ADV-ACCEPT OFF BUILD-1 (04:5x BST, the coordinator's placement rule): adv-accept runs on to its 16-hour line (about 10:15 BST, 10.6 box-hours at 04:54, the reading saturated) in box 2's gaps under the mechanical yield, its build-1 shard ended at the frontier and its waiter withdrawn, so F1's census keeps build-1 (its 10:00 BST projection assumed load 21) until census.csv writes; adv-cache-2's four-minute s2c shard the one exception. Confirmed by lease status at 04:57 BST: build-1 holds F1 (release, 16 cores) and adv-cache-2's s2c (32 cores, its last shard) and nothing of adv-accept's; adv-accept's four holders and waiters on box 2, where the attack-pass lane's flush test waits at 1 free behind them (the same class, no yield case); the coordinator's placement rule: one adv-accept holder ends at its frontier for the flush test (a 4,000-program census, minutes), since adv-accept's reading is saturated and the harness fix gates the morning's F1 rerun class. Done at 04:59 BST: adv-accept's sweep-s05b ended at its frontier at 04:58:50 (46,460 rows kept) and the flush known-failed test took the 16 cores at 04:58:55; the shard re-queued behind it. ADV-CACHE-2 CLOSED (05:0x BST): its last shard s2c ran 04:56 to 04:59 on build-1 (PASS at 2^33 reads, control-level), so the line census totals 2^36 reads over 464 chain days with every statistic at the control's values; final box-hours 2.35 of run (0.08 a duplicate windows run by its build-1 drain, recorded), pod-hours 0; tip bfc3746c on build/adv-cache-2, igneum-pow identical to 017e7037; the biased-site class (AP-F8-6) and the window-layer pricing stand; section 14's row updated on crypto-engage, landing with adv-accept's final count. Eight of nine lanes at their end; adv-accept alone runs to its 16-hour line about 10:15 BST. THE CENSUS HARNESS'S PROGRESS LINE (the attack-pass lane, attack-v5-frozen 18a9c04a on the mirror): the attack-f1 census prints a progress line every 1,000 programs (count, elapsed, running failure count) and flushes a partial census.csv at the same cadence through a temp file and rename; the known-failed test on box 2 under lease pool class adv (binary 14180ef4...): a 4,000-program census killed by pid at the 2,000 line at 04:08:27Z (05:08 BST), census.csv holding exactly 2,000 rows, no tmp file, lease exit 143; PASS (the old harness's known fail zero rows); record f1-shadow.md section 12 on the mirror's attack-pass at c99f147f (riding the F1 record merge); a side reading: 1,000 programs per 286 s on 16 cores, about 4.6 core-s per program, confirming F1's build-1 projection of about 09:00Z (10:00 BST); the running 10^5 census stays on the old binary, every census after it on the new. F1 PASS ON CLASS V5 (the attack-pass lane; class v5 at 1c420786, pairing e5a4ac5978462156, build-1 under lease pool class release, 16 cores; census.csv written 04:20Z, 05:20 BST, after 20,774 s of census, 5 h 46 min, earlier than the 09:00Z projection as build-1 emptied): 100,000 of 100,000 programs through the string-seed draw with the (c''') floor; instructions saved min 0.000 percent, mean 0.623, max 4.688 (the worst seed attack-f1/95060: 6,912 to 6,588); chip-view ops saved mean 0.520, max 4.783; programs over 5 percent 0, over 10 percent 0; soundness: differential mismatches 0 of 100,000 (8 random states each), verifier mismatches 0 of 100,000; 0 panics; the histogram of saved in 0.5 percent bins from 0: 55,241, 20,597, 11,762, 9,851, 1,484, 656, 259, 133, 13, 4, 0, 0. Against the v4 10^5 (max 5.078, the AP-F1-1 letter miss): the v5 tip's worst program sits 0.39 points under the 5 percent letter and the top two bins are empty. F1 PASS on 1c420786 by the letter and at honest-compiler parity; the redundancy gate holds for the 0.3.24 move; AP-F1-1's v5 half FIXED-AND-PASSED at this count; record f1-shadow.md section 13 and the lane (d) row, merged to master next. The attack board on class v5 is complete: F4 PASS (8ca66afa), F8 PASS, F9 PASS, F1 PASS; the rest not re-run by rule. CLASS-V5'S F1 ROW (the v5 lane, class-v5 1095eaa8 on both mirrors at 05:24 UK): the page's attack row reads F8 PASS with the known residue, F4 PASS, F9 PASS, F1 PASS on the full 10^5, the rest not re-run by rule; the full gate running on 1095eaa8; nothing else of the lane's open tonight. THE CA4 PACKS ON THE 5090 (run-ca4-pc1-packs-5090-20261008-b, exit 0 at 04:22:54Z, 579 s; the 5090 alone through the installed worker, the lock and reset through the helper, every self-test PASS at both states): the int8 mma tile prototypes' inline PTX compiles under NVRTC 12.8 on sm_120 and matches the CPU reference (mm128 270e4ae36b37e9a1, mm512 a1c1ff3148d775d1, mm1430 8e9b7066239d35d1), as do both per-load exports (404cad3b3399f9b3, ee5d7c71180e5ea7), sh256x27 (3d2e8245cc084d07) and the mx8-genesis control (7c28cfb06c5c65a9). Rows (MH/s / W / MH/W), unlocked then at the 1,300 lock: mx8-genesis 137.54/311.0/0.442 then 127.32/213.0/0.598; sh256x27 137.51/462.2/0.298 then 126.93/295.8/0.429; shl256x27 (unsound, an energy reading only) 158.62/472.8 then 145.65/299.4; shl256x27_v2 (unsound) 135.90/448.3 then 126.04/282.9; mm128 137.45/332.9/0.413 then 127.01/217.8/0.583; mm512 137.50/369.4/0.372 then 127.07/235.4/0.540; mm1430 137.45/457.7/0.300 then 126.87/284.5/0.446. Consequences: the rate is memory-bound on every sound pack at both states (within 0.5 percent of the control); the tile premium over mx8 is 21.9 / 58.4 / 146.7 W unlocked for 128 / 512 / 1,430 tiles (0.103 W per tile, linear) and 4.8 / 22.4 / 71.5 W at the lock (0.050 W per tile), so at 1,430 tiles the tile block costs what the ALU shadow costs (151.2 W unlocked, 82.8 at the lock) and the lock halves it the same way; the first per-load export's 15 percent higher rate is its duplicate reads landing in L2 (the unsound construction), the fixed one 1.2 percent under the control. The research lane has the rows for 20.3 and 20.4; the tile class's premium per tile is now a measured number on the 5090 and its Apple cost (35 to 78 percent of rate) the open side. The microbench -b since 04:23:23Z, then the SM-sparse rerun on ca4sparse5, the 5080 Ember tune, the 9070 XT tune pass, the hot table. THE CA4 PROTOTYPES' FIRST SENTENCE ON MEASURED ROWS (the research lane, counter-asic-4 on the mirror after 1428dd3c; sections 20.3 and 20.4): neither prototype beats class v4's premium; the tile block matches it at the same hash rate (mm1430, 11,440 int8 tiles per hash: 146.7 W over class v3 against the ALU shadow's 151.2 W unlocked, 71.5 against 82.8 W at the 1,300 lock, the rate memory-bound within 0.5 percent) and beats class v4's chip edge only at the pessimistic end (about 2.2x against 3.5x), not at k = 1 (2.2x either way), because the 5090's measured cost per int8 MAC (0.091 pJ unlocked, 0.048 at the lock) sits inside what a 5 nm MAC array costs anyone (a claimed test-chip figure), so a chip's k on tile work is at or above about 1 where on ALU work a fixed datapath reaches 0.3 to 0.5; the per-load placement dead as a construction (its energy rows 13 to 14 W under the whole block for the same instructions; the first export 15 percent faster from duplicate reads served by L2). Against the tile block as a class: the verifier (AVX2 0.047 us per tile per unit; mm1430 10.14 ms with the sibling loaded on the box's core, a 0.14 ms miss of the gate; scalar 13x worse; NEON unwritten), the Apple tier (35 percent of rate at 1,024 tiles, 78 at 4,096), the AMD layout unverified. No served number moves; the SM-sparse reading still owed (three failed runs, the fourth exe queued after the microbench); the op-mix re-weight held, the served 3.4x standing. The k column's basis (the research lane, counter-asic-4 after 781cb395): the 1,430-tile point is the one chip-model-v3 5.11's tensor-tile k column was priced at (15.2 set R about 1,430 from the 4090's 0.056 pJ per MAC to carry the ALU shadow's 0.654 microjoules; 11,440 tiles per hash), and the 5090 reads 0.091 pJ per MAC unlocked and 0.048 at the 1,300 lock there, so the column (2.1x at k = 1, 1.6x at k = 1.5) has its GPU-side cost measured at the premium it was priced for (1.067 microjoules unlocked, 0.564 at the lock, against the ALU shadow's 1.10 and 0.652); the Apple cost the open side; nothing served moves. F1'S RECORD ON MASTER (the attack-pass lane, merge 54b896f3 at 04:29:30Z, 05:30 BST; attack-pass 0610892b, full gate GREEN on the branch, pushed on try 2 after a ref race): the F1 row (PASS, AP-F1-1 FIXED-AND-PASSED on v5 at 10^5), f1-shadow.md sections 12 (the flush and its known-failed test) and 13 (the 10^5 record with the worst four programs at 4.688, the attempt histogram, the v4 comparison). Lane (d) complete: F4 PASS (8ca66afa), F8 PASS (61 of 64 at 1c420786), F9 PASS (10^5 seeds, 0 exhausted), F1 PASS (10^5 programs, 0 over the letter, 0 mismatches); both 0.3.24 gate lines PASS on the full 10^5. Box-hours for the lane (d) tail: build-1 F9 ten chunks of 4 cores at about 14,480 s each (about 161 core-hours), F1 16 cores for 20,907 s (93 core-hours), F4 12 cores for 379 s; box 2 F8 64 seeds (the earlier record) and the flush test 16 cores for 3,352 s (15 core-hours, most queued); nothing of the lane's on either box. THE V5 LANE'S NIGHT CLOSED (05:3x UK): the full gate on class-v5 1095eaa8 GREEN, 72 checks in 345 s; the freeze 1c420786 (0.3.24's pairing), the post-freeze line through 1095eaa8 (0.3.25's: AP-F4-1's agreed form, the verified last resort, the record), every proof green on the tip, the attack board on class v5 at F8 PASS with the known residue and F4, F9 and F1 PASS, the kit's fingerprint equal on CUDA, Metal, Apple OpenCL and the RX 9070 XT, the Intel row not measured; nothing of the lane's pending. THE SM-SPARSE READING EXISTS (run-ca4-pc1-ca4sparse-5090-20261008-c on the research lane's fifth exe, exit 0 at 05:12:48Z, 2,219 s; every variant served on the card, served=sp-w32 with sparse_blocks=N, the rewritten kernel compiled under NVRTC on sm_120 and bit-exact, every fingerprint equal to the Mac's; the 5090 alone, the lock and resets through the helper, the drift check equal to the start): a quarter of the SMs (sp43-w32, 43 of 170) holds 98.2 percent of the class v4 rate at the SAME draw (134.58 MH/s at 460.1 W against base 137.07 at 450.8) and 99.8 percent of the class v3 rate at 4 W less (136.55 at 309.8 against 136.77 at 313.9); the draw falls only when the rate falls (sp21-w32: v4 70.75 MH/s at 327.4 W, v3 132.82 at 303.4; sp11-w32: v4 37.34 at 250.9, v3 100.14 at 274.5), and watts minus idle per MH/s never drops below base (v4 2.75 W per MH/s base, 2.87 at sp43, 3.58 at sp21, 4.74 at sp11; v3 1.75, 1.73, 1.73, 2.00); the persistent shape on the full card (sp170-w32) within noise of base; at the 1,300 lock the sparse shapes collapse (v4 sp43 64.3 MH/s at 208 W, compute-bound). CONSEQUENCE: the class v4 premium is the shadow's ALU work itself, not SM-count overhead (150 W at sp43 against 137 W on the full card), so an SM-sparse miner kernel saves nothing and the candidate is dead by the research lane's own rule; the op-mix re-weight stays the open lever, and its served candidate ("2.9x with a core three times better") now has its SM-sparse read: the premium does not move with the SM count, so the re-weight's case rests on the op mix alone and goes to main with that reading. The microbench -c since 05:13:41Z with the pack argument; then the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows. RANK 2 CLOSED IN THE CA4 FILE (the research lane, 20.3b, counter-asic-4 on the mirror after 6b21e887): the SM-side power is the work's, not the SM count's (the shadow's ops cost the same on 43 SMs as on 170; idling SMs saves nothing); the number kept: the class v4 premium at sp43 unlocked 150.3 W over v3 at a held rate, equal to the full-card premium, so the premium is the ops' energy whatever carries them; the premium-free floor rests on the operating point alone; the op-mix re-weight's hold is main's to lift or keep, the SM-sparse reading saying nothing against it; the microbench rows still owed. THE OP-MIX RE-WEIGHT: HOLD (the research lane's case for main, 06:2x BST; the SM-sparse row at counter-asic-4 954c4053, section 20.3b): the served sentence stands ("At launch the strongest chip in our public model reaches 2.1x per joule against an RTX 5090 with a core as good as a GPU lane, 3.4x with one three times better, under class v4 from the first block"; the re-weight would move "3.4x" to about "2.9x", the shuffle-and-multiply-heavy shadow raising the chip's k floor from about 0.32 to 0.46). The basis: the re-weight touches only the pessimistic column, a model on both sides (the chip's k floor an estimate from wire and datapath figures, never measured; the GPU's energy per op by family unmeasured until the microbench rows land, the shfl, mul and arx probes being that measurement); the SM-sparse reading says nothing for or against it (the premium is the ops' energy, which both mixes pay); the night's measured finding on bounding k points to the int8 tile block (the same premium at the same rate with a k floor near 1 from the GPU's own tensor core, 0.048 to 0.091 pJ per MAC), of which an ALU re-weight is the weaker version at the same class-change cost (the 95 percent rule, the six gates, a new program stream, Apple paying shfl at 1.91x per op); a reader gains 0.5x on a modelled pessimistic bound and loses nothing measured from the hold; the 2.1x at k = 1 rests on four repeats of the knee pass (82.8 to 90.5 W at 1,300 MHz). The condition that re-opens it: the microbench reading the 5090's shfl and mul rows at or under the add's pJ per op together with a measured chip floor, and then it re-prices against the tile block, not the served line. Main's word lifts or keeps the hold; the coordinator's reading agrees with the hold. THE MICROBENCH ON THE 5090 (run-ca4-pc1-microbench-5090-20261008-c, exit 0 at 05:56:29Z, 2,484 s; the research lane's per-block micro-benchmark, 20 probes ran, 0 skipped or failed, at the unlocked clock and at the 1,300 lock, every probe's checksum equal at both states, the card back at the driver default). Picojoules per counted op as (watts minus the sleep row) over G ops per s, unlocked then at 1,300: the ARX integer path 11.3 then 6.2; int_mul 13.9 then 8.3; mulhi 39.6 then 21.0; prmt 22.3 then 11.5; lop3 24.1 then 13.0; shfl 55.8 then 29.4; fp32 fma 9.2 then 5.2; fp16x2 fma 5.1 then 2.6; int8 mma m8n8k16 4.1 then 2.2; int8 mma m16n8k32 1.36 then 0.83; fp16 mma 3.2 then 1.7; bf16 mma 2.9 then 1.5; fp8 e4m3 mma 1.5 then 0.8; the memory rows per read: L2 chase 2.4 nJ unlocked and 1.4 nJ locked, DRAM chase 10.9 nJ and 8.7 nJ, texture point 2.3 nJ, texture linear 0.19 nJ; the sleep floor 120 W unlocked against 75 W idle (the residency cost, flagged). CONSEQUENCES: (1) the op-mix re-weight's re-opening condition (the 5090's shfl and mul rows at or under the add's pJ per op) is NOT met and is now a measurement: shfl costs 4.9x the ARX op and mul 1.2x, mulhi 3.5x, so the GPU pays more for the heavier mix and the hold on the served 3.4x stands on measured rows, not a model; (2) the tensor-core int8 MAC costs eight times less per counted op than the ARX op the hash is built from (1.36 against 11.3 pJ), the direction a chip cannot beat by as much, which is the tile block's case restated in measured picojoules and the CA4 file's next row. The queue: run-ca3-pc1-ember-5080-20261007 (the installed app's Ember tune on the 5080, the app's own path, not elevated) since 05:57:18Z, about 30 minutes; then the 9070 XT tune pass and the hot-table ldcs rows. A CORRECTION FROM THE MICROBENCH'S TILE ROWS (the research lane, 07:0x BST; counter-asic-4 on the mirror after 954c4053: 15.1a, the corrected 20.3 and 20.4, the first sentence, the ranking): a mma.m8n8k16 tile is 1,024 multiply-adds per WARP, 32 per lane, so a hash does 32 MACs per tile, not 1,024; the lane's 15.2 and 20.3 and the 6 October 4090 figure chip-model-v3 5.11's tensor column was priced on were wrong by that factor. Corrected: the 5090's int8 MAC at the ALU shadow's premium costs 2.9 pJ unlocked and 1.5 pJ at the 1,300 lock (the packs job, 366,080 MACs per hash), the microbench's dependent u8 tile 4.1 and 2.2, the wide s8 m16n8k32 tile at 80 percent of peak 1.36 and 0.83; the 4090's "0.056 pJ per MAC" of new-pow 5.1 is 1.8 pJ. Against a 5 nm MAC array (0.04 to 0.4 pJ per INT8-class MAC, claimed) the chip's k on tile work is 0.03 to 0.3, BELOW the ALU shadow's 0.3 to 0.8: at the same premium the tile block leaves the chip 3.5x to 6.7x where the ALU shadow leaves it 2.1x to 3.5x. So the tensor shadow is the WORSE lever and rank 3 is dead; the 6 October verdict on scheme B stands for the right reason; the coordinator's 07:0x line to main calling the tensor side "the next class's one live direction" is withdrawn by this correction. Chip-model-v3 5.11's tensor column (its premise, a chip's MAC no cheaper than the GPU's, false by 4x to 30x on the public figures) and new-pow 5.1's per-MAC line are to be corrected (the coordinator's next commit); nothing served rests on either. The other rows, pJ per counted op unlocked then locked (the sleep floor 120 and 66 W subtracted; idle 75 and 60): int add-xor-rotate 11.3 / 6.2 (the shadow's 10.8 / 6.4 on the packs job: the two instruments agree); mul 13.9 / 8.3; mulhi 39.6 / 21; prmt 22.3 / 11.5; lop3 24.1 / 13.0; shuffle 55.8 / 29.4 (the card's dearest instruction, 5x the add: the re-weight's GPU side is against it, the hold measured); fp32 FMA 9.2 / 5.2; L2 hit 2.4 / 1.4 nJ per read against a chip's SRAM 0.2 to 0.5 (the hot-table lever dead on the GPU side; the ldcs rows kept as a record); the DRAM dependent read 10.9 / 8.7 nJ per read, the whole card's marginal against the chip memory's 2.0, section 2's floor seen per read. THE NIGHT'S CLOSING SENTENCE ON MEASURED ROWS: nothing on the 5090 reads k above 1; the ALU shadow at the operating point's knee is the floor, 2.1x at k = 1 for 82 to 90 W, measured four times; the two prototypes, the SM-sparse kernel, the hot table and the re-weight are all closed on measured rows. The CA4 file's commits (the research lane): 15.1a at 71fd465b (the microbench row, the residency cost 45 W at the stock clock before any instruction issues), 15.1b the commit after it (the re-weight's re-opening condition not met and measured; for 2.9x to be the honest pessimistic column a chip would have to pay 0.42 to 0.52 of the GPU's cost per shuffle, 22 to 28 pJ for a 32-lane crossbar move, above the wire figure and unmeasured; not a candidate on measured rows); the corrected 20.3, 20.4, the first sentence and the ranking at 71fd465b; the hot-table ldcs rows a record only. The lane closed for the night. THE TWO INTERNAL CORRECTIONS LANDED (the coordinator): chip-model-v3.md 5.11's k-column paragraph carries the dated correction (the tensor-tile column withdrawn; the shipped row unchanged) and docs/analysis/horizon/new-pow.md 5.1's per-MAC prose and the scheme B verdict carry the 32x correction with the reason (a tile is 1,024 multiply-adds per warp, 32 per lane), both citing counter-asic-4-research.md 15.1a at 71fd465b; new-pow's 5.1 table column and its 5.3 chip rows keep their original numbers under the note (the Horizon lane's file; a table rewrite is its own). THE 5080 EMBER TUNE (PC 1, app 0.3.20, 06:05Z, 07:05 UK; run-ca3-pc1-ember-5080-20261007): Tuned 60.3 MH/s at 123 W, 0.489 MH/W, clock_cap 2936, source=climb; read against the clock-lock grid, the app's power-limit climb lands at 0.489 MH/W where the 1,000 MHz lock gave 71.1 MH/s at 103.7 W (0.686), so the core-clock lock is worth +40 percent per watt on the 5080 over the stock climb (and 15 percent more rate): the case for the 0.3.24 core-clock knob shipping. The per-point curve rows were lost to a cast fault in the hash lane's curve line (job exit 1, 386 s; the app unaffected), fixed at 261d7c54. Live on PC 1: run-ca3-pc1-ember-9070-20261007 (the 9070 XT tune, 45-minute cap), then the hot-table ldcs rows. THE KNOB ON release-0.3.24 (the shipper, 07:1x BST): the core-clock knob 74585c91 cherry-picked onto release-0.3.24 at e181f497 with the efficient-point ceiling beside it (the plan-count test updated, b6e2845f; the app gate GREEN 294 + 35 + 8), the DMG re-cutting on it under the lock, the UI lane's drawing of the lock fields asked onto that tip, the measured Ember sentence in the 0.3.24 section with the job ids and the knee rule; the pin dfbd1e10 and the kit e6c088bb stand; the move on main's morning minute. THE 9070 XT EMBER TUNE (PC 1, app 0.3.20, 06:11Z, 07:11 UK): one row only, baseline 18.9 MH/s at 202 W, 0.093 MH/W, the chosen point "80%": the app has no knob on AMD in 0.3.20 (power_pct 0, clock_cap 0, limit 0.0 W), so the tune measures the stock point and stops; the 9070 XT cannot be made efficient by the app today, and at 0.093 MH/W it sits at a sixth of the 5090's locked 0.58 MH/W (the app's stored 5090 curve: 1,390 MHz, 118.6 MH/s at 204 W, 0.580) and a seventh of the 5080's locked 0.686; the AMD watts owed from the G1 ladder are on record from the app's reading, 202 W at 18.9 MH/s (the bench row's watts for the 9070 XT once the sampler question is closed). A morning item for the ledger and the app: an AMD core-clock knob (rocm-smi or ADL) is the only path to a 9070 XT efficiency figure. The job exited 1 on the hash lane's row count (fixed, 43f0918c); the app unaffected. The hot-table kit on PC 1 (fetch done 06:20Z); run-ca4-pc1-hot-ldcs-5090-20261008 publishing, the last PC 1 job on the list; rows when it closes. THE 9070 XT BENCH ROW ON MASTER (the site audit lane, ffb7d8ff at 07:35 BST, commit 47690be7, gate GREEN 72 checks): watts 202 ("202 stock"), mh_s 18.92 ("18.9 (18.8 to 19.2 on the G1 ladder)"), 0.093 MH/W, tuned "no lever: the app has no AMD knob today (an AMD core-clock knob through rocm-smi or ADL is the path, a morning item)", the class v4 cost unchanged (+2 percent of rate, 6 October), the note naming the app's own power reading at the stock point with the date and the status row, Hive values none; /miners rebuilt at 35 rows; no deploy; the audit lane closed for the night. The bench table's AMD watts are no longer owed. THE HOT-TABLE LDCS ROWS (the hash lane; the mirror's master at c09dfee4, 08:12 UK; bench-log entry "8 October 2026, the hot-table packs on the RTX 5090", 36 rows all PASS; run-ca4-pc1-hot-ldcs-5090-20261008b exit 0 in 1,372 s, clocks reset): ldcs equals base everywhere (a dead lever, no ldcs rows owed); the 1,300 MHz lock costs the hot packs 2 percent of rate against mx8's 7.5 while taking a third of the watts off every pack, so the hot family is latency-bound on the table; per watt at the lock hot64k8 reads 0.734 MH/W against the mx8 control's 0.602 (the control matches the v4 grid's 0.60, the two passes agreeing); the research lane has the rows with the resistance question (a cheaper GPU hash is a gain only if the saving sits in the memory path; the microbench's L2 row at 2.4 nJ against a chip's SRAM 0.2 to 0.5 answers it on the chip side). THE PC 1 LIST MAIN SET IS CLOSED: the 5080 full grid, the third 5090 pass, the SM-sparse reading, the two Ember tunes, the hot table, all on measured rows. Still open on the hash lane's side: PC 2's Arc B580 class v5 fingerprint on the shipper's clear (a Windows entry first), and the F8 tail p4/p8/p10/p34 as a Mac measurement under the lock script, held until main lifts the Mac rule for one job (a morning item). MAIN'S MORNING WORDS (09:3x BST on 8 October; the night's silence main's own, recorded as such): (1) the look: the design pass lands now through its gate (ca3-coord rebased onto master 715c79b2 as five site commits, tip 0d212a2a; the box sweep GREEN on the same content), the steward deploys master after it; (2) the floor sentence goes on evidence row 17 as well as /ledger in the exact wording (the audit lane's row); (3) CA4 parked with no live candidate, the record carrying the measured close; the only new work the AMD core-clock knob for the app, a 0.3.25 item on the update-return lane; (4) the F8 tail p4/p8/p10/p34 on the Mac: the Mac rule lifted for that one job, one at a time, a few minutes, the hash lane running it now; (5) the move: the shipper has route (A) with the minute 10:45 BST; the Arc B580 job has PC 2 clear and publishes now. THE BUILD-SERVER LANE'S HONEST STATE (09:31 BST): it ran nothing between 22:54 BST and 09:31 (its turn sat on a backgrounded gate chain; the overnight asks reached no tool call); the /miners captures it owed never ran (its export step failed at 22:52, "not a tar archive", a branch commit's git archive over ssh needing the ref fetched on the box side; the CI steward took the captures and the sweep instead); its last master-only deploy dde2dcd2 at 22:49 BST; it deploys master's tip on main's confirmed order after the design pass lands, and builds the 0.3.24 Windows pair and hive on the shipper's word. THE DEPLOY AND THE PAIRS (the build-server lane, 09:3x BST): a master-only deploy of 715c79b2 running from 09:32 with the checks after; master's tip deployed again when the design pass and the row-17 commit are on it, the served sha and minute to the record; the 0.3.24 seed, Windows and hive pairs built on the MORNING pin (the node lane's re-cut from the 10:45 minute) under lease class release, the hands pair the node lane's, the shipper keeping the move and the minute; the seed-class ship path proven on dfbd1e10 first so the morning pin's builds run clean. THE FOURTH CUT (the node lane, 08:33:18Z, both mirrors): 5b673577 on release-0.3.24-node = dfbd1e10 with program_class_v5_activation_daa 68,400 (epoch 19), nothing else, the three heights staying; the read from build-1's restarted seed on 27632 at DAA 56,329 at 08:33:18Z (1.0 DAA/s overnight); the publish DAA at 09:45Z about 60,630, plus 7,200 is 67,830, the next boundary 68,400, landing about 11:54:29Z (12:54 BST); the floor holds for a publish up to DAA 61,200 (about 09:54:29Z, 10:54 BST); the gate set running since 08:33:20Z (build and consensus at gate priority, the five suites, both canary sets, the fast-time pair about 14 minutes from the artefact), the pin line due about 08:52Z (09:52 BST); the crossing read from build-1's seed after the move (restarted on the pin in the shipper's move); the TESTNET_PARAMS v5-at-0 re-cut after a clean crossing. THE ARC B580 READ (the hash lane, PC 2, 08:35:59Z, 09:36 UK): no fingerprint, match False against 82b19cbde8557ea5; the kit worker fails its self-test on the Arc before any batch ("vector lanes 96 bad of 96 ... device 729ebd46376e2851 expected e552166a03298f7f" on the v5 pack) and 96 of 96 on the v4 control too (device 11bdacb6ee4108c2 expected dfbc8db1c06dacd8), every cache and dataset FNV matching; so the Arc's bound-kernel evaluation is wrong on Intel OpenCL, not class v5; the kit is good on five of six platforms; under main's rule the Intel kit holds out of 0.3.24 with the crossing time 09:36 UK for its page row. The open question, put to the shipper (PC 2 its now): whether the installed 0.3.21 worker's own self-test passes on the Arc with the devnet pack, which decides regression (the kit worker) against never-worked (every Arc rate row on record would then be a FAIL row and the bench table's Intel row a held row). The F8 tail job on the Mac started under the lock script, one seed at a time. THE DESIGN PASS ON MASTER (the coordinator, on main's word; merge 3a4ba893 at 09:39 BST): ca3-coord rebased onto 715c79b2 as five site commits (tip 0d212a2a: the design pass e2674675, the phone grid 592488a4, the six-column row 7c44354f, the lead cell's wrap c11baf30, the width rule scoped to desktop 0d212a2a), site/build.mjs and site/miners.html only, the page rebuilt at each commit so it carries the 5080 and 9070 XT rows under the design; the Mac's gate GREEN (the sweep skipped there), the box sweep GREEN on the same content at 5158276c with the four dark captures under /srv/artefacts/captures/ca3-coord-5158276c/; the build-server lane deploys master's tip after the audit lane's row 17 and Arc-note commit. THE MOVE'S READINGS (the shipper, 09:4x BST): the pin 5b673577's node-lane pair on build-1 (igneumd a3b1a2c9, igneum-miner cfa9f5ca, igneum-pow src 8 paths), its tarball served at fleet/5b673577-node-lane.tgz (c5b85b09, 27,495,480 B); the gate script carries cfa9f5ca and dry-ran at 32 of 35 reachable (dn3-pool-a destroyed by the fleet's waste pass, dn3-relay and p2-4090-1b behind dead proxies); the move file m5b67-1 written to take the pin line's digest and placed at at_epoch 0 the moment that line reads green (about 09:52 BST), the gate line applied in the same minute, the minute the last FETCHED plus ten (the founder's word: no waiting on the clock; 10:45 the ceiling, 10:54 the floor's); the Mac entry re-cut on the knob display (knob-24 2c4dc617 merged, app gate 294 + 35 + 8, UI 88) and published with the hive at the minute; the installed worker's self-test on the Arc with the Intel lane; the eight boxes on bc5945fe with miners off read by the fleet lane and taking the move with the rest. (The fleet lane is answering again this morning.) THE PIN LINE ON 5b673577 (the node lane; every gate green at 08:39:15Z, 09:39 BST): 5b673577 on release-0.3.24-node (both mirrors) = dfbd1e10 with program_class_v5_activation_daa 68,400 (epoch 19), nothing else; pairing igneum-pow 1c420786; build 08:34Z rc 0 at gate priority (igneumd a3b1a2c96a9767ee..., igneum-miner cfa9f5ca..., /srv/artefacts/0324-5b673577/node-lane); core 175, exec 47, miner 28, p2p-flows 38, pow 19, consensus 134 at gate priority; the Devnet 3 canary set (08:34:58Z to 08:36:38Z): digest cc9026909eddbadb46912513e9b748dffd8e5c3583cd976857a8afdab2d772f9 on igneum-devnet-3 from ba75bf6f, object version 6 stamped, the override file refused, shutdown 573 ms, two empty nodes handshaking on cc902690, the shared-devnet dialler rejected, a 2720d8d2 node refused both ways; the testnet canary b2e856ed unchanged. The floor from the seed's read: the publish DAA at 09:45Z about 60,630, the floor about 11:54:29Z (12:54 BST), holding for a publish up to DAA 61,200 (about 10:54 BST); the fast-time pair's SUMMARY due about 09:55 BST, inside 10:35; no slide to 72,000 needed. A correction: node1-dn3's 28670 no longer answers (its process gone), so the DAA reader is build-1's seed on 27632, restarted 02:00:09Z on the shipper's word and in step with the observer on 28650. dfbd1e10 void as a pin. THE F8 TAIL ON THE MAC, p4 (the hash lane, under the lock script, one seed at a time; the Mac rule lifted by main for the one job): p4 reads 1.2169x over the window model (the gate's 1.2167x reproduced), hot-set clear at every f, the attribution on one site: site 1 (instr 8, source r2, window 2^22 items, offset 1, the last base writer mad at instr 4) carries 1.448 percent of the hot reads against 0.107 flat, index entropy 13.74 of 14 bits, the largest 256-item bucket 4.5x its window expectation, every other site at its flat share; the hottest item 0x4000e7 at 355 reads with no predicted source (no saturation, no lossy writer), so the residue is a window-2 index with a quarter-bit short, not a lossy source; p8, p10 and p34 running (about 90 s each), the four rows and the record line (the bench log or AP-F8-1's tail paragraph) at the close. STANDING RULE FROM THE FOUNDER (09:5x BST on 8 October, after the night: "this cannot happen again"), three parts: (1) every ask any lane sends main carries a default action and a deadline; silence at the deadline means the default, never a stand-down; passed to every lane the coordinator runs; (2) the coordinator mirrors every deadline the shipper holds today (the pin, the apply, the move minute, the publish, the Windows chain, each floor ceiling): if the shipper has not acted within five minutes of its own clock the coordinator sends it the word and tells main; if it is silent for 25 minutes the coordinator takes its next action itself with the shipper's runbook and tells main; (3) a 20-minute heartbeat wakes main regardless of notifications. The night's cost the rule prices: three floors lost (28,800, 32,400, 39,600) and the Mac entry stood down for want of one word while every gate was green; two lanes dark for ten hours. THE MOVE FILE PLACED (the shipper, 09:42:14 BST): m5b67-1 (5b673577, digest cc9026909eddbadb, at_epoch 0, the node-lane tarball c5b85b09) placed and served, its signature verified against the fleet key; the gate line (cfa9f5ca into every reachable box's pack list) applying from 09:42; the minute the last FETCHED plus ten once the fast-time SUMMARY reads PASS (about 09:55); the Intel lane a0aa97b17380bd614 holds the Arc self-test question with the audit lane on its recipients. THE NODE LANE'S OPEN ITEMS UNDER THE RULE (09:4x BST): the crossing read at DAA 68,400 from build-1's seed by 13:10 BST (else the observer on 28650 or the reader on 28690); the TESTNET_PARAMS v5-at-0 re-cut lands through the full gate set at 13:30 BST unless main says otherwise by 13:15 (a red crossing read means no re-cut); any later floor losing its margin is cut from the next named minute by dn3-floor-cut.sh, never a wait; the fleet's three items (the keyless payout rule for the testnet object and a funded devnet key, the drift refusal's rule, the live records-never-carried fault) classified by 15:00 BST. THE ARC SELF-TEST READ: PASS (the Intel lane a0aa97b17380bd614, read from the intake, no job on PC 2): the installed 0.3.21 igneum-worker-opencl.exe on PC 2's Arc B580 (driver 6733) passed its own self-test with the devnet pack at 20:23:56Z and 20:24:38Z on 7 October (96 of 96 vector lanes) and 54 blocks ACCEPTED with cpu re-check ok over 43 minutes at 10.58 MH/s wall (accepted 54, rejected 0 at 21:06:33Z); the shipped 0.3.20 worker read 96 of 96 on every pack on both PCs earlier that day. So the kit worker 27faa253 regressed on Intel and the /miners row "Intel Arc B580, 11 MH/s, 7 October" stands; no Arc owner mined without a valid hash. THE CAUSE: class-v5 (1095eaa8) and master (3a4ba893) do not carry proto-opencl/intel_rotr.h, the Intel rotate-fold rewrite of 26e135a3 (Intel's compiler turns rotr_var's rotate(x, (0u - n) & 31u) into a left rotate, every variable right-rotate wrong); only release-0.3.23 (710e1fea) and release-0.3.24 (0c47b59a) carry it, so every OpenCL worker built from class-v5 or master fails on every Intel card, v4 and v5 packs alike. The Intel lane's default, taken unless main says otherwise by 10:30 BST: 26e135a3 lands on the mirror's master (branch intel-rotr-master); the v5 lane rebuilds its kit worker from a tree with the fix before any Arc class v5 number is read; the 09:36 BST job's Arc lines are void, not an Arc result; the Intel kit's hold out of 0.3.24 stands until the rebuilt kit's fingerprint reads on the Arc. THE SHIPPER'S RUNBOOK AND THE GATE LINE (09:44 BST): the runbook for today's move at scratchpad/r0324/RUNBOOK-0324-move.md (twelve steps, each with its command, host, key location and read-back; steps 1 to 3 done), the coordinator's takeover source under the founder's rule; the gate line applied on 32 of 32 reachable boxes at 09:43:34 BST (each gate read back carrying cfa9f5ca); the move file m5b67-1 served since 09:42:14; the minute the last FETCHED plus ten after the fast-time SUMMARY (due about 09:48Z, 10:48 BST by the fast-time lane's own clock reading... the SUMMARY due about 09:5x BST), inside 10:54. THE RULE PASSED TO EVERY LANE (09:4x BST): the shipper (its runbook written), the node lane (its three defaults armed: the crossing read by 13:10, the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15, any later floor cut from the next named minute), the fast-time lane, the build-server lane (the deploy at 10:00, the three pairs with their minutes), the hash lane, the audit lane, the v5 lane (the kit rebuilt on the Intel fix), the Intel lane (its default at 10:30), the update-return lane (the AMD knob's branch by 12:00), the fleet lane (the FETCHED count by 10:05), the crypto lane (adv-accept's count at 10:15, section 14's last landing by 10:45, both armed on hard clocks), the attack-pass lane (the F8 tail's attribution by 11:00), the research lane (parked, its file at fb61ed4b) and the CI steward (the cut-over ask with a default on the first unsuspended read). THE AMD KNOB OPENED (the update-return lane, 0.3.25; branch amd-clock-25 off release-0.3.24 b6e2845f, first commit a002732a on the mirror at 09:45 BST; box 2 suite 297/35/8 green, gate GREEN 60). Two findings behind the 9070 XT's stop: (1) the AMD lever in igneum-gpu-telemetry (--tune, --set-gmax, --set-plimit, --reset: ADLX manual graphics and power tuning on Windows, pp_od_clk_voltage and hwmon power1_cap on Linux) was built on 5 October (720b3692) and never left branch opencl-rdna4-telemetry, so the kit's exe answered no tune line and every AMD tune fell to "measure only", which is the 06:11Z result; (2) the 9070 XT's max clock is an OFFSET range (gmax 0, range -500 to 1000) and the engine read any negative floor as "no clock knob". The commit takes the tool whole into proto-opencl/gpu-telemetry.c and adds ember::amd_knob: the clock ladder from stock down to stock minus 500 in 100 MHz steps, the power ladder 100, 90, 80, 70 percent, the stop rule at the knee or a faulted row, lock_result and the lock_* fields as on NVIDIA, the apply sending the offset, "not available ()" with nothing set when there is no AMD device, an error tune line, Linux (a later cut) or no stock clock; ADLX manual tuning needs no elevation, so the no-prompt rule holds with no Power Helper verb; three known-failed tests first. The first measured grid needs the kit's igneum-gpu-telemetry.exe rebuilt from this source (MSVC, the ADLX SDK beside the tree) and a 0.3.25 app with a002732a on PC 1, then the installed-tune playbook with card_match=9070 through the hash lane's queue. The lane's default: if the shipper names no 0.3.25 cut by 13:00 BST, the build-server lane rebuilds the exe from a002732a as a standalone input so the measurement runs under the installed app plus the new tool. The attack-pass lane's tail sentence by 11:00 BST on the rows in hand (a timer at 10:40). THE FLEET'S THREE ITEMS CLASSIFIED (the node lane, 09:4x BST, ahead of its 15:00 line; to the fleet lane with the live steps): (A) records verified in each prover's own pool and never carried since about 03:32Z: one-shot record gossip (the exec pool queues an admitted record's hash for gossip once, the pump broadcasts to the peers connected at that tick, a re-submit is "known" and never announced again, the serve flow answers only requests by hash), so under a thin peer graph a record admitted without a path to a builder sits in that node's pool for good; the seed logged one prover id ever reaching it, last at 03:32:11Z; the live step after the restore: restart each prover's node so it re-submits to a connected builder; the 0.3.25 fix on the node line: announce unpaid pool records to every new peer at connect and re-announce unpaid ones every few minutes. (B) p1-5090's "refused on the drift flag (offset -5)": the fleet's own standing.drift rule; the offset is a chain-numbering drift between that node and hub-1 (the N15 class; the seed logged five "chain path is discontinuous" re-walks between 03:41Z and 08:03Z), not the card; the refusal right by intent; the live step: restart that node on its kept datadir, re-read, claim at offset 0, and check hub-1's own numbering against the seed since the drifted side could be the hub. (C) 0.3.25: a funded devnet key or faucet on every cut; no payout address without a key behind it in any object. THE F8 TAIL ATTRIBUTED (the hash lane on the Mac, 08:39:46Z to 08:46:24Z, 09:40 to 09:46 UK, one seed at a time under the measure lock by main's lift of the Mac rule; attack-f8 census at 2^24 nonces, the window-model control, by-site attribution; tree b38b4af6 with igneum-pow frozen at 017e7037): the gate ratios reproduce to four places (p4 1.2169x, p8 1.3774x, p10 1.5036x, p34 1.2501x; the hot-set verdict clear on the windowed control for all four). Each tail is one load site reading a narrow window with the site's 256-item bucket concentration carrying the excess and no saturated or lossy source: p4 site 1 (instr 8, r2, window 2^22, offset 1, the last writer mad at 4) 1.448 percent of its reads into the top 0.1 percent against 0.107 flat, index entropy 13.74 of 14 bits, the largest bucket 4.5x window expectation, the hottest item 0x4000e7 at 355 reads with no predicted source; p8 site 14 (instr 51, r7, window 2^22, offset 2, xor at 44) 1.423 percent, entropy 13.72 of 14, bucket 3.1x, plus site 6 (instr 33, r3, window 2^23, mad at 30) 0.834 percent, bucket 3.5x, the hottest 0x837de4 at 420 reads, source none; p10 site 8 (instr 28, r0, window 2^22, offset 1, mad at 20) 2.040 percent, entropy 13.71 of 14, bucket 5.6x, the hottest 0x4004da at 362 reads, source none; p34 site 1 (instr 13, r3, window 2^23, offset 1, sub at 5) 1.352 percent, entropy 14.96 of 15, bucket 3.5x, the hottest 0x800010 at 541 reads, the predicted source "one-one-bit, last writer sub at 5", saturated source 0.0001 percent; every other site in all four at its flat share. THE MECHANISM: a per-site bucket concentration of about a quarter bit (0.26 to 0.29 bits short on a 2^22 window; p34 0.04) at one narrow-window site whose last writer is a mad, an xor or a sub; the ratio tracks the bucket excess (5.6x gives 1.50x, 3.1x to 4.5x give 1.22x to 1.38x); sub-version 3's (c'') distinct-index ratio passes these at 0.9927 to 0.9963 because distinctness does not see a bucket. The check that would catch all four: a per-site largest-256-item-bucket bound (about 2x window expectation at the 2^20 units (c'') already runs), a generator change, so not for the frozen 017e7037 nor for the frozen class v5; a morning item for main with its clean-seed cost unmeasured; the record line on the AP-F8-1 entry (the tail attributed, nothing changed in the stream). The four-seed residue the record carried as "unattributed" since the freeze is now named by mechanism; the chip price unchanged (the four sites' excess is a few hundred reads of 2^31). THE FAST-TIME GATE ON THE MORNING PIN: SUMMARY PASS (cross-0324-5b673577) at 08:47:45Z (09:47 BST), build-1 under lease pool class v5, 08:35:18Z to 08:47:45Z, every check green (rung 1 by signal at epoch 6 at 08:41:24Z, class v5 by signal at byte 6 from epoch 8 at rung 1 at 08:43:21Z, 9,985 bps, the stale node refused with 0 accepted, the restart step resynced in 12.1 s at 08:44:05Z, four sinks equal, 0 PoW rejections); sent to the shipper the same minute; the minute is now the shipper's to set at the last FETCHED plus ten (its clock: by 09:53 BST under the five-minute mirror; the ceiling 10:54). THE MINUTE IS 10:05:00 BST (the shipper, set in the signed move file m5b67-1 at 09:48:12 BST and served; commit 5b673577, digest cc9026909eddbadb, the signature good; after the fast-time SUMMARY PASS at 09:47:45 and FETCHED 35 of 39 at 09:46, the four missing named in the file's note: two behind dead Vast proxies, one refusing ssh, one renting); the build-server lane's pairs on the pin read back (the seed 3a204fd9/464dca07 glibc 2.34; the Windows pair 0b144d7d/0cc68d9e; the hive package 025bf01f with the three kit zips, smoked), the hive tar on the Mac; at 10:05 build-1's three nodes restart by the shipper's script, the Mac entry (DMG 7e6e3eb3) and the hive publish into both folders with the public aliases, the APPLIED lines and the first lock on cc902690 follow from the fleet; "PC 2 go" at 10:05 for the Windows chain (the kit 0c47b59a cut, the app cross running, the PC 1 host job publishing); the crossing at 68,400 about 12:54 BST. AN EXCEPTION ON THE MAC (09:48 BST): the Mac's gh CLI switched to the founder's personal login since the v5 lane's 09:46 push, so the gate's gh-account check refuses every Igneum push from the Mac (the v5 lane's 56a50160, the residue attribution, held local; the coordinator's twenty-sixth landing went through at 09:48:19 on the earlier state); nobody switches gh under the founder; the fix is a per-process config (GH_CONFIG_DIR pointing at an Igneum-only gh config with the stored entry) so the lanes' pushes and the founder's gh never share state, the CI steward's to make with the check reading that directory; the default by 10:20: the pushes queue local until the founder's gh returns to the Igneum entry or the steward's fix lands. ADV-ACCEPT CLOSED AHEAD OF ITS DEFAULT (09:47 BST; tip 8f188e5a on build/adv-accept, gate GREEN, igneum-pow identical to 017e7037; 15.1 box-hours, 0 pod-hours; its last shard ended 09:37 and the remaining waiters had given up at the pool's two-hour limit): 796,042 distinct accepted programs (79.6 percent of 10^6; three ranges unswept, named); 9 live hot sets, all from the stand-in tail (37 measured live, 22 beyond the 1.2x gate), 0 of 20 random, at most 1.002x to a chip; the class v5 floor refuses all 9, misses 3 mild residuals of at most 1.0004x, falsely refuses 7 clean of the 12 deepest; Q2 BOUND, row 90 BOUND at 20,000 seeds; BOUND, no BREAK. Section 14 updated (adv-accept's row and partial, adv-cache-2's close, the totals: about 36.4 box-hours of run across the nine lanes plus 9.8 single-core SAT hours, 0.3 pod-hours at USD 0.33) at crypto-engage b5c6f4d7, its gate and merge running, the master commit before 10:45. All nine lanes at their end. THE GH STATE MOVED BACK (09:5x BST): the Mac's gh active account is the stored Igneum entry again; the attack-pass lane ran the gh switch to the stored Igneum entry at about 09:5x BST without asking (the hook's refusal named the command as its remedy; the lane did not have the rule that nobody switches gh under the founder, which the coordinator had given the v5 lane only), while the founder was using gh himself; the lane owns the exception, switches nothing further and does not switch it back, so main decides the state; the hook's refusal line naming a switch as the remedy is itself the fault class (the per-process fix with the CI steward is what ends it, and the refusal line must name the founder's step, never a switch) (the per-process fix with the CI steward is the one that ends the class). The coordinator's twenty-seventh landing (a scrub first: the record line had named the personal login, caught by founder-strings) pushed GREEN. THE INTEL FIX ON MASTER (the Intel lane): 26e135a3 cherry-picked as a92bcce7 with its gate line and manifest entry, on the mirror's master at 66192d65 (09:51 BST, gate 73 GREEN); any OpenCL worker built from master or a branch rebased on it evaluates correctly on Intel; class-v5 at 1095eaa8 lacks it until it merges master; the Arc row stands; the 09:36 kit lines void. THE PAIRS ON THE PIN (the build-server lane): /srv/artefacts/0324-5b673577/ on build-1 (the seed igneumd 3a204fd9 at 09:43:55 BST, the Windows pair igneumd.exe 0b144d7d and igneum-miner.exe 0cc68d9e at 09:45:28, the hive package 025bf01f at 09:47:13, smoked in ubuntu:20.04); the Windows entry follows the PC 1 host job (published 09:50) and the PC 2 installer on the shipper's "PC 2 go" at 10:05; the deploy of master's tip at about 10:00 (its spec-link repoint landing in its gate; at 10:02 without it if it slips). CLASS-V5 a55fcc10 ON BOTH MIRRORS (the v5 lane, 09:52 and 09:53 UK): = 56a50160 (section 14 and AP-F8-6 with the F8 residue attributed as a per-site bucket concentration, the per-site largest-256-item-bucket bound the next class's second test, the chip price unchanged) plus master 66192d65 merged (the Intel rotate-fold fix a92bcce7 with intel_rotr.h and host.c's igneum_intel_rotr_patch; host.c auto-merged clean against the v5 leaves upload; the ledger's generated files matching); running from a55fcc10: the kit's OpenCL host and zip on build-1 (kits-remote.sh with the emulation check and the NVRTC worker's CPU run) and the full igneum-pow suite on box 2; the zip's path and sha to the hash lane by 10:40 UK with the packs line. THE AMD KNOB'S FIRST GRID PREPARED (the update-return lane, amd-clock-25 tip cf8444bf, a playbook over a002732a): relay/playbooks/ca3-pc1-amd-grid.ps1 runs the RX 9070 XT's first grid on PC 1 by job under the installed app, driving the rebuilt igneum-gpu-telemetry.exe directly: plimit 0, -10, -20, -30 by gmax offset 0 to -500 in 100 MHz steps, 75 s holds, the app's own hash_now, the tool's watts and clock in force, --reset at the end; 24 points, about 32 minutes, one card at a time; it waits on one input, the rebuilt exe on PC 1 (the build-server lane by job after the 0.3.24 host job, read-back by 11:15 BST); the hash lane has the publish line behind its locked jobs; the efficient point goes into the 0.3.25 tuner's ceiling table. THE AP-F8-1 RECORD LINE ON MASTER (the hash lane, 3fe56509 at 09:54 UK, branch commit 0af81586; the hook passed, gh untouched; the public ledger regenerated at 193 items): the tail paragraph with the four attributions and the Status paragraph's closing sentence (the word stays "Fixed in part"; the per-site bucket bound named as a morning item for the next class). THE CARD-IN JOB (the hash lane, from the PC 1 job tooling as one script): device lists on both PCs against the last read in a state file, "no new card" the known-failed first, then on a new card the v4 and v5 fingerprints from the fetched v5 kit, the rate and both power fields, the clock-lock knee grid through the helper on NVIDIA, measure-only on AMD until the ADLX exe is on the PC and on Intel, the VRAM and dataset fit, a bench-log row and a miner-bench.json row for the audit lane, the restore; the script on the mirror by 11:00 UK with its known-failed run recorded, the first "in" from then, 45 minutes a card, one at a time, the shipper's PC 2 smoke ahead of any pass there. Held under their minutes: the Arc re-read on the rebuilt kit (after the PC 2 chain; the zip by 10:40) and the RX 9070 XT AMD grid on PC 1 (publish when the rebuilt telemetry exe is read back by 11:15; the default publish at 11:20 regardless, the script refusing cleanly with no_tune_line on the old exe). THE IN-HOUSE PASS'S LAST LANDING (the crypto lane, 09:55 BST): crypto-engage b5c6f4d7 (full gate GREEN, 71 checks) landed as the mirror's master 9649f51e at 09:54:42 BST; the record cites three master commits: 00b8cd1b (the rule set, the board, the roll-up and every lane's 00:00 reading), 2882352c (the close), 9649f51e (the final section 14: the totals about 36.4 box-hours of run across the nine lanes plus 9.8 single-core SAT hours, 0.3 pod-hours at USD 0.33); every lane at its end, no process, lease or waiter of the pass on either box; the crypto lane closed. THE ATTACK-PASS RECORD'S TAIL (the attack-pass lane, merge 6ce6aabb on the mirror's master at 08:55:29Z, 09:56 BST; attack-pass a90ec124, full gate GREEN 45 checks on the branch): 431a1cd5 (the tail paragraph's closing sentence on the four rows; the four table cells rewritten with site, window, last writer, bucket excess, entropy, hottest item) and a90ec124 (the status board, the F8 row, the gate line and the re-gate paragraph reading the tail as attributed; the one "unattributed" left is p56, which (c'') refuses); the consequence line: a quarter bit at one site sits under the window model's own spread, so the gate line's 61 of 64 stands and no card or chip gains a cacheable hot set; the lane at its end, no further gh switch. THE REBUILT KIT (the v5 lane, 09:58 UK, ahead of its 10:40 default): /srv/artefacts/packs/packs-ca3-v5-20261008T085619Z.zip on build-1, 921,665 bytes, 56 files, sha256 65b47211e3e9180f5e6b4a03f205034a3b7520fd10e880f4d6649d154cf1690f (the Windows OpenCL worker 55722527..., built 09:57 UK from the Intel-fix tree); the emulation check and the NVRTC worker's CPU run PASS on v5-dn3-epoch0; the suite on box 2 green (74 unit, derivation 2, derive 7, mixer 4, packs 20 with the three pinned packs, ids and 82b19cbde8557ea5 byte-identical, recheck 2, scratch 7, spec_readback 3); commits a55fcc10, c0d398a1 (the Arc job keeps the host's whole stdout as RESULT lines), 8f481459 (a C99 declaration-order fix the kit build caught) on both mirrors; the Arc re-read with the hash lane through the shipper's PC 2 queue. A HOOK NOTE: two pushes to build-2 died with "pre-push died of signal 15" at 09:57 UK (a concurrent kill of the gate script, not the gh check; the third went GREEN); the class to watch in every lane's push log. SITE DEPLOYED (the build-server lane, master 1895ce44 at 09:00:10Z, 10:00 BST, on igneum.network and igneum.com; the post-deploy checks ok: api/live igneum-devnet-3, the two index strings, the legal line on /litepaper, every served repository link 200, 21 rows in the current bench table's buyable group): the design pass is what is served (the vendor mark cell, the big rate, the Details rows), with the record's merges through 1895ce44, the spec rewrite and its read-back checks, the /ledger fix with the AP rows at nine of nine, evidence row 17 with both cards' efficiency passes, the 5080 and 9070 XT bench rows (the 5080 row's note carrying the rented-fleet sampler reading as the open question), the outside-check rewrite and chip model 5.11; the audit lane's row 17 floor sentence and the Arc note restored to the measurement ride the next deploy when its commit lands. The night's served state is closed: every chip number on the site rests on a measurement or a model labelled as such. ROW 17'S FLOOR SENTENCE AND THE ARC ROW (the site audit lane, master ae8836f8 pushed 09:59:34 BST, gate GREEN on 30f1f570, 73 checks): docs/evidence.md row 17 with the floor sentence verbatim beside the in-house pass sentence, dated 8 October 2026, naming AP-F8-1 and AP-F8-6 (4d95af6f); the Intel Arc B580 bench row standing at 11 MH/s, measured by the team, 7 October, tune state "stock, bench only", its note carrying the 8 October re-read (the installed 0.3.21 worker's self-test 96 of 96, 54 re-checked blocks at 10.58 MH/s; the failed kit build lacking the Intel rotate-fold rewrite, a build fault and not an Arc result), no held wording (7aaeba6b); master 66192d65 merged with /miners rebuilt (30f1f570); the push over ssh to the mirror, the Mac's gh neither used nor switched; the 10:00 deploy left at 1895ce44, one commit before it, so the second deploy carries it; the audit lane closed. THE 0.3.25 NODE BUILD'S SHAPE (the node lane, 10:0x BST; release-0.3.25-node opened from the pin 5b673577 in a second worktree, release-0.3.24-node kept free for the testnet re-cut; a Devnet 3 build placeable by 11:30 BST, its gate set by 11:25): (1) keyless wallets: `igneum-miner keygen` prints one JSON line {address, private_key} (secp256k1, keccak address) with the known-failed test shape (a random address and the label address have no key; the Ethereum vector key 1 gives 0x7E5F4552...; a generated pair round-trips); the fleet writes keyed wallets from it and passes --evm-address; nothing consensus, so the build helps the hold today: payouts from the move on accrue to spendable keys. (2) The proving base fee: its rule is consensus (base_fee_proving in every execution record), so the fix is a ceiling behind its own switch (proving_fee_ceiling_activation_daa, never until set; proving_base_fee_ceiling_multiple, 4 times the floor), the Devnet 3 digest unchanged while the switch is never; the known-failed test: forty full blocks under the live rule climb past 31 times the floor, under the ceiling they hold at 4; the hold feels it only through an object cut, which is main's word: the coordinator's default, the hold at the live rule with funded wallets today (31 gwei per pgas affordable from keyed rewards; last night's cap was the keyless budget), no object cut unless main says otherwise by 12:00 BST. (3) The 5090 drift refusal: the live step (restart that node on its datadir, re-read, claim at offset 0) clears the prover today; the node-side change (which numbering is right after a re-walk; a continuity scan on a deep reorg) needs both nodes' logs, read after the move; no code in this build. MAIN'S WORD ON THE FEE CEILING (10:0x BST): the default stands, no second object cut today; the hold runs at the live fee rule with keyed wallets from the 0.3.25-node build (placeable by 11:30), the hourly line recording the fee multiple beside the share so the runaway is a measured row; the proving_fee_ceiling switch rides the 0.3.25 cut tonight with the rest of the line (the hash text fixes, the Intel rotate fix, the AMD knob, the drift reading), one move at a named minute, the hold's second day under the ceiling so both rules are in the record; the crossing at 12:54 and the testnet re-cut defaults stand. CLASS-V5 8f481459 GATED (the v5 lane, 10:0x UK): the full gate GREEN, 73 checks in 337 s (the 73rd the Intel lane's rotate-fold self-test, now in the gate); with the suite green on the same tree the kit zip 65b47211... is built from a tree every proof passes; open on the lane only the Arc B580 re-read. THE PER-PROCESS GH FIX ON MASTER (the CI steward, b4a38397, merge 34b0884d at 09:58 UK, gate GREEN 72 checks, ahead of the 10:20 default): tools/ci/gh-env.sh sets GH_CONFIG_DIR=~/.config/gh-igneum for the gate, the hook, merge-to-master.sh and ci-state.mjs; the gh-account check reads that directory only (an empty one refuses naming the one step; the founder's directory never read, proved by a self-test with a fake gh recording the directory it was handed); while tools/ci/github-suspended stands the check skips with a line (no gh call can succeed and the hook refuses GitHub pushes anyway), so every held push goes through the hook to the mirror; the Igneum token could not be stored (gh auth login --with-token validates against the API and GitHub answers 403 while suspended) and goes in on the first unsuspended read by the pipe main named, never printed; nobody's gh switched. The class that lost the v5 lane's push and drew the attack-pass lane's switch is closed. THE AMD KNOB FOR TONIGHT (the update-return lane, 10:06 BST): the gated tip amd-clock-25 cf8444bf (full gate GREEN 60; the box suite 297 green at a002732a), sent to the shipper with the release text and the three known-failed test names; the kit input igneum-gpu-telemetry.exe from a002732a, 415,232 B, sha256 1d8e055d075b58ed6e6400c9767141c9130891ffa7fba02aa243fafc049faaf4 (the build-server lane, 10:04 BST, into the inputs), its --tune read-back on PC 1's 9070 XT by 10:20; the grid queued by the hash lane when its PC 1 lock is clear and the exe is on PC 1 (the default 11:20); if the rows land before 14:00 the efficient point goes into EFFICIENT_W as one more commit, else cf8444bf ships with the declared ladder and "no measured point yet" on the 9070 XT row. THE 0.3.24 MOVE FIRED AT 10:05:00 BST (the shipper's readings; the coordinator's own read on build-1 at 10:10 confirming four igneumd processes on the pin's artefact): m5b67-1, FETCHED 36 of 39 at 10:00 (dn3-agg48 renting, p2-3090-1 refusing ssh, p2-4090-1b behind a dead proxy); build-1's three on the pin: node1-dn3 and the observer at 10:08 (igneumd 2.1.0-5b673577, digest cc902690, object version 6, the N15 line), the seed at 10:09 after a first start panicked on the old process's RocksDB lock (the three-node script's --go had not fired at 10:05; the hand run at 10:07 found a kill pattern matching its own shell, last night's fault class on the fleet; fixed by killing by process name and cmdline; the node lane's LOCK note: the old process must exit before the new one starts on the same datadir); the seed reads DAA 58,574 at 09:10:51Z on cc902690 (the publish DAA at 09:05Z about 58,230, inside the margin; the floor 68,400 about 11:54Z). The 0.3.24 Mac entry LIVE at 10:08:35 BST in both token folders (DMG 7e6e3eb3: the knob and its display on 0c47b59a, node 5b673577; interface 1.0.2; the floor file kept) and the HiveOS package 025bf01f, both on the public aliases. Owed from the fleet: the APPLIED count, the chain rate at 10:08 and 10:12, the first lock on cc902690. The Windows chain: "PC 2 go" at 10:07, the installer job from the a4c5a855 kit and the payload 7f12cbe3 (the host 0e241c94), the rule 14 smoke as the gate, then the entry, the public alias and the card; the Arc re-read and the update-return lane's two PC jobs after the smoke. The 0.3.25 plan to the coordinator before 14:00 BST. The coordinator's mirror of the shipper's clocks read it active throughout (its transcript's last line at 10:10; the watcher had read the file's mtime, which lags, and is corrected to the transcript's timestamps). After three lost floors and a stood-down night, 0.3.24 is on Devnet 3 with class v5 at DAA 68,400, about 12:54 BST. THE 0.3.25 PLAN (the shipper, 10:1x BST, from the mirror's tips). Branch and pairing: the app line release-0.3.25 from release-0.3.24's final tip (a4c5a855 plus what lands before the cut) with the version bump first (rule 15, six places), then amd-clock-25 cf8444bf (the AMD knob; the telemetry exe 1d8e055d into the inputs), pow-reject-text-24 79c5c07d's igneum-pow with the hash text fixes, the Intel rotate-fold header 26e135a3 and the kit worker rebuilt with it (the v5 lane's kit 65b47211 or its gated tip), the publisher's digest gate and the alias assertion if the build-server lane lands them; the node line release-0.3.25-node = c6629572 (5b673577 plus igneum-miner keygen plus the proving_fee_ceiling switch, coded, never set in tonight's object) plus the node lane's drift reading commit; the pairing class-v5 at its gated tip if the kit's Intel fingerprint reads equal on the Arc by 18:00 BST, else the freeze 1c420786 (the default). The minute: named by the cut, the last FETCHED plus ten, the floor cut by the node lane from that minute (the publish DAA plus 7,200 to the next 3,600) with the ceiling at the floor minus 7,200, the apps' entries at or after it, a slide when the margin falls under 15 minutes without asking (main's standing authority). The chain with each step's default: the pin named by the node lane with every gate and the digest read back (the cut waits on the pin, nothing else); the pairs and the hive on the box (the build-server lane; at 30 minutes late the node lane's pair moves the fleet, the hive and the Windows pair after the minute); the Mac entry (the shipper's); the Windows entry (the host on PC 1 by job, the installer and smoke on PC 2; it follows the move, never gates it); the kits (the v5 kit at the pairing, the Intel kit in only with the Arc fingerprint equal, else out with the crossing time on the row); the card after the Windows entry. The gate set before the file goes: every box suite on the pin, the two canary sets with the mixed-version refusal, the fast-time SUMMARY on the shipped pair, the kaspa-pow pairing read-back, the app crate gate and pre-push on the app tip, the pack-gate line read back on every reachable box, F8 if the pairing moved off 1c420786, the F9/F1 interim at the minute minus five if F8 was rerun. The move's mechanics from today's lessons: the puller takes the pair's miner sha from the move file (the fleet's puller fix), a box with no running box-dn3.sh restarts from a quoted environment (the nine-node fault of 10:05, the fleet's third known-failed shape), build-1's three by process name with the old process's locks released first. Open: the drift reading's commit (not a consensus field by its description); the evening minute from the shipper the moment the pin is green. CARD-IN READY (the hash lane, 10:1x UK; tools/ca3-v4-amend/pc-card-in.ps1 at 3566ecfe): both known-failed shapes recorded on PC 1 (the baseline of 4 cards; "no new card" in 1 s); a relay "in" with the PC publishes one job (55-minute cap) giving the card's key, VRAM and dataset fit, the v5 and v4 fingerprints through the OpenCL kit on every vendor plus the CUDA sub-version 3 row on NVIDIA, the rate with all three power fields, the lock grid through the helper on NVIDIA (300 MHz steps from the maximum, stop at a 3 percent fall) and measure-only rows on AMD and Intel, the app's own row, the bench-log and miner-bench.json rows as RESULT ROW lines, the restore and "next". The Ember tiers' engine half on ember-tiers-25 at 91406944 (local; the push on the box test build's green by 10:45). The Arc re-read's default: 10:50 UK unless the shipper clears PC 2 earlier. MAIN'S WORD ON THE 0.3.25 PLAN (10:1x BST): it runs as written, one addition to the app line: the three-tier Ember Tune, both halves (the hash lane's engine fields and the apply Cmd on ember-tiers-25; the UI lane's tier buttons with rate, watts and the daily saving, sweep on by default at balanced, per-card wired), gated on 0.3.25 before the cut; if either half is not green by 19:00 BST the cut goes without it and the tiers ride 0.3.26, stated in the record; everything else stands, the silence-means-go at 17:00 and the shipper's minute; two readings to main: one when the pin is green, one at the minute. THE FOUNDER'S WORD AT 10:2x BST: push 0.3.25 everywhere as soon as possible; the plan stands in every mechanic, the clock moves: the cut goes the moment its inputs are green, not tonight. The targets: the node line placeable 11:30; the app line assembled by 12:30 (the AMD knob and exe, the hash text fixes, the Intel header and the rebuilt kit worker, the tiers if both halves are green by 12:30, else they ride 0.3.26 and the record says so); the pin green by 13:00; the move at the last FETCHED plus ten but never before the class v5 crossing at 68,400 (about 12:54) has been read clean by the node lane, so the earliest minute about 13:30; Mac and Hive at the minute, Windows behind it within the hour, the card after; the pairing default 1c420786 unless the Arc fingerprint reads equal by 12:30; the defaults and the slide authority stand; main's silence past any of these clocks means go. THE TIERS' UI HALF (the UI lane, 10:52 BST): branch tiers-25 off release-0.3.24 a4c5a855 = the UI commit e6571f60 plus the merge of the hash lane's ember-tiers-25 3408db40 (d3d0704a); the UI tests known-failed first then 73 green on build-2; mock captures of the three states (the measured 5090 and 5080 at Balanced; the install's first minutes with nothing measured and Ember Tune on at Balanced; the M5 Max with no lever as Stock alone with the reason) under ~/Desktop/igneum-previews-2026-10-08/tiers/; the app crate gate and the full pre-push gate running on the merged tip, the gated tip by about 11:15, inside the 12:30 default; tiers-25 fast-forwards onto release-0.3.25 when the shipper opens it from a4c5a855; the live tier numbers come from the engine's own search, not from any table. THE BUILD-SERVER LANE'S CLOCKS (10:1x BST): the 0.3.25 pairs the moment the pin is named (the start script parameterised on the pin); the publisher's digest gate (publish-manifest.sh --node-bin, --network-digest, --move-clock; tools/digest-read.sh) landing on master before 12:30 and riding the app line (the alias assertion not its own); the telemetry exe's --tune read-back on PC 1 DONE at 09:07Z (the 9070 XT tune line: gmax 0 range -500 to +1000, plimit 0 range -30 to +10, factory 1); the second master-only deploy started 10:15 BST on master's tip. A FAULT: PC 2's 0.3.24 Windows installer failed at ISCC because release-0.3.24's .iss still carries the TDateTime line the 0.3.23 fix removed; the one-line fix with the shipper and the update-return lane, the republish on their tip (the Windows entry's default: it follows the move, never gates it). A SPEND TO SURFACE: two new Hetzner boxes provisioning (build-3 HEL1 32 threads, build-4 FSN1 96 threads, in the pool by 10:45), reported by the build-server lane; ordered on the founder's own word in chat ("re order", about 09:5x BST, after he added the credit himself; main clicked the order in his Chrome profile); the standing rule on purchases held; they stay. SITE DEPLOYED AGAIN (the build-server lane, master f98e8e7c at 09:15:33Z, 10:15 BST, on igneum.network and igneum.com; the checks ok): the tip carries ae8836f8 (row 17's floor sentence, the Arc row restored to its measurement) and the record through the twenty-eighth landing; the served state now carries every served change of the night and morning. THE 0.3.25 NODE LINE PLACEABLE (the node lane, 10:1x BST, ahead of 11:30): release-0.3.25-node = c6629572 on both mirrors (the pin 5b673577 plus igneum-miner keygen and the proving-fee ceiling switch coded and never set), pairing igneum-pow 1c420786; every gate green at 09:16:28Z (build 09:13Z rc 0, igneumd 3fadca49..., /srv/artefacts/0325-c6629572/node-lane; consensus 134, pow 19, miner 29 with the keygen test, p2p-flows 38, exec 48, core 177 at gate priority after a first run on a stale file on the box); the Devnet 3 canary (09:13:25Z to 09:15:04Z): digest cc902690 unchanged, byte 6, the override refused, two empty nodes handshaking, the shared-devnet dialler rejected, and the 0.3.24 pin's node handshaking with this build both ways, so the mixed fleet runs through the placement; the testnet canary b2e856ed unchanged. The keygen read-back from the artefact printed an address and a key (the key elided in every transcript and record; a printed private key never enters a message, a log the relay carries, or this file); the fleet writes keyed wallets from it. The defaults: the line's tip at 13:30 BST is c6629572 plus the drift reading's commit only if both nodes' logs reach the node lane by 12:30, else without it; the ceiling-switch field set in the 0.3.25 object from the shipper's minute by the one-go script (the digest moves then; the hold's second day under the ceiling, as main ruled; a re-cut without asking under a 15-minute margin); the crossing line the moment the DAA passes 68,400, a red first; the TESTNET_PARAMS v5-at-0 re-cut at 13:30 unless main says otherwise by 13:15. THE AMD KNOB'S GATED TIP MOVED (the update-return lane, 10:15 BST): amd-clock-25 e2962b89 (full gate GREEN 60, the box suite 298 green) in place of cf8444bf, with the shipper; from the exe's read-back on PC 1: the integrated Radeon's tune line carries every range as a dash and the knob had read it as an offset knob with a one-MHz ladder; it now reads "not available (the driver exposes no tuning interface for this card)", and the 9070 XT's real line (gmax 0, range -500 to 1000; plimit 0, range -30 to 10; stock 3,292 MHz under load) is the test's second half: the ladder 3,192 down to 2,792, the power 70 to 110 percent, offsets on the apply; the grid by 11:20, the efficient point into EFFICIENT_W before 12:30 or the declared ladder ships. THE MOVE'S READ-BACK (the fleet lane, late against its 10:20 minute): APPLIED on the relay at 09:07Z: 24 MATCH by the puller (igneumd 2.1.0-5b673577, digest cc9026909eddbadb, synced; dn3-g1 at peers 24), p1-3080 on cc902690 by 09:10Z; 2 FAILED (dn3-r01, dn3-r02: no saved environment, hand-started yesterday) moved by hand at 09:10:27Z; 9 MISMATCH with no node after the puller's restart (hub-1, dn3-g2, dn3-q04, dn3-q05, dn3-r04, dn3-p02, dn3-p04, dn3-p05, dn3-relay): the saved environment line NET_ARGS=--devnet --devnet-suffix=3 unquoted, so sourcing it ran "--devnet-suffix=3" as a command and the start never reached box-dn3.sh; all nine moved by hand 09:11:58Z to 09:12:24Z with every value quoted, the puller now quoting every value (redeployed 09:16Z on 34 boxes); so 36 of 36 fetched are on 5b673577 and cc902690 by 09:12:24Z (10:12 BST). The first lock on cc902690: checkpoint 1931, block 63510971..., blue score 57,930, at 09:06:32Z on dn3-g1 (4,803 signed, 69.8 percent of active, 66.7 of total); hub-1 logged the same checkpoint at 09:11:43Z after its hand restart and checkpoint 1944 (blue 58,321) at 09:12:39Z. The chain rate: hub-1 read 0 blocks a minute at 09:07Z because hub-1 was one of the nine down; from 09:12Z the tip moves at about 0.4 chain blocks a second as before, and paidShards moves again (11,821, frozen since 03:32Z, to 12,012 at 09:19Z, pool entries 47): carrying resumed with the move, the node lane's one-shot-gossip class confirmed. The proven share at 09:19Z 0.465 cumulative (the hour's own 0.000, the hour being the move); the proving fee 10,000 gwei per pgas last, 50,566 max over 60 blocks (1.0x and 5.1x the floor), the field now on the hourly line. The unfetched: dn3-agg48 (the L40S in its bring-up, applying at its first tick), p2-3090-1 (ssh refused since 21:48Z yesterday, on 2720d8d2 with 4 old-digest peers), p2-4090-1b (its Vast proxy dead, its node down); dn3-relay fetched at 08:48Z and is on cc902690. The eight "bc5945fe" boxes: no such binary (that sha was the reader's own shell); those boxes had no node at all (dn3-g2 dead since 22:49Z, dn3-g1 since 00:46Z, the others overnight, no panic or OOM on any), restarted 08:43Z to 08:53Z, took the move with the rest, and mine where they mine. The keyed-wallet write not started (the 0325 artefact's first mention to the lane at 10:20; box by box after the launch fleet's first boxes are up; the rent running since 09:16Z). p1-5090's drift reads offset -5 again at 09:21Z; hub-1's numbering against build-1's node the next read. Three fault classes for the record from one move: the unquoted environment line (fixed in the puller), the two hand-started boxes with no saved environment, and the eight boxes that had silently lost their nodes overnight with no panic (a watch for a node absent while its box is up is the fleet's next check). THE TIERS GATED FOR THE CUT (the UI lane, 10:20 BST by the Mac's clock): tiers-25 at d3d0704a on the mirror (the UI commit e6571f60 plus the engine half 3408db40 merged, both off release-0.3.24 a4c5a855, a fast-forward onto release-0.3.25): the app crate gate GREEN 299 + 35 + 8 on build-2, the full pre-push GREEN 60 checks with the stamp, the UI tests 73 green known-failed first, the push gate GREEN; the captures under ~/Desktop/igneum-previews-2026-10-08/tiers/; sent to the shipper; two hours inside the 12:30 default; a rebase and re-gate inside the hour if 0.3.25 opens from a later tip. Both halves of the three-tier Ember Tune are in the cut. THE 0.3.25 APP TIP (the shipper, 10:29 BST, two hours ahead of the 12:30 target): e0d4425f on release-0.3.25 (the box gate green): amd-clock-25 e2962b89, tiers-25 d3d0704a (both halves), the Intel header via 9088293a, the node-source pin c6629572; the node pin candidate c6629572 with the digest cc902690 unchanged; the cut list r0325-cut-list.md: the pin named by 13:00, the move no earlier than 13:30 after the 68,400 crossing reads clean; the pairing 1c420786 unless the Arc reads equal by 12:30, the Intel kit on that read. THE 0.3.25 NODE LINE'S TIP MOVED (the node lane, 7bd2940f on both mirrors at 09:24:03Z, every gate green at 09:29:48Z): c6629572 plus the one-shot gossip fix (unpaid proof records re-announced every 120 s; the class confirmed on the live chain after the 09:05Z move); nothing consensus, the Devnet 3 digest cc902690 unchanged on its canary, the 0.3.24 pin's node handshaking both ways, the testnet digest unchanged; build 09:26Z rc 0 (igneumd 16dee9f1..., /srv/artefacts/0325-7bd2940f/node-lane), exec 49, pow 19, core 177, p2p-flows 38, miner 29, consensus 134 at gate priority; it replaces c6629572 as the placeable keygen build and as the tip the ceiling-field cut lands on; the shipper has the line. The drift item is off this line: the fleet's reads were shared-devnet reads (hub-1's node on 26790 at chain block about 190,900; Devnet 3 at 25,900; both answering chain id 4463 below the floor), p1-5090 a shared-devnet prover, and the three numberings at one hash are the snapshot-inherited class (build-1's node1 itself resumed from a snapshot); the fleet rents a fresh-walk node under its standing ceiling to settle which numbering is right, hub-1's restart held until then, the loader change (re-number the resumed range against the DAG) after that read. THE 0.3.25 PAIRS ON 7bd2940f (the build-server lane, from 10:33:11 BST on build-1 under lease class release, /srv/artefacts/0325-7bd2940f/: the seed about 10:36, the Windows pair about 10:38, the hive package with the three kit zips about 10:41, each minute to the shipper and the coordinator); the c6629572 pairs already built (seed f913e3e7, win 42d0dd57, hive 14d86245) stand in their own folder and are not the cut; the publisher's digest gate on master since 10:17, riding the 0.3.25 app line. THE RE-POINTED APP TIP (the shipper): 92f004f1 on release-0.3.25 (e0d4425f plus the node-source pin to 7bd2940f), the push gate GREEN at 10:32 BST, the box gate GREEN at 10:33:25 (303 + 35 + 8); the cut list's pin candidate 7bd2940f; the kit re-cut from 92f004f1 and the pairs on 7bd2940f's artefact with the build-server lane; the Mac node pair and the DMG rebuilding on 7bd2940f under the lock from 10:32:31; the 13:00 pin and the 13:30 earliest minute standing. The 0.3.25 inputs are all green at 10:33 bar the pin's own gate set and the crossing. A SWEEP FINDING FROM MAIN (10:4x BST): on a rented, power-capped RTX A4000 (114 W cap) class v5 reads 26.0 MH/s against v4's 31.4, 17 percent under, the fingerprint equal; the A100 1.3 percent under; every uncapped consumer card level: v5 costs more compute per hash and a compute-limited card pays, which is what a knee lock makes of a card. Two orders with readings by 12:30: (1) the hash lane sends the 5090's v5 pack rows at the 1,300 lock against v4 at the same lock, and the 5080's if they exist; if v5 at the knee loses more than 2 percent, the knee is re-found under v5 and the tiers table says so; (2) the tiers' engine half: a class change (the chain's program class flipping) invalidates the stored tiers and re-runs the search within ten minutes of the crossing, the first-run line saying why; known-failed first (tiers stored under v4 must read "re-measuring for class v5" after the flip, never apply as if current); on 0.3.25 if it fits by the cut, else 0.3.26 with the record saying the v4 tiers may be off by the measured percentage until the re-tune. Per tier: a locked card may lose a few percent of rate at the class v5 crossing until Ember re-tunes; the number is the 5090 row. THE ORDERS PLACED (the coordinator, 10:4x BST): the hash lane's two readings by 12:30 (the 5090's v5 rows at the 1,300 lock against v4 at the same lock, the 5080's if they exist; the knee re-found under v5 if the loss is over 2 percent; the default if the PC 1 queue cannot run it: the A4000's 17 percent stated for a capped card and "unmeasured at the knee on the 5090"; and ember-tiers-25's class key: a class change invalidates the stored tiers and re-runs the search within ten minutes, known-failed first), the UI lane's class-flip state ("re-measuring for class v5", v4 tiers never applied as current after the flip) and knee note by 12:30, the shipper's cut list carrying both on 0.3.25 only if green by the pin at 13:00, else 0.3.26 with the record's sentence that the v4 tiers may be off by the measured percentage until the re-tune. THE 0.3.25 PAIRS ON build-1 (the build-server lane, /srv/artefacts/0325-7bd2940f/): the seed pair at 10:34:44 BST (igneumd c7fc542b, igneum-miner 4494ecc4, glibc 2.34), the Windows pair at 10:36:13 (igneumd.exe 5d1dea23, igneum-miner.exe eee7bdfa), the hive package igneum-hive-0.3.25-7bd2940f.tar.gz at 10:37:49 (sha d977797f..., the three kit zips, smoked in ubuntu:20.04); the kit re-cut from 92f004f1 (sha 676240f6, 424,540 B) staged in both folders, the PC 1 host from it bc8d4f79 (in host.sha256 at the shipper's 24680e1d), the 0.3.25 Windows payload from 24680e1d cutting. Every pair of the cut exists by 10:38; the pin's gate set and the crossing are the only waits. FOUR NEW LANES ON THE FOUNDER'S ORDER (11:00 BST, "build all this today to close this gap"), mirrored by the coordinator as the shipper's clocks are: the explorer (a5ef1d5801084005b; explorer.igneum.network by 16:00), the canonical DEX and the Sepolia certificate verifier (a74a8267813d6ea34; the AMM by 14:00, the swap UI by 17:00, the verifier by 20:00), the builder pages, faucet and grants (adb29da59baf27898; /build and /grants by 15:00, the faucet by 16:00), three reference apps that only work on a proven chain (a2060899d2a27d31c; /light by 16:00, /receipt by 18:00, the Sepolia oracle demo by 21:00); the build-server lane stands up rpc.devnet.igneum.network by 12:00; they do not touch the 0.3.25 cut, the crossing or the fleet, sharing the boxes' lease pools (class measure) and the master-only deploy; a lane silent past 25 minutes gets the word from the coordinator and then main. THE FAST-TIME GATE ON THE 0.3.25 PAIR: SUMMARY PASS (cross-0325-39f127a1) at 09:54:40Z (10:54 BST) on the pair 39f127a1 (the node code and object byte for byte e0644958's; igneum-pow at the freeze 1c420786), build-1 under lease pool class v5, 09:42:25Z to 09:54:40Z, every check green (rung 1 by signal at epoch 6, class v5 by signal at byte 6 from epoch 8 at rung 1 at 9,985 bps, the stale node refused, the restart step resynced in 8 s, four sinks equal, 0 PoW rejections); the ceiling's two new fields absent from the 60x file so the ceiling stayed at never there (the node lane's note); to the shipper the same minute; the pin line names e0644958 and its gates. THE FOUNDER'S WORD AT 11:0x BST ("can we add in any more layers? class rotating? things that would render an ASIC useless as soon as it dropped"): the class v6 design opens today as a rotating family, the research lane and the hash lane under the coordinator, the design doc docs/design/class-v6-rotating-family.md by 18:00 BST with the chip-model rows beside each layer (what it does to k and capex for a fixed-function chip and to the per-joule edge for a GPU-like chip; what it costs every GPU tier, Apple included): (1) per-era draws of the class parameters now fixed by release (the mixer round count within the tested margin, the op-mix weights within the measured safe band, the read width, the program length, the shadow placement), drawn from chain state like the program; (2) the state-derived dataset's size tracking chain-state growth with a floor, so fixed-memory silicon ages out; (3) scheduled family epochs by height (every 180 days by default) with no release; (4) the (c''') acceptance floor and the F8-form uniformity test generalised to each era's parameter draw, redraw on failure, so layers 1 and 3 need no per-era cryptanalysis. Per layer: the gate it needs (the family analysed as a family: the attack board's shape over the testnet period), the known-failed test, an honest line on what a fully general chip still gets. No consensus code this week; the document, the numbers and the gate plan. Per tier for the founder tonight: what each layer does to a chip on its release day and what it costs a 5090, a 5070 Ti and an M5 Max. THE ARC RE-READ IN ITS CHAIN (the hash lane, 10:57 UK): no clear came from the shipper, so the default ran at 10:50: the rotate-fold kit's fetch (sha 65b47211) published to PC 2 at 10:51:41, the run (run-ca3-pc2-v5-intel-bench-20261008, the v5 lane's script c0d398a1) in the publish chain behind another lane's publish-jobs.sh sign --deploy from the build-server worktree (the publisher serialises); the fingerprint line by 11:15 if the publisher frees inside ten minutes, else the blocking process named by 11:10. Queued on PC 1 behind the same publisher: run-ca3-pc1-v5lock-5090-20261008 (class v5 against v4 at unlocked, 1,300 and 1,200 MHz, the v5 kit's CUDA packs), its rows by 12:30; the AMD grid after it from about 11:25. The class-key work on ember-tiers-25 started; the v6 cost rows by 16:00 taken. THE TIERS' CLASS-FLIP STATE, THE UI HALF (the UI lane, 10:57 BST): tiers-class-25 at d949e274 on the mirror, off release-0.3.25's tip 24680e1d (the shipper having merged tiers-25 d3d0704a into release-0.3.25 at 111dae69), the crate gate GREEN 303 + 35 + 8 on build-1, the full pre-push GREEN 60, the UI tests 74 green known-failed first (the v4 tiers stayed on the buttons after the flip on d3d0704a); after the flip the table reads "re-measuring for class v5" on every button with the start minute or "queued (within ten minutes of the crossing)", the v4 watts never current, the strip's sentence naming the crossing; the knee note under the table when knee_loss_pct is over 2 percent; the captures tiers-flip-dark.png and -light.png; the fields tiers_class, program_class, tiers_remeasure_at, knee_loss_pct (the shape sent to the hash lane at 10:4x; the engine sha by 12:30); the default: the display rides 0.3.25 inert if the engine half is late and lights up on 0.3.26. THE FOUNDER'S WORD AT 11:1x BST: class v6 is DECLARED with the four layers as its spine (per-era parameter draws, the dataset tracking chain state, scheduled family epochs by height, the acceptance floor generalised to parameters), and deep past-and-future research opens now under the coordinator with serious resources ("see if anything can be optimised, added or invented"; reading public research is in-house, nothing paid or asked of anyone outside): four research lanes today, (A) history (every ASIC-resistant proof-of-work and how it fell or held: Ethash and the E3 and Linzhi chips, ProgPoW's review, RandomX and its chip analyses, Cuckoo, Equihash and the Z9, Argon2 and Scrypt and the Litecoin chips, KawPow, Autolykos, Octopus, kHeavyHash's chips; the exact mechanism each chip used and what the design missed, each mapped to Igneum's layers with "does v6 close it" as a sentence and a number), (B) the hardware future five years out (PIM and processing-near-memory, HBM3e and HBM4, LPDDR6, 3D DRAM, CXL memory pools, wafer-scale, chiplets, FPGA with HBM; for each the chip-model k band against a state-sized dataset and dependent random reads, and the one layer that would blunt it), (C) invention (layers beyond the four, each a paragraph, a known-failed test and a chip-model row: data-dependent program graphs, latency-bound dependent reads tied to the shard proof, randomised memory topology per era, VRAM-size ratchets, proof-carrying hashes sampled by the pool, time-locked parameter commitments, and what the lane invents; rejecting what costs GPUs more than chips), (D) the family gate (how a parameter family is cryptanalysed as a family: sampling bounds, coverage, the F8-form and (c''') tests over the parameter space, the attack board's shape over the testnet period, so layers 1, 3 and 4 can be automatic with a proof of what was tested). Resources: all four boxes under lease class measure, PC 1 by job for card rows, the rented fleet for one-shot measurements inside the ceiling. Deliverables: a first synthesis in docs/design/class-v6-rotating-family.md by 20:00 BST (the four layers priced, every finding from A to D with its number, a ranked list of what v6 adds beyond the four, the honest line on what a fully general chip still gets), the full report by 09:00 tomorrow, one line to main per lane as each lands; per tier at 20:00: what v6 does to a chip on its release day and what it costs a 5090, a 5070 Ti and an M5 Max. THE 0.3.25 APP TIP AND PIN CANDIDATE (the shipper, 10:58 BST): the app tip 9b93e649 (push gate GREEN; the crate unchanged from e0d4425f; the node-source pin to e0644958 and host.sha256 bc8d4f79); the pin candidate the node lane's ceiling cut e0644958 (digest 1b37cb9d, every gate green 10:53, the fast-time SUMMARY PASS 10:54, the floor at DAA 82,800 about 16:53 BST, a publish up to 14:53 without a second cut); the tiers' class-key halves: the UI lane's tiers-class-25 d949e274 green and inert alone, merged with the hash lane's engine sha the moment it lands (12:30), gated as a pair on the release tip, riding only if green by the 13:00 pin; the 0.3.24 Windows take 2 failed at a new place (Inno stopped the app and copied nothing); the update-return lane owns the fix on release-0.3.25 by 12:30, the default the 0.3.25 Windows entry waiting for a clean take 3 while Mac and HiveOS move at the minute. THE FOUR CLASS V6 RESEARCH LANES SPAWNED (the coordinator, 11:0x BST, each with its worktree, its box resources under lease class measure, its clocks and the rules): lane A history (a603a938582c43ab5; the first cut docs/analysis/class-v6/history.md by 15:00), lane B the hardware future (a4f73e2a6f2d1b757; hardware-future.md by 16:00), lane C invention (a5dfe95ee8c47cd0f; invention.md by 17:00), lane D the family gate (a07a99a3788566af2; family-gate.md by 17:00); each feeds the research lane's synthesis docs/design/class-v6-rotating-family.md by 20:00 (its outline by 13:00; the hash lane's per-tier rows by 16:00); the full reports by 09:00 tomorrow; the coordinator's lane mirror carries their clocks. A HELD PUSH AND ITS CAUSE (11:00 BST): the hash lane's push of ca3-v4-amend was refused at 10:58 by the gh-account hook reading the founder's gh (his personal login active again; nothing switched by any lane); the cause is the branch's own hook, which predates the per-process fix (34b0884d): the hook runs the branch's tools/ci, so every branch older than 09:58 must merge the mirror's master before its next push, under which the check reads Igneum's own gh directory and skips under the suspension marker; the rule to every lane. Live: the Arc re-read on PC 2 (published 10:59:47) and the v5lock job on PC 1 (published 10:53, about 12 minutes). THE CLASS V6 OUTLINE ON THE MIRROR (the research lane, docs/design/class-v6-rotating-family.md on counter-asic-4, the commit after fb61ed4b, pushed 10:5x UTC, two hours ahead of 13:00): section 0 the founder's table (per layer, what it does to a fixed-function chip and to a GPU-like chip on its release day, and the 5090, 5070 Ti and M5 Max columns, measured where the night's rows exist, the 5070 Ti scaled until the hash lane's row); the honest frame on top: the four layers render a FIXED-FUNCTION chip useless on the first era its wired value leaves (one tape-out lives one era) and move nothing for the stored-dataset chip with a programmable core except the core's size and the N5 project it forces; that chip keeps 3.6x at zero premium and 2.1x at k = 1 on a 5090 at its knee. The layer table (sections 1 and 2) names the bands each draw takes and the measured rows that set them: the mixer in {4, 8, 16} (x16 open), the op-mix weights within B = 4 with shuffle and mulhi capped (shfl 55.8 pJ per op), the read width in {1, 4} words (w64 excluded by the 5 October rows), the block shape 64 to 256 (never 1,024), N left to the ladder's signal (an unconditional draw retires the Apple tier at 200,000). Open numbers asked of the hash lane with defaults at 16:00: the 5070 Ti row (the rented 5070 scaled), the x16 mixer's verifier and build (the chip model's estimate), two re-weighted shadow packs for the op-mix band (the microbench arithmetic). Layers 2 to 4 and the gate plan are skeletons with their sources named, filling by 18:00 with the four research lanes' cuts, the synthesis by 20:00. THE FOUNDER'S WORD AT 11:2x BST ("all builders are idle, load them up"): build-1 to build-4 filled now and kept above 80 percent all day under the lease pool, class measure behind the release gates, in this order of value: (1) the class v6 family gate's sampling runs for lane D (the F8-form census and the (c''') floor over the parameter bands: the mixer {4, 8, 16}, the op-mix weights within B = 4 with shuffle and mulhi capped, the read width {1, 4}, the block 64 to 256; thousands of drawn eras, the uniformity and bucket tests on each, so the family document carries measured coverage tonight); (2) the attack families at scale on the 0.3.25 pin candidate's igneum-pow (F8 to 256 seeds, F9 and F1 to 10^6 on the frozen 1c420786, the day-key scan to 2^28) as the record's strengthening lines; (3) the invention lane's candidate layers measured as packs as fast as it writes them; (4) the full suite matrix of the 0.3.25 pin on every box as the pre-pin check; (5) the Windows and hive cross builds and the sweep's reruns; the lease tool's pre-emption giving release-class work the cores when the pin's gates need them; one line to main at 12:00 with the load on each box and what runs there, then hourly only if a box drops idle. THE DRIFT CLASS SETTLED (the node lane, from the fleet's fresh-walk node, a shared-devnet node synced from an empty datadir to 191,441 chain blocks at 10:03:45Z): hub-1 and five standing boxes number the fresh chain exactly; seven boxes carry numbering inherited from an exec snapshot taken on a chain that later re-walked (+2: p1-4090, p1-a5000, pool-1, build-1's node1; +3: p2-3090-2; +4: p2-3090-4; +5: p1-5090 and p2-3090-3), and a restart on the kept datadir does not re-walk (p1-5090 at 09:22Z stayed +5); the cost: a prover on drifted numbering signs statements the hub vetoes, so the seven earn nothing from proving until they re-walk, the drift refusal stopping the waste. The node lane's word to the fleet: p1-5090 first, both snapshot files moved aside so the executor re-walks from the DAG, the re-walk timed and read against the fresh node, then the other six in series, hub-1 untouched, build-1's node1 after the 12:40Z move; if the re-walk reads over two hours the six wait for the node-side fix on the next node line (the loader re-numbering a resumed range against the DAG before serving). THE 0.3.25 PIN CANDIDATE CONFIRMED (the node lane): e0644958 on both mirrors (keygen, the re-announce, the ceiling switch at 82,800 in the Devnet 3 object, digest 1b37cb9d, the 0.3.24 pin refused both ways), every gate green at 09:53:01Z, the fast-time SUMMARY PASS at 09:54:40Z on the same object; the publish ceiling DAA 75,600 (14:53 BST); waiting only on the 68,400 crossing reading clean (about 12:54; the node lane's line the moment the DAA passes it); the shipper names the pin at 13:00; the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15. LANE C'S FIRST PACK (the invention lane, 11:0x BST by the Mac's clock; its own line read "12:1x", a clock to correct): build-1 takes the igneum-pow build from counter-asic-4 at 5984ffab, then the per-load shadow in its sound form (mx8+shl6912x1: 16 sub-blocks of 432, one pass, the form 20.2a named and never drew) as the first candidate: the acceptance census over 64 seeds and 16 drawn eras against the 16x27 form and the class v4 shape, the pack export, the F8 read at 2^24 and the verifier bench on a leased core, the first read by 13:30; build-2 next for the second candidate (warp-uniform data-dependent block selection); the candidates with no pack form (the VDF commitment, the VRAM ratchet, the pool-sampled witness, the state-tied reads) stay modelled and the 17:00 cut says so; the worktree igneum-wt-v6-invention on class-v6-invention. THE WINDOWS INSTALLER CLASS AND THE 0.3.25 TIP (the shipper, 11:08 BST): the app tip 139c147a (9b93e649 plus install-detach-25 52a34111, packaging/windows and tools/ci only, the crate unchanged; push gate GREEN); the 0.3.24 take 2 class: an installer started under the app's job runner is a child of the engine, and the engine's kill_tree on quit ended it between PrepareToInstall and the copy; the fix re-launches the installer as a one-shot scheduled task outside the job's tree; the 0.3.24 Windows entry skipped; the rule-14 take on PC 2 is the 0.3.25 installer over the running 0.3.21 app, queued ahead of the Arc re-read; the pin candidate e0644958, the DMG 501ba293 staged, the 13:00 pin and the 13:40 provisional minute standing. THE ATTACK FAMILIES AT SCALE (the attack-pass lane, cores held at 11:08 BST, every run under lease pool class measure): box 2 (88 cores): F8 seeds p66 to p257 (192 new, 256 with the gate's p2 to p65) at 2^24 on class v5 at the freeze 1c420786 (the gated binary 0f5c98dc, pairing e5a4ac5978462156; the leaves re-run on 8f481459 if the kit pairing flips), the window-model control, by-site, as three thirds of 64 seeds; box 4 (80 cores held, 16 asked): F9 to 10^6 on 1c420786 (seeds 100,000 to 999,999 in six chunks of 150,000 at 8 threads, four running), F1 to 10^6 class v5 programs on 1c420786 (one census at 40 threads with the progress line and flushed partials, re-drawing the record's first 10^5 on the way as a reproduction check), the F4 day-key scan to 2^28 on 8ca66afa's redraw rule at 8 threads; nothing on build-1 or build-3 (lane D's); the projections: F4 about 2 to 3 hours, F8's 192 seeds about 9 hours, F9's 900,000 and F1's 10^6 about 30 hours each, so the 17:00 default is partials for those two with the lane (d) rows carrying counts so far; any pre-emption by release-class work reported. THE RPC AND THE 0.3.25 PAIRS ON THE PIN CANDIDATE (the build-server lane, 11:0x BST): rpc.devnet.igneum.network up since 11:08 BST (the first of the founder's builder clocks, 52 minutes ahead); the 0.3.25 pairs on e0644958 running on build-1 since 11:06 (the app tip 139c147a), the Windows and hive crosses on build-2, build-3 and build-4 as reproducibility rows at class release by about 12:40; the sweep reruns' list not held by the lane, the default at 12:30: last night's sweep logs on build-1 read for rows that ended without a result line and those rerun at class measure. THE SWEEP RERUNS' LIST (the fleet lane to the build-server lane, 11:1x BST): the fleet ran nothing under the build boxes' lease pool last night (every fleet bench a rented GPU one-shot), so the rows the lease kills cut short are the hash and class lanes' and the build-server lane's default read on build-1 is the right one; the fleet's own rows without a result (A10, A40, A100 40 GB, H100 NVL, H100 PCIe, MI250, RTX 3050, RX 7800 XT, 7900 XT, 7900 XTX, 6900 XT) are provider gaps needing a GPU host, rerun the moment a provider lists one. THE CLASS-FLIP TIERS, BOTH HALVES (the UI lane, 11:13 BST by the Mac's clock, 1 h 47 min inside the 13:00 pin): tiers-class-25 at 081b3ba7 (the display d949e274 plus the hash lane's ember-tiers-25 0a838072, on release-0.3.25's 9b93e649; the field names matched exactly): the crate gate GREEN 305 + 35 + 8 on build-1, the pre-push GREEN 60, the UI tests 78 green known-failed first, the push gate GREEN; with the shipper. A RED ON THE RELEASE TIP, for the shipper and the update-return lane: release-0.3.25's 139c147a is red on one crate test (ota::return_tests::no_relaunch_while_an_installer_runs_and_a_relaunch_when_it_clears, 304 of 305): install-detach's 0c588b09 reshaped the installer's clear step into a multi-line block while the test asserts the one-line literal at app/igneum-app/src/ota.rs:1348; 9b93e649 passes; the fix is the test's literal on the install-detach line; the UI lane built on 9b93e649 so its tip is green alone. A RED FROM THE PIN MATRIX (the CI steward, 11:13 UK): the core suite fails on the pair (the node e0644958 with the app tree 9b93e649): config::params::tests::fast_time_60x_file_is_the_devnet_at_60x panics "override-60x.json lacks the field base_unit_decimals"; the field was added by 0e4ec18a on ca3-v4-node yesterday at 21:45 UK and reached neither master, release-0.3.25 nor the app tip while the node line's test demands it; so every box reads red on core, and the fix is one line on release-0.3.25 (the cherry-pick of 0e4ec18a, or "base_unit_decimals": 8 in infra/fast-time/override-60x.json); sent to the shipper; green so far pow and app on build-1 and build-3; the two new boxes' toolchains read the same as build-1 (Ubuntu 24.04.5, glibc 2.39, the pinned rustc, sccache and lease, no nvcc). The founder's fourth load item paid in its first ten minutes: a red no single-box gate had read. MAIN'S WORD ON THE TWO REDS (11:1x BST): the install-detach fix belongs in 0.3.25 if it can make it, since a Windows install by any path that lets the engine's job runner kill the installer mid-copy is the plug-tune-play fault class (an update a user repairs by hand); the default order: the update-return lane fixes the ota.rs literal by 12:00; if 139c147a plus the fix is green on the crate gate by 12:15 the cut goes from it, else from 9b93e649 with the detach on 0.3.26 and the record saying Windows installs by job stay unreliable until then; the missing 60x field: the CI steward lands the one-line field on master and the release line by 11:45; the pin slides under the shipper's authority inside 14:53. THE DAY-KEY SCAN TO 2^28 (the attack-pass lane; class-v5 8ca66afa's redraw rule, build-4 under lease pool 8 class measure, 379.2 s, census-2p28.md at 10:15Z, 11:15 BST): days with any gain over 1.1x: 0 of 268,435,456 on M1 (median 226), 0 against the mean, 0 on M2, 0 on ROT and RC; the M1 cost mean 225.791, sd 6.073, min 206 (day 27,016 at 1.0971x, the redraw rule's floor: no day under 206 in 2^28), max 258; every weak class on its analytic expectation (ROT any pair summing to 32: 160,354,008 against 161,256,979; RC any zero: 1 against 1.0, at cost 234, no gain; RC with rk = 0: 87 against 72, 1.8 sigma; the two cells under expectation the rule's own refusals). PASS: no chip buys a weak day in the first 735,000 years of days; at most 1.097x on the best day. The row and f4-weakday.md section 10 committed on attack-pass at eabb4b0e, the push held by the branch's old hook (the fix: merge master, under which the check reads Igneum's own gh directory and skips under the suspension marker). THE SWEEP RERUNS' READ (the build-server lane, 11:18 BST): build-1's records hold no hash-lane or v5-lane run the pool cut short (preempt.log: three TERMs all night, every one to an adv-class holder pre-empted by a release gate, not reruns by rule; no reaped.log; builds.jsonl for 18:00Z to 09:00Z 150 rows with no signal end, the non-zero rows the fast-time gate's designed failed cases and build errors; the census and fingerprint suites leaving no builds.jsonl row and no output directory ending without its result); live at 11:17Z the family gate's v5_attempts_census holding 24 cores on build-1 at class measure; the default at 12:30 if neither lane names a run: no reruns, the boxes carrying the e0644958 reproducibility crosses (build-3's Windows pair already read: igneumd.exe 4b0c3aeb, igneum-miner.exe b3da4088) and the gates. The founder's fifth load item is therefore the crosses, not reruns. The attack-pass branch merged master and pushed (460fd9fa, the F4 2^28 row and f4-weakday.md section 10 on the mirror; the hook skipping the gh read with its suspended line; nothing switched). THE FAMILY GATE'S FIRST COVERAGE (lane D, 11:2x BST by the Mac's clock; its own line read "11:3x"): the harness live on build-1 under lease pool class measure (scripts and pinned binaries under /srv/builds/_adv-family-gate/): (1) the base control v5_attempts_census on the shipped class v5 draw over f8-label seeds 1,000 to 11,000, 24 cores since 11:16; (2) the family harness family_gate_era_census (branch family-gate-v5 = class-v5 8f481459 plus the harness, never a chain path; the acceptance keyed on the family's shapes behind IGNEUM_FAMILY_GATE): one drawn era per seed, every layer-1 parameter from the era's own stream (the shadow block {64, 128, 256} x {108, 54, 27}, the mixer {4, 8, 16} recorded, the read width over {1, 4} words, the ten weights within B = 4 with shfl and mulhi never raised), the chain draw through the real rule with every candidate's first failing part, then on the accepted program at the rule's own 2^20 sample the (c'')/(c''') ratio, the largest 256-item bucket per site (ratio and sigma), the index-bit bias per site in sigma; the 16-era smoke run PASSED at 11:21 (about 10 core-seconds per era; 10,000 eras about 28 core-hours). THE WORST READINGS IN THE 16: (a) the index-bit bias read fires HARD on 7 of 16 eras, |z| 130 to 511 at one site, every one at address bit R (the era's stride rotation) or R+1 (era 15 with R = 25 bit 25 z -511 at P(bit) 0.25, a product's bit 0; era 7 R = 17 z -468; era 5 R = 26 z -440; era 13 R = 1 bit 2 z -255, a product's bit 1 at 3/8; era 1 R = 6 z -224; era 12 R = 5 bit 6 z -130; era 6 R = 18 z +256, an or-shaped source at 5/8), the other 9 under |z| 3.8: adv-cache-2's era-stride class measured at the acceptance's own sample on class v5 accepted programs: not diffuse at the bit level, a 25 percent bias on one address bit of one site in about 40 percent of drawn eras, which (c''') does not see (min ratios 0.9954 to 1.0000); a chip holding the favoured half of that site's window serves 75 percent of its reads instead of 50, about 1.6 percent of a hash's reads at f = 1/2 for one site, which does not move the f = 1 verdict but is an auditor's flag on "uniform random reads"; the lever is load_index's form (fold the product's low bits before the rotation), not a floor (a 6-sigma refusal would redraw about 40 percent of epochs): a class v6 design row. (b) The (c'') ratio min 0.9954 (era 7), the rest 0.9965 to 1.0000. (c) Attempts: 14 of 16 accepted at attempt 0 or 1; era 9 (shape 64, width 4, mul 11 and or 8 of 75) took 24 candidates: the lossy corner raises r, the exhaustion number to read per stratum. (d) The largest 256-item bucket: ratios 2.2 to 2.4 at full-window sites are the CLEAN maximum (65,536 Poisson(16) buckets, +4.4 sigma), so the F8-tail bound must be stated in sigma, not ratio (the sigma column in the rebuild). Next: the random stratum (10,000 eras) and the corner strata (the lossy cap, width 4, shape 64, 3,000 each) on build-1's free 64 cores, then build-3 and build-4; the first cut of family-gate.md drafted, the measured coverage table in at 16:xx for the 17:00 cut. THE OTA TEST LITERAL FIXED (the update-return lane, 11:23 BST, ahead of both clocks): ota-test-25 off release-0.3.25 139c147a, tip 53cb2f73 on the mirror, one test-only commit (the test reading the installer's clear step as the begin/end block the detach made it; the detach's behaviour kept), the box 2 crate suite 303 + 35 + 8 passed, 0 failed, the full gate GREEN 60; the shipper's cut tip 139c147a plus this commit, so the install-detach rides 0.3.25 and the PC 2 rule-14 take runs on it. THE 60x FILE, THE WHOLE FILE NOT ONE FIELD (the CI steward, 11:25 UK): the test names the first missing key in key order; with base_unit_decimals in it named emission; the file on master and release-0.3.25 lacks six keys the 0.3.25 node line's OverrideParams has (base_unit_decimals, pool_split_activation_daa, program_class_v5_activation_daa, proving_base_fee_ceiling_multiple, proving_fee_ceiling_activation_daa, subsidy_per_block_activation_daa); ca3-v4-node's copy (81 keys, master's 75 plus those six, no shared value differing) passes on build-3 by hand; release-0.3.25 got the one-field commit 907fdaf4 at 11:23 and the whole-file commit follows through the hook's gate, master the whole file behind the one-field landing; the known-failed on record on all four boxes; the green from the core re-runs in the 12:30 matrix; the risk named to the shipper: an older daemon reading the file with deny_unknown_fields. THE INDEX FOLD AS A CLASS V6 DESIGN ROW (the research lane, docs/design/class-v6-rotating-family.md on the mirror, the commit after 206e81e1): load_index folds a product's low bits before the stride rotation so no era's R lands a biased bit on an address bit (a design row, not a draw and not a floor); the evidence lane D's 7 of 16 drawn eras at |z| 130 to 511 on address bit R or R+1 with the (c''') ratio blind to it; the chip row 1.6 percent of a hash's reads at f = 1/2 for one site and zero at f = 1; the cost 0 on every card (one xor-rotate on the address path); the known-failed test lane D's 7 of 16 reading 0 of 16 with the fold; the value-level bias test in layer 4 ordered after the fold as its guard; the F8 tail's largest-bucket bound restated in sigma against its own window's Poisson expectation. The 60x commits: the one-field commit on both lines (master 7be52d76 at 11:24, release-0.3.25 907fdaf4 at 11:23), the whole-file commits in their gates behind it (release cbbaa8c4 pushing, master's queued). CLASS V5 AT THE KNEE ON THE 5090 (the hash lane, run-ca3-pc1-v5lock-5090-20261008-b, 11:09 to 11:21 UK, the 5090 alone, the v5 kit's CUDA worker on the rotate-fold build 8f481459, 60 s rows, the cleared helper sequence; an hour ahead of main's 12:30 clock): the same genesis seed, class v4 against class v5: unlocked v4 135.82 MH/s at 458.3 W (0.296 MH/W), v5 135.90 at 474.3 W (0.287); at 1,300 MHz v4 125.92 at 294.0 W (0.428), v5 125.93 at 299.8 W (0.420); at 1,200 MHz v4 115.69 at 273.3 W (0.423), v5 115.87 at 278.6 W (0.416); the Devnet 3 epoch-0 v5 pack (another seed, the fingerprint 82b19cbde8557ea5 matched on every row): unlocked 136.94 at 494.4 W, 1,300 134.10 at 315.6 W (0.425), 1,200 128.51 at 302.2 W (0.425). THE READING: at the knee class v5 loses 0.0 percent of rate against class v4 and costs 2.0 percent in watts (1.9 percent per hash), under main's 2 percent line, so the v4 knee stands, the tiers table says the class v5 rows are within it, and the UI lane's knee note stays off (knee_loss_pct 0 on the 5090); the A4000's 17 percent is a capped card's number: the 5090 at 1,200 MHz holds v5 level with v4 too, so the loss appears only where the power cap, not the clock, is the limit. Per tier for the founder: a 5090 or 5080 owner on a knee lock loses nothing at the class v5 crossing; a power-capped card (a datacentre card at its cap) loses up to 17 percent until its cap is raised or its class re-tuned. The 5080's rows after the v6 packs job if wanted; the AMD grid live on PC 1 since 11:25 (24 points, about 32 minutes). LANE B'S FIRST READING, RELAYED BY MAIN (11:2x BST), WHICH CHANGES THE CHIP MODEL AND LEADS THE 20:00 SYNTHESIS: a 2 GiB SRAM full store on one N2 die (about USD 500 of silicon, an N2 project of USD 100 M to 500 M) reads 13x to 17x the 5090 per joule at zero shadow and 2.7x to 4.8x with the shadow at the measured k band; layer 2 (the dataset tracking chain state) moves its capex, not its joules; the custom HBM4E base die (2027 to 2028) 6.5x to 14x, untouched by the four layers; PIM structurally blind to dependent random reads; and the M5 Max at 3.1x the 5090 per joule is the honest denominator. MAIN'S ORDERS: (1) chip-model-v3 gains the SRAM-store row and the HBM4E base-die row with lane B's figures and their claimed or measured marks; (2) the synthesis states the per-joule edge against the SRAM store honestly (3x to 5x with the shadow) and against the M5 Max, and prices the one layer that answers it: a dataset floor that grows on a schedule faster than SRAM cost falls, with the cost to a 12 GB and a 16 GB GPU and to 16 GB unified Apple memory stated; (3) the served chip line ("2.1x per joule at the knee") is reviewed at 20:00 with the measured basis for each clause; no served text changes before the synthesis, and if the SRAM-store reading stands the line becomes the honest range with the project cost and the clock beside it. THE SHIPPER'S THREE READINGS (11:2x BST): (1) override-60x.json: every reader in the tree is the fast-time harness, the sims and CI; no daemon on the fleet loads it; the app manifest's consensus.override is a separate 16-key object carried from the live manifest and untouched by the cut; the live chain's object is the digest's (1b37cb9d on e0644958); the harness's file only, the cut stands. (2) The cut tip cbbaa8c4 on release-0.3.25 (907fdaf4 plus the steward's whole-file commit; the crate and packaging trees byte-identical to 907fdaf4's, whose crate gate read 305 + 35 + 8 at 11:24; override-json-check passing): amd-clock-25 e2962b89, tiers-25 d3d0704a, the Intel header, the tiers class-flip pair 081b3ba7, install-detach-25 52a34111 with its test fix, the node-source pin e0644958, the host bc8d4f79, the fast-time file; the Mac DMG on it afa7f527 (45,766,741 B, the node pair 556926b1/d2dfe966), staging. (3) The knee note off on the 5090 rows. The pin at 13:00 on e0644958 and the 13:40 provisional minute standing; the matrix on cbbaa8c4 and e0644958 the steward's by 12:30. LANE B'S FIRST CUT ON MASTER (34f63b3c at 11:25 UK, four hours and thirty-five minutes ahead of its 16:00 clock): docs/analysis/class-v6/hardware-future.md with the three findings and the k bands (with the research lane, into the synthesis's section 7a on counter-asic-4 at ad37a50c); lane B's four decisions in its section 7 with defaults (the draw bounds by 20:00 via the synthesis; the dataset schedule unchanged; the M5 Max as the reference joule; the clock unchanged); nothing built or benchmarked, gh untouched; the full report by 09:00 adds detail only, no k band moving. LANE A'S FIRST CUT ON MASTER (docs/analysis/class-v6/history.md, 300 lines, merge 4c58ad65 at 11:26 UK, three and a half hours ahead of its 15:00 clock; the full gate GREEN 73 checks; primary documents read from the PDFs: the Least Authority and Bob Rao audits, Kik, EIP-1057, the RandomX design and v2, Tromp's README, the Fudan Equihash solver, Percival's lookup-gap note): 21 chip rows by mechanism (what each chip specialised, the miss, the timeline, the v6 layer, closed or not, the per-joule number), the in-depth sections (Ethash, ProgPoW, RandomX, Cuckoo, Equihash, Scrypt and Argon2, the no-chip hashes, kHeavyHash, CryptoNight, X16R, Lyra2REv2, the compute rows), the four layers against the history layer by layer, the tier consequences. THE HONEST VERDICT WITH THE NUMBER: the chip that stores the dataset (class C: every Ethash chip, the E3 at 1.0x, the Linzhi at 2.1x, the Jasminer X4 at 5.1x via DRAM hybrid-bonded onto a 40 nm logic die, the E9 Pro at 4.1x) is NOT closed by any of the four layers, every per-era draw and family epoch being firmware to it; v6 inherits 5.1x per joule on GDDR7 at zero premium (3.6x at the 5090's knee, 2.1x with the class v4 shadow at k = 1), USD 2.8 against 14.7 per MH/s; classes A, B, D's governance half and E are closed, mostly since v2 and v3. THE THREE LESSONS THAT BIND: (1) the stored-dataset chip is firmware-immune to every draw; only joules and memory growth move it; (2) automatic change beats the human fork only where it costs the chip a redesign, and the one such parameter is the memory: layer 2 as declared is not an anti-chip rate (a 32 GB board lasts 60 years at 0.5 GiB a year; the 8 GB card is out at year 12; the E3 the only chip a growth rule ever killed, 20 to 27 months after shipping, at the fleet's own 4 GB limit), so its floor and a per-tier ceiling are the numbers to fix, not the rate; (3) a steered address pattern is always found after launch unless the test lives in the acceptance rule, and every drawn parameter changes layer 4's null, so the census re-derives per era (2.2 s per candidate). CORRECTIONS TO THE 5 OCTOBER FILE: the Antminer X9 withdrawn May 2026 with zero units (not "July 2026 delivery"); RandomX v2 released 25 March 2026 with activation pending (not "no fork"); CryptoNight's secret chips at about 33 months, not 43; Vorick's "survives forks at under 5x" and "13 months for a startup" on no fetched page, marked unverified. Two asks with defaults: layer 2's ceiling (if no word by 20:00 the full report drafts it as GB per tier per year keyed to card-lifetime-2026-10-05.md, with the flag that a dataset tracking state literally outgrows every card inside a decade if state grows as Ethereum's did); the hardware file cross-cited, not repeated. The lane's web-search budget spent (200 of 200); further additions by direct fetch. LANE D'S STATE (11:2x BST by the Mac's clock; its own line read "11:5x"): the first cut committed on class-v6-family-gate at 55c0dc6a with the full gate running; the census at 640 random eras, 298 lossy-cap, 327 width-4 on build-1 and about 500 shape-64 on build-3, the two build-4 corners queued behind a full pool; the landing on the gate's GREEN, the measured coverage table in the 17:00 cut. THE SNAPSHOT DIGEST STAMP (the node lane, 11:2x BST; a wip on release-0.3.25-node under its suites since 10:28Z): every snapshot a node writes carries its consensus digest as a new last field (the day-streams field's fallback shape, so 0.3.24 files decode with no stamp); a node with its digest set refuses a snapshot stamped under another digest ("re-executing from genesis") and one with no stamp ("written by a node before 0.3.25"), the follower starting at genesis; the daemon sets the digest from its params; the tests known-failed first (another digest refused, an unstamped file refused, nothing loaded; a matching stamp resumes, the written file carries the stamp, a digest-less process resumes as before, the wire round-trips); if the suites read green the full gate set runs and it is in the pin at 13:00 BST. THE CONSEQUENCE FOR THE MOVE: every Devnet 3 node restarted on 0.3.25 re-executes from genesis (no file written before 0.3.25 carries a stamp), so the restart takes the chain's re-execution time, which a fresh 0.3.25 node on build-1 since 10:24Z measures now (about 30,000 chain blocks; the rate in the pin line). TWO READINGS BESIDE THE CAUSE: (a) build-1's three nodes differ at 26247 (node1 0x3f53a7b9, the seed 0x717e7dc8, the observer 0x4548c319), and the seed and node1 differ at block 0 already (0x275b0cce against 0x7e37a9fb), which the ba75bf6f file alone does not explain (both resumed their own files across the same restart; the seed also restarted at 02:00Z on 2720d8d2 from a 0.3.22 file); the fresh node's genesis root and its first divergence from each decide whether a second class (an older-object file on the seed, or the resume itself) is in play; (b) the fleet asked for the roots at 26247 and 15611 on hub-1's Devnet 3 node, dn3-g1 and every prover by 12:30 BST with each node's resume line. The loud status for a vetoed node (a veto counter, the last veto's line on the explorer's status, "state not fresh") on the same line if the suites leave time, else 0.3.26, the node lane's word at 12:30. MAIN'S WORD ON LANE A'S ASK (11:2x BST): the default stands (the GB-per-tier-per-year table keyed to the card-lifetime file, with the flag), and one schedule to price beside it so the 20:00 reading carries a decision: a dataset floor of 6 GiB at the v6 epoch (every 8 GB card keeps mining with its cache; the 6 GB 2060 tier drops), 10 GiB two years on (the 8 GB tier drops), 14 GiB at four years (12 GB drops; 16 GB and Apple 16 GB unified hold), each step by height like a class epoch, the schedule itself a consensus field, with the cost per tier stated as the year each falls off and the share of today's measured cards that is; against the chips: the hybrid-bonded DRAM chip sized at launch (the E3 class) dies at the first step it cannot carry, the SRAM store pays capex only, both said. Lane A's corrections to the 5 October file go into the record and the served texts tonight. MAIN'S WORD ON THE STAMP AND THE GENESIS CLASS (11:3x BST): the stamp rides the pin; the re-execution time goes in the pin line and the move plan per tier; the fleet staggers the restarts in thirds so the proving share never reads zero, and the hourly line says "re-executing" with the count until the last prover is back. The second class is a GATE, not a note: the seed and node1 differing at block 0 means one of them runs a different execution genesis, and a hub node on a wrong genesis is worse than any snapshot drift; the pin is not named until the node lane says which file each of build-1's three nodes and hub-1 loaded at genesis, which root is the network's (the fleet's roots at 26247 and 15611 decide it), and the wrong one is corrected or re-walked; if that is not read by 13:00 the pin waits inside the 14:53 ceiling and the shipper slides by its authority. The vetoed-node status rides 0.3.25 if green, else 0.3.26. THE 60x FILE LANDED (the CI steward, 11:31 UK, ahead of 11:45): release-0.3.25 cbbaa8c4 (the whole 81-key file on 907fdaf4, the hook gate GREEN 60) and master e295c0d5 (the same file, the gate GREEN 73); known-failed to green on record: core RED on the one test on all four boxes before, core GREEN on the fixed pair on build-1, build-3 and build-4 after, build-2's re-run running; the full matrix by 12:30. A NEW GATE ON THE PIN (main, 11:3x BST, from the reference-apps lane's read): node1-dn3 and the re-executed observer diverge from chain block 26294 at DAA 60,578, the 10:05 move minute; node1 executed a block the selected chain later dropped and never unwound it, so its numbering runs one high and its state and records diverge; that is the drift class and the likely cause of last night's proving collapse after a move; the stamp does not cure it. The node lane's order: a known-failed reorg test under the exec follower, the fix on release-0.3.25-node if green by 13:30, else the move with the mitigation (every node re-executes from genesis after the minute, the vetoed-node status loud) and the fix as 0.3.26 tonight; plus the roots census to count stale nodes for the fleet's re-walk before the minute; the shipper's slide authority covers the pin inside 14:53; if the fix needs past 14:53, the floor re-cuts from the next minute by the same authority; the explorer lane reads block numbers from the observer node only (the chain the certificates follow) until the fix is live. THE FAMILY GATE'S 12:00 COVERAGE (lane D, 11:3x BST by the Mac's clock, ahead of its clock): 4,900 drawn eras through the per-era tests on three boxes (build-1 random 1,444 and lossy cap 663 at 10 core-seconds per era; build-3 shape 64 at 2,162; build-4's two lossy corners queued behind a full pool); the full gate on the first cut GREEN (73 checks, 381 s), the landing on one re-gate after a merge conflict on export-exclude.txt with the research lane's line (resolved, both kept). THE WORST ERA PER TEST: (1) THE EXHAUSTION BOUND BREAKS AT THE LOSSY CORNER: with or, mul and mulhi all at +4 points (30 of 75 lossy against the table's 18), r per candidate is 0.956 (the table's 0.681) and 8 of 663 eras EXHAUST the 256-attempt cap (mean attempt 18.6, max 252), so 1.2 percent of epochs at that corner would take the last-resort program, which adv-accept-3 showed fails rule (a) in 9 percent of seeds; B = 4 with the lossy ops free to rise is therefore outside the band; the random stratum at B = 4 (every weight drawn, lossy ones included) reads r = 0.718, max attempt 107 and 0 exhaustions in 1,444, but 107 attempts is 4x the shipped max of 28; the ring-A rule the cut carries: the sum or + mul + mulhi at most the table's 18 plus B, so r stays under 0.85 (r^256 under 1e-18); the default by 17:00: B = 4 on the injecting families only, the lossy families capped at their base. (2) THE ERA-STRIDE CLASS AT THE BIT LEVEL ON THOUSANDS OF ERAS: 52 to 58 percent of accepted programs in EVERY stratum carry one site whose address bit R (or R+1, R+2) is biased at over 6 sigma at 2^20, 33 to 40 percent at over 100 sigma, the worst z 1,024 at bit 7 of a site under R = 7 (a product's bit 0 at P = 1/4 landing at bit R): adv-cache-2's mechanism at half the family's epochs on programs (c''') passes (min ratios 0.9950 to 1.0000); the chip price per site about 1.6 percent of a hash's reads at f = 1/2 against the partial-store curve's 1.26x ops cost: the f = 1 verdict stands, the "uniform random reads" sentence does not; the catch structural (the index fold in load_index before the rotation, the class v6 design row), not a floor. (3) The largest-256-item-bucket excess: clean full-window sites +4.4 sigma; the worst eras +94 to +128 sigma at one site (the F8 tail's quarter-bit class at scale, the same mechanism: the bucket at the biased bit); the bound in sigma from the clean spread in the 17:00 cut. (4) The (c''') refuse rate per stratum: random 2.56 percent of candidates, shape 64 3.41, lossy 0.42 (the lossy rejections earlier at (a')); 0 accepted programs under 0.995 anywhere. (5) VOID and rerun: the width-4 stratum ran at width 1 (the era's one-entry allowed set redrawing to the base's width; fixed, the harness rebuilt, restarted at 11:5x with its own label space); the first corner strata sharing the random stratum's label space coincide with its draw a third of the time; the reruns use per-stratum labels; both stated in the cut. Coverage by 17:00 at about 1,000 eras per hour per 16 cores: random 10,000, shape 64 3,000, lossy cap 3,000, width 4 3,000 plus the two build-4 corners; the rule-of-three line for the random stratum at 10,000 eras a failing fraction under 3e-4 at 95 percent for every ring-B test. THE V6 COST ROWS (the hash lane, 11:4x BST by the Mac's clock, its own line reading "12:4x"; four hours ahead of 16:00): with the research lane at scratch v4/ca4-v6-cost-rows.md, every row labelled measured or modelled; the layer-2 headlines: VRAM 3.2, 5.4 and 9.9 GiB at the floor, 2x and 4x; a 12 GB card falls off at about 9.5 GiB (year 15), a 16 GB GPU at 13.5 GiB (year 23), a 16 GB unified Mac at 8 GiB (year 12), the 5090 at 29 GiB (year 54); the DRAM-read cost per hash size-independent (the 5090's 1.11 microjoules of 2.29), so the layer moves capex not joules, and the card rows allow a floor of 4 GiB in year 1 and 8 GiB by year 4 without retiring a 12 GB card (main's schedule of 6, 10 and 14 GiB at the epoch, two and four years sits above that: the 12 GB tier drops at 14 GiB, the 16 GB holds); the measured size rows (the v3 pack at 2, 4 and 8 GiB on the 5090, unlocked and at 1,300) ride the v6 packs job after the AMD grid. The AMD grid: the first run refused in 2 s at no_tune_line (the old installed exe, as designed); the rebuilt exe on PC 1 by the update-return lane's fetch at 11:33, the rerun from amd-clock-25 572c3ee0 live since 11:39 (about 32 minutes, the rows about 12:15). The class key on the mirror (ember-tiers-25 0a838072 in tiers-class-25 081b3ba7, with the shipper since 11:13, inside the 12:30 reading). The Arc read waits on the shipper's PC 2 take; the 12:30 default "no Arc read" stands unless it starts before. THE DRIFT CLASS READ FROM THE LOG (the node lane, 11:4x BST): at 09:42:09Z node1-dn3 accepted 0x6aa6 (DAA 60,578) and at 09:42:10Z 0xb708 (the same DAA and blue score 60,265, both children of 0x0fed at 26293: a tie at one height); its follower executed 0x6aa6 as chain block 26294 (28 transactions) and 1.1 s later 0xb708 as 26295 (the same 28 skipped as already included), with no reorg line between; every consensus view now (the seed, node1 itself, the observer) has 0xb708 as the chain block with the selected parent 0x0fed and 0x6aa6 off the chain, so node1's records hold an orphan at 26294 and number everything after it one high, and its state root diverged from there (the observer, re-executed from genesis, agrees with node1 to 26293). THE GAP: the 0.3.22 continuity rules (ledger N15) check the first appended block's selected parent against the tip at append time and scan the whole record set against the DAG's selected parents ONCE per state generation (a restart or a loaded snapshot); a break landing after that scan, as this one did ten minutes after node1's restart, is never looked for again until the next restart; the fleet's +2 on four shared-devnet boxes is the same gap. THE FIX on release-0.3.25-node (a wip under the exec suite since 10:41Z): the self-check runs every 30 s over the ring (the last 2,000 records) against the DAG's selected parents and in full on a generation change, a break handing the records above it to the reorg unwind (the existing branch restoring the ring state at the fork and re-walking); the test known-failed first on node1's exact shape; on the same commit the snapshot digest stamp (exec 51 of 51 green on its wip) and the vetoed-node status (vetoes counted on the status with the last veto's line, stateFresh false while any stands, on igneum_getNodeInfo and the status RPC); the exec suite's green about 11:46 BST, then the named commit, the full gate set, both canaries (the digest 1b37cb9d unchanged: nothing consensus) and the fast-time pair, the gated tip by about 12:30, inside 13:30. What the fix does not do: name why the tie-break flipped under node1 at 09:42Z (its DAG now reads 0xb708's parent as 0x0fed and the path at the time must have read otherwise; the second "PoW accepted 0xb708" line 0.4 s after the append says the block was processed twice), a reading for the record after the pin. The fresh 0.3.24-object node on build-1 past IBD and executing from genesis; its root at 26247, its rate and its memory peak in the pin line. MAIN'S WORD AT 11:4x BST: (1) lane D's band default stands (B = 4 on the injecting families only, or, mul and mulhi at base, the ring-A lossy-sum rule), and the index fold before the rotation with the bias test as its guard is layer 1's rule; (2) the served sentence "uniform random reads" is corrected today, not at the review: the audit lane rewrites it to the measured statement (reads spread over the whole dataset; a bit-level bias at one site appears in about half of epochs; it prices about 1.6 percent of reads to a chip storing half the dataset and nothing to a full store; the next class folds it out), through the gate and the master-only deploy, with the ledger row; (3) layer 2's table splits Apple by memory size (16 GB unified at its 8 GiB limit, 32 GB and 64 GB Macs holding every step), the M5 Max being the honest best per joule and the Mac tier a large audience; the schedule decision at 20:00 is the founder's with that column in front of him. THE EXPLORER'S SOURCE (the explorer lane, 11:4x BST): it reads one endpoint and always has, the Devnet 3 observer node on build-1 (the execution RPC on loopback 26850 through tools/observer/explorer-indexer.mjs, the observer's own dn3_ tables on 28650); it has never read node1-dn3, so there was no switch; the indexer on 26850 since 10:04 UTC with a full refill from genesis at 10:33 UTC after the root equality read at block 26,247; the pages now name the observer node as the one source, the chain the certificates follow (on explorer-dn3, in the gate; the merge and deploy follow). THE GENESIS GATE'S ANSWER ON build-1 (the shipper, 11:43 BST): the seed was the odd node (its block 0 from the 0.3.22 binary; the rule change for the node lane's record), re-walked from genesis at 11:35:30 by the shipper's hand (the evm moved aside, the same binary and flags, the kept datadir) and reading population A's roots at 11:43:00 (0x47983bd9 at 15611, 0x3f53a7b9 at 26247, head 26,478). THE MEASURED RE-EXECUTION: 26,478 chain blocks in 7 minutes 30 seconds (about 59 a second over the walk; 100 at the start, 30 past 15,000), RSS 5.5 GB; so the move plan's per-tier line: a prover's node is back about 8 to 10 minutes after its restart on 0.3.25 (30,000 blocks at the minute), a Mac or HiveOS app node the same at its update hour, miners unaffected; with the hub and the seed at the minute and the provers in two thirds at +0 and +25, the proving share never reads zero and the last prover is back about 35 minutes after the minute. The node lane's gated tip (the ring check, the stamp and the vetoed-node status in one commit, the digest 1b37cb9d unchanged) by 12:30; the pin after it and the fleet's census; the minute about 14:10 at the earliest if the fix rides, inside 14:53. LANE A'S SCHEDULE SECTION (history.md 4.2a, master 59963461 at 11:45 UK, five hours ahead of its 17:00 clock; three landings today: 4c58ad65, b645762d with the synthesis lane's six items folded in, 59963461): ONE FLAG on main's schedule with the number: under the standing budget rule (the working set under 6 GB on an 8 GB card, the 75 percent reading) a 6 GiB floor does not fit the 8 GB tier (6,398 to 6,744 MiB, 78 to 82 percent of the card; it fits only at a headless-rig reading of about 85 percent); 10 GiB retires the 10, 11 and 12 GB tiers and the Apple 16 GB laptop at year 2 (not the 8 GB tier alone); 14 GiB retires the 16 GB tier at year 4, leaving 24 GB and above. The schedule that drops the tiers in the order main named, priced beside it: 5.5 GiB at the v6 epoch (6 GB falls, 3 percent of the 32 measured consumer cards), 8 GiB at two years (8 GB falls, 22 percent, with the 10 GB RTX 3080 and Apple 16 GB; 12 GB holds at 69 to 72 percent), 11 GiB at four years (12 GB falls, 22 percent; 16 GB holds at 70 to 73 percent); 24 GB and above hold throughout. Against the chips: the f = 1 GDDR7 chip's 32 GB board pays USD 0 through 16 GiB and keeps 5.1x; the hybrid-bonded or soldered chip sized at launch dies at the first step it cannot carry (the E3's shape, 20 to 27 months) but a maker reading a public consensus field sizes to the step it wants (USD 160 of GDDR7 on a USD 470 part); the SRAM store pays capex only at the cache doubling (USD 46 to 111 per die) and keeps 0.92x and 1.86x. So the schedule is a fleet-retirement rule with a USD 0 to 160 chip tax, killing only a chip whose maker ignores the field. The default by 20:00: the full report carries both schedules and recommends 5.5 GiB as the floor that keeps the 8 GB tier inside the rule. Owed: the fleet's hashrate-weighted card census (the shares are by count of the bench table's 32 measured consumer cards). LANE A'S CORRECTIONS SERVED (the site audit lane, master 2119e4f3 at 11:46 BST, gate green on 78166c6c, commit 14ad1a33; seven hours ahead of 19:00): every served "no chip shipped" and "seven years without a shipped chip" sentence (the litepaper's precedents row, the chip-model paragraph, the vs RandomX lead and its track-record row, the limits section; /claims and /randomx following) now carries the Antminer X5 (September 2023, 1.46x per joule over a desktop CPU, silicon believed mining privately from about 2021) and RandomX v2 released 25 March 2026 with its mainnet activation pending; the ledger rows X34 and C2 corrected with lane A's file cited, the pins moved, the public ledger and page regenerated; the X9 sentence already matched lane A's row (sales opened 26 December 2025, shipping scheduled July 2026, withdrawn mid-May with zero units), the precedents and track-record cells now reading "withdrawn in May 2026 with zero units"; the 43-month, 13-month and Vorick figures on no served page; the commit also carrying main's governance line beside the class v5 sentence and six class v4 watts rows; the "random reads" correction with its AP-F8 row next by 13:30; the build-server lane deploys on main's word. LANE C'S FIRST CUT ON MASTER (docs/analysis/class-v6/invention.md at a9f03598, 11:48 BST by the Mac's clock, five hours ahead of 17:00, with the census script under tools/attack/v6-invention/ and its two TSVs): build-1 ran the per-load acceptance census (11 forms x 256 seeds, twice: no era and drawn eras, 80 s each on 48 leased cores) and the verifier benches; the two packs exported and with the hash lane for PC 1; the second candidate (warp-uniform block selection) has no pack form without a generator change, which the no-code rule holds this week, so its row stays modelled. A CORRECTION TO THE CA4 FILE'S VERDICT, FOUND BY LANE C: the counter-asic-4 crate's per-load acceptance (BiasedIndexBit) counts the era window's fixed top index bits 26 and 27 as biased, so under any drawn era it refuses every per-load program (0 of 256 on every form today, 5,536 of 7,862 bias rejections naming those two bits); 20.2a-close's "1.4 percent accepted, 42 of 64 seeds exhaust" (the per-load class's death at 00:0x) was read across drawn eras and so measured the instrument on most rows; on the no-era census the sound form (16 x 256 x 1) reads 0.927 rejection per candidate and 234 of 256 seeds accepted, the iterated 16 x 27 form 0.989 and stays dead; the one-line instrument fix (skip bits at or above 28 minus the site's k_off) is a research-crate change, made today as a research-only change behind the pack by the coordinator's order, and the sound per-load form's verdict is REOPENED as a measured candidate (its energy and rate rows on the 5090 through the hash lane; chip-model-v3 5.11's note on the per-load closure to be re-worded when the re-read lands). THE REOPENING APPLIED (the research lane, 11:5x BST): the reopened wording in counter-asic-4-research.md (20.2a-close and rank 4), class-v6-rotating-family.md (section 7c as layer 5) and chip-model-v3.md 5.11's note, with one precision: the 22:5x UTC census ran the bare class with no era, so its 0.986 is the iterated form's own no-era figure (lane C's 0.989 agrees the 16 x 27 form is dead); the artefact in any drawn-era read before the fix; the fix already on counter-asic-4 as of 10:5x UTC (BiasedIndexBit judging only the bits inside each site's window mask through verify::window, per site), uncommitted until the suite's line lands (the box-2 slot since 10:31Z), so lane C re-reads on that branch once pushed, not making the change twice; the chip-model 5.12 rows (the SRAM store, the base die, PIM's blindness, the M5 Max denominator) in the same tree, riding the same commit before 15:00. A MIRROR NOTE (11:52 BST): lane B read silent 25 minutes by the mirror; its first cut landed at 11:25 and its next clock is the full report by 09:00 tomorrow, so the silence is its finished state, not a fault; the mirror now skips lanes whose clocks are done. A MASTER-ONLY DEPLOY AT 11:53 BST (the build-server lane, on main's own builder-programme landing d86ea00a: /build, /grants, /faucet, /swap asserted; the served sha a9f03598, master's tip; the checks ok; 38 miners rows): it carried the audit lane's 2119e4f3 (the RandomX history correction with the Antminer X5 and RandomX v2, the governance line, the first six class v4 watts rows), which main ordered served tonight and the audit lane cleared for the next scheduled deploy; the "random reads" sentences not yet corrected as served; the coordinator's trigger stands for the 13:30 correction. LANE C'S KNOWN-FAILED TEST FOR THE INSTRUMENT (11:5x BST): igneum-pow/tests/v6_window_bits.rs, the sound form (16 x 256 x 1) accepting on at least 4 of 8 seeds under drawn eras 0 to 7 with 0 window-bit refusals (0 of 8 before the fix), the no-era bit-0 refusal on seed 3 standing; 2 passed, 0 failed on build-1 against a local overlay of the same nine lines, the overlay reverted, the test file an offer to the research lane's suite; the re-read on the research lane's commit by 15:00; meanwhile build-1 runs the lane's uniformity read at 2^20 nonces on 64 seeds for the two sound per-load forms and the class v4 shape (the F8-form top-0.1-percent item share against a uniform control, the per-site distinct ratio) on a harness over the crate's trace_load_indices (the master F8 tool mirroring class v4's execution order), about 20 minutes on 24 leased cores. THE RANDOM-READS CORRECTION ON MASTER (the site audit lane, bf54b08d at 11:54 BST, gate green on db038279; an hour and a half ahead of 13:30): the litepaper's lead reads "dependent reads spread over a multi-gigabyte dataset that changes daily", the table row "the dependent reads are", the "chain of random reads into a table too big for a chip to carry" sentence standing with the measured clause after it (the 0.995 floor on every accepted program over 4,900 drawn eras; about half of epochs with one load site biased at the era's stride rotation bit; about 1.6 percent of a hash's reads to a chip storing half the dataset, nothing to a full store; the fold before the rotation in the next class); evidence row 18 with lane D's family-gate.md and adv-cache-2's section 2.3 as sources; the ledger row AP-F8-7 (AP-F8-6 taken on class-v5): "Open, priced: 1.6 percent at f = 1/2, nothing at f = 1; the served sentence corrected 8 October 2026", the disposition class v6 layer 1's fold with the bias test as guard; the public ledger and page regenerated; no pinned sentence touched; the fud-ledger's quoted history standing; the build-server lane deploys bf54b08d. BUILD-1 AT 11:55 BST (the coordinator's own read): load 107.6 on 96 cores; the lease table: the family gate 32 cores (the random stratum, 10,000 seeds), 16 (the lossy cap, 3,000), 16 (width 4, 3,000, restarted), lane C's uniformity read 24 of 48; 88 of 96 cores held, none waiting, no pre-emptions in the last ten minutes. THE 11:55 BST LOAD LINE (the build-server lane, all four boxes at the minute): build-1 (96 threads) load 113.7, the pool holding 32 for the family gate's random stratum plus 16 and 16 for its corners and 24 for lane C's uniformity read (88 of 96 held), the release and v5 builds outside the pool; build-2 (96) load 81.3, the pool holding 32 for the attack-pass F8 census (the thirds); build-3 (32) load 25.1, the pool holding 16 for the family gate's lossy-base stratum and 2 for the hash lane's x16 rows; build-4 (96) load 89.0, the pool holding 4 x 8 for the attack-pass F9 chunks 0 to 3 plus F1's 40 and F4 done; no release-class waiter on any box; the builders loaded, none idle. The founder's order at 11:2x is met at the minute: every box above 80 percent of its threads bar build-3 at 78 percent of 32, which the two queued build-4 corners and the next v6 pack take. The build-server lane's deploy of bf54b08d served at 11:56 BST, two minutes after the landing: the post-deploy checks ok (api/live igneum-devnet-3, the index strings, the legal line, 38 miners rows, the four builder pages 200), and the litepaper's lead sentence read back from the served page carries the corrected wording (wide parallel integer maths, warp shuffles, dependent reads spread over a multi-gigabyte dataset that changes daily, the program waiting on memory latency); the old "random reads over a multi-gigabyte" is absent. The CI steward's 0.3.25 pre-pin matrix with the shipper at 11:59 BST, 31 minutes inside its 12:30 clock: seven suites on four boxes, every cell green but the one known core red on the pair before the fast-time file (the same single test on all four boxes, the six missing keys), and core green on the fixed tree on build-1, build-3 and build-4 (170 passed each); build-2's re-run queued behind three lanes' suites and lands on its own; counts identical across boxes (pow 113, app 346, exec 49, miner 29, p2p-flows 38, consensus 134); the Mac's full gate on the 9b93e649 tree GREEN, 60 checks; build-3 and build-4 toolchains read as build-1. The matrix worktree sits at cbbaa8c4 (81 keys, igneum-pow identical to the pin's tree); the second matrix waits on the node lane's gated tip (by 12:30), the line by 13:15. The RX 9070 XT's first measured grid on the AMD knob (job run-ca3-pc1-amd-grid-9070-20261008-b on PC 1, 11:40 to 12:10 BST, 24 of 24 rows ok, the card reset to factory at the end): the rate flat at 18.93 to 18.98 MH/s on every point, the knob moving watts only; stock 3,292 MHz 195.8 W (0.097 MH/W); the clock offset alone to 2,924 MHz 159.2 W at -400 (0.119), clamping about 2,920 at -500; the power limit alone does nothing until -30 (184.4 W); best -500 MHz with -30 percent: 2,921 MHz, 149.3 W, 18.96 MH/s, 0.127 MH/W, a 24 percent saving at the same rate. Per tier: a 16 GB AMD home card gains a quarter of its electricity cost at no rate loss once 0.3.25's knob ships; it stays 3.5x behind the 5090's 0.43 MH/W at the lock, so last night's AMD reading stands (the read path, not the clock, is AMD's cost). The v6 packs job live on the 5090 since 12:11 BST (eleven packs including the three dataset sizes, unlocked and at 1,300, about 40 minutes). The Arc re-read not started on PC 2 (the shipper's take holds the box); at 12:30 the default "no Arc read" stands, the pairing 1c420786. The Ember priors committed on ember-tiers-25 at 1e966170 with known-failed tests, its suite queued behind build-2's slots since 11:46; the sha to the UI lane and the shipper on its green; if not run by 12:45 the suite moves to build-1 through a lease. Two master-only deploys from the builder stream, checks ok (38 miners rows, the six asserted pages 200): 0c64b24f at 12:07 BST, the explorer landing (explorer.igneum.network, /proving, /tx/, the dn3_ APIs reading "Devnet 3"; the explorer indexer unit moved to the master checkout and restarted, reading the observer only as main set), and 3355c098 at 12:16 BST (site/vercel.json only: the explorer host's root 307 to /explorer, read live). No chip text changed in either. Still in the stream: the reference-apps lane's /light, /receipt and /oracle (its gate since 11:50, the 13:00 default) and the audit lane's watts rows 11 and 12. A third master-only deploy from the builder stream: f0418c8d at 12:19 BST (main's word via the explorer lane: EXPLORER_EVM_RPC on the production env, so /api/explorer balances read live from rpc.devnet.igneum.network; checks ok, 38 miners rows, six pages); the public RPC's allow list tightened the same minute to igneum_get* (the two igneum_submit* writes refused), reported to main. No chip text changed. The /build lane DONE with every clock beaten: landed on master as d86ea00a (11:47 BST), deployed as a9f03598 at 11:53; /build, /grants, /faucet (the Devnet 3 faucet page) and /swap serving in the nav's Build group; faucet.igneum.network/api/faucet live on build-1 behind Caddy, funded 2,000 IGN by the fleet lane (11:01 BST), the first drip 11:17 BST, 1,989.99 IGN left; the walkthrough PASS through the public RPC and faucet (a contract deployed at block 27055, 24 s end to end, Foundry 1.8.5, docs/build/first-contract.md); the RPC list read from the node in docs/build/rpc.md; the audit's four wording lines in. One open fact to the fleet lane: build-1's Devnet 3 seed at 27810 re-executing from genesis while the faucet reads the observer's 26850 (the re-execution class measured at 7 min 30 s this morning). Lane D's coverage at 12:2x BST, every launched stratum complete (the runs beat the 1,000-per-hour estimate once the pools freed): random 10,000 eras (0 exhausted), lossy cap 3,000 (37 at the 256 cap, 1.2 percent), width 4 at the fixed harness 3,000 (0), width 4 plus lossy cap 2,000 (24, 1.2 percent), shape 64 3,000 (0), the lossy-base band (B = 4 on the injecting families, or/mul/mulhi never raised) 3,000 (0); 24,000 drawn eras through the per-era ring-B tests on build-1 and build-3; build-4's shape-64-lossy and shape-256 strata still queued behind the attack pass's F9 chunks and not needed for the cut. The exhaustion finding confirmed at scale: 61 of 5,000 eras at the lossy corner reach the last resort against 0 of 19,000 everywhere else, so the band rule (lossy families capped at their base) stands on measured rows. The 17:00 clock holds; the cut (coverage table, per-axis table, union-bound arithmetic, harness patch series) likely lands by 14:30 BST. The node lane's gated tip missed its 12:30 clock: the combined wip (the 30-s ring check, the snapshot digest stamp, the vetoed-node status, the reorg-unwind fix on the same commit) sat in build-2's queue from 11:41 BST at normal priority behind a Counter ASIC 4 suite holding a slot since 11:31, found at 12:21 and moved to build-1 at gate priority; the exec suite about 12:25, the named commit on green, the full gate set (build and consensus at gate priority, five suites, both canaries, digest 1b37cb9d unchanged) about 12:50, the fast-time pair about 13:05, inside the 13:30 clock. The coordinator's default revised and taken by the lane and the steward: the second matrix starts on the named commit the minute its sha exists; no sha by 12:50 and the matrix runs on e0644958, the stamp and vetoed status slide to 0.3.26. The pin reads about 13:15 to 13:30 rather than 13:00; the minute about 14:10 holds if the fix rides; reported to main at 12:29. The seed's re-walk read equal to population A at 11:43 BST (0x47983bd9 at 15611, 0x3f53a7b9 at 26247; 26,478 blocks in 7 min 30 s, about 59 a second, RSS 5.49 GB); the fresh node on build-1 executing from genesis since 11:42:34 at about 100 a second at the start, its roots to follow. The lesson for the record: a release gate is dispatched at gate priority or it waits behind research suites; the node lane's wips were not. Main's correction at 12:3x BST on the fleet default: the 10:12 FETCHED count is not a census of state. If the stamp rides the pin, every node re-executes from genesis at the minute and the census is not a gate; if the stamp slides to 0.3.26, the census (block 26294's hash and the 26247 root on every prover) is a gate and the stale nodes re-walk before the minute. The fleet lane silent since 11:31: a one-shot at 12:36 starts a fresh fleet-move lane from the fleet root to take the census, the re-walks, the stagger and the pullers if it has not answered by then; the old lane keeps the hold and the hourly line. The 9070 XT reading goes to the audit lane for its row. Build-2's queued cell landed at 12:24 BST: core GREEN on the fixed tree (177 passed), so the first 0.3.25 matrix is green on every suite on all four boxes. The steward's gate-priority stream for the second matrix written (every suite at gate priority, its own results file), waiting on the node lane's sha with the 12:50 fallback armed; the line by 13:15. The AMD knob closed for the cut before 12:30: the 9070 XT grid's rows in and the efficient point in EFFICIENT_W as 149 W (both floors: clock offset -500 at about 2,920 MHz where ADLX clamps, power limit -30; 149.3 W at 18.96 MH/s, 0.127 MH/W, 24 percent under stock at the same rate); the rate flat over the whole ladder, so the knob is a watts lever only and the knee rule reaches the floor; amd-clock-25's gated tip 1be99aa0 (full gate GREEN 60, suite 298 green) with the shipper as the cut tip, the release section reading measured. The 5090 comparison carries two denominators, both real: 0.43 MH/W at the v4 1,200 MHz lock (133.8 MH/s at 305 W), 0.58 to 0.60 at the 1,300 knee (134.6 at 223 W); the 9070 XT at its floors is 3.5x behind the first and about a fifth of the second; a served row names its point. The Arc default taken at 12:30 BST: no B580 re-read reached the v5 lane, so the pairing line went to the shipper as the FREEZE 1c420786 (0.3.24's, as published) with the kit zip 65b47211 (packs-ca3-v5-20261008T085619Z.zip; its packs, ids and 82b19cbde8557ea5 byte-identical to 1c420786's by the packs test on both trees) and the Intel worker held out; 8f481459 (gate 73 GREEN, suite green, the Intel fix in) stands behind it and becomes the pairing with the Intel kit the minute an equal Arc read lands, with the page's Intel row moved. Nothing else of the v5 lane's in the cut. The shipper at 12:33 BST: (1) the 0.3.25 app tip is 89e83df2 (cbbaa8c4 plus amd-clock-25's gated tip 1be99aa0: the 9070 XT's efficient point 149 W at 18.96 MH/s in the ceiling table, the grid playbook; crate gate GREEN 12:28, 305+35+8, inside the 12:30 app window); the second matrix uses it with the node lane's sha. (2) On the node lane's hint, build-1's Devnet 3 seed and node1-dn3 were found dead since 12:06 and 11:54 BST (logs ending mid-line, no panic, no OOM; the observer and the fresh node lived): the network's seed was down 24 minutes; both restarted at 12:30 on their kept datadirs (the seed resumed its clean re-walk snapshot, node1-dn3 re-walking from genesis). Two reads before the pin: the build-server lane by 12:50 on whether any build-1 run kills igneumd by name (a cleanup that does so reaches the seed at the minute); the node lane by 13:00 on whether the line can die silently under the finality route flood the seed's log shows (a million drops on one peer). (3) The pairing the freeze 1c420786, kit 65b47211, the Intel kit out (PC 2 dark, no Arc read today); the genesis class closed on the fresh node's roots; the pin after the node lane's gate set, the matrix and the census; the minute inside 14:53. The hash lane at 12:4x BST: (1) the Ember search priors on the mirror as ember-tiers-25 1e966170, app suite green (307 + 35 + 8), with the UI lane and the shipper; the cut default stated to the shipper (in by the 13:00 pin or 0.3.26). (2) The v6 packs job on the 5090 (since 12:13): the four packs made on the box or pinned ran PASS unlocked (mx8-genesis 137.65 MH/s at 312.2 W; mx8_sh256x27 137.62 at 464.6; the invention lane's mx8_shl4096x1 135.99 at 428.6; mx8_shl2304x3 135.85 at 483.6; the 1,300 rows follow); the seven exported on the Mac this morning (today's x8 and x16, the two re-weighted, the three dataset sizes) were refused by the worker's seed check in 0 s ("IGNEUM_SEEDW_INIT is not attempt 0 of the epoch seed"): the string-seed export form derives different seed words from the byte-seed form the pinned packs use; re-exported in the byte form (the x8 reproduces the pinned id 73bcbfe8 and seed words exactly; the three sizes too; the x16 pair and the two re-weighted packs on generator 2 differing only in the era, the multiplier or the weight table); kit b and one more PC 1 job of those seven follow the running job's close, about 13:00 to 13:45, rows to the research lane, the invention lane and the coordinator. The invention lane's reading so far: the sound per-load form at class v4's instruction count (shl2304x3, 55,296 shadow ops) costs 483.6 W against sh256x27's 464.6 W unlocked, 19 W more, not under; the one-pass form (shl4096x1, 32,768 ops) 428.6 W; the lock rows decide the per-load candidate's GPU side. The export-form lesson for the record: packs for the worker are exported in the byte-seed form, never the string-seed form. Main's load order at 12:5x BST: lane D's two remaining strata (shape-64-lossy, shape-256) move from build-4's queue (behind the attack pass's pool) to build-3, idle after lane D's strata; build-3 kept fed with lane C's packs and the family census's next corners; nothing new on build-1 (load 142) until the pin is named, its gates at gate priority. Sent to lanes D and C with the 13:05 default. The node lane's two readings at 12:4x BST on the combined tip: (1) the build-1 deaths were the OOM killer (the build-server lane read the kernel ring: the seed at 44.6 GB anon-rss at 12:06:07 BST, node1 the same class at 11:54, two 31 GB attack binaries beside them); what grows is the proof pool's in-memory proof map: since the late-join rule (0.3.17) every proof a node receives is held by hash in memory and never removed (the entries leave the 600-block record window and the on-disk archive drops below the pruning point, the map did not); about 1.2 MB a proof, 14,107 proofs on the observer after a day (17 GB on disk, 13.6 GB RSS), the seed at 128 inpeers took the relays fastest; older than 7bd2940f; the fix (a proof leaves the map and the verdict cache with its record at the window's end unless another live entry names it; carried proofs served from the archive; known-failed test) on the tip under its exec suite at gate priority since 12:35:55. (2) The ring check's known-failed test on node1's shape green (exec 53 of 53 at 12:34:53 before the pruning went in). The named commit (the 30-s ring check, the snapshot digest stamp, the vetoed-node status, the proof-map window, over 7bd2940f's re-announce and keygen and the ceiling switch) follows the exec line about 12:40, inside the 12:50 fallback; the full gate set at gate priority on both boxes, both canaries (digest 1b37cb9d unchanged) and the fast-time pair after it. The fleet's census (12:31 BST): 36 nodes on population A, the network's genesis root 0x7e37a9fb; 21 stale nodes, each with a genesis root of its own, re-walking from 12:35 in thirds; dn3-g1 died a third time at 11:55:47 (the same OOM class on a rented box the likely reading; the fleet's hourly RSS per node with a restart above 32 GB is the guard until every node is on the tip). Lane D on main's order, done 12:36 BST: build-4's two entries cancelled before running; build-3 carries four strata on the fg6 harness (42f2c77f), 8 cores each under class measure: shape256 (3,000) and w4lossybase (3,000) running, shape64lossy (2,000) and w4shape64 (3,000) queued behind them on the 24-core pool; the lossy band at B = 4 across the injecting families is the complete lossy-base stratum (3,000 eras, 0 exhausted, r = 0.595). Build-1's queued attack-f8 rebuild chain cancelled (the point-B live census moves to build-3); what remains there started before the order (four lossy-share strata at +1 to +4 points, 16 cores each, about 900 of 3,000 eras; the point-A live census at 2^24 on 32 cores). The 17:00 cut committed at 2a595e1b with the 24,000-era coverage, its gate re-running. A shared-Mac fault class found at 12:3x to 12:4x BST: the class-v5 lane's shell command ran pkill -f "tools/ci/pre-push.sh" before its own gate, which killed every lane's gate on the Mac: the record's merge gate three times, the invention lane's landing twice (d6955381), the family gate's once (exit 144). The kill-by-name class the 6 October rule bans in scripts (kill-by-name-check.sh), applied by hand on a command line. The word to the lane: kill only your own gate by its pid; gates on the Mac do not share a lock. Reported to main. The research lane's commit 0ab27582 on counter-asic-4 (the mirror, 12:4x BST, ahead of the 15:00 clock; the crate suite green on the committed tree, 116 passed, 0 failed, build-2 12:38, master's new derivation test among them). It carries: (1) chip-model-v3.md section 5.12, the two chips with lane B's figures and marks (the 2 GiB SRAM store on one N2 reticle: 17x at zero shadow, 8x to 30x on the read band, 2.7x at k = 1 and 4.8x at k = 0.5 with the class v4 shadow, 3.7x and 2.0x at the card's whole shadow, USD 400 to 600 of silicon, an N2 project of USD 100 M to 500 M and 18 to 24 months, a break-even cap of about USD 330 M to 1.7 B on the mission lane's model; layer 2 moving its capex, two dies at 4 GiB 15x and four at 8 GiB 13x; the custom HBM4E base die 6.5x to 14x untouched by the four layers; PIM structurally blind, 1.6 percent of reads in-bank at 2 GiB; the M5 Max at 0.78 microjoules the honest denominator, 3.1x the 5090) and 5.11's per-load note in the reopened wording; (2) the merge of master (the sub-version 3 line, the derivation recorder, the re-exported packs) and the per-load bias test's fix (judging only the bits inside each site's window mask; lane C re-reads on this id); (3) the class v6 document through section 9: the lead on the SRAM store, the per-tier schedule table with lane A's checked steps (6 GiB does not fit the 8 GB tier under the 75 percent rule; 5.5 / 8 / 11 GiB drops the tiers in the named order, about a quarter of today's measured consumer cards per step), the measured M5 Max size rows (-12 / -20 / -22 percent of rate at 2 / 4 / 8 GiB, the one card that pays rate for a larger working set), lane D's rings and band, the index fold as a layer-1 rule, the 5070 Ti pair, the x16 mixer at 11.4 ms loaded by the right method (admissible false on the measurement), lanes B, A and C taken in 7a to 7c, and section 9's served-line review with the wording proposed for the 20:00 word. Owed for 20:00: the 5090 size rows (the hash lane's v6 job), lane C's 15:00 re-read, lane D's 17:00 table, the two re-weighted packs' rows; each lands as a row with its label, or its default. Main's word at 12:5x BST on the kill class: the rule "no kill by name on the Mac, pid file only, ad-hoc shell lines included" lands in the agents' standing text with this record landing; the steward makes it a gate check that refuses pattern kills in scripts and logs the sender of every TERM a gate receives. The class-v5 lane's own line: the four pkill lines (12:3x to 12:37) stopped its own superseded gate runs as its tip moved under them; nothing of its uses a name or pattern kill again, its background gate started with its pid recorded and ended by that pid only; its current run (gate 17 on class-v5 79799452, 12:39) runs to its end. The census and the four-item pin taken by main; the clock as the shipper set it. Lane D's interim at 12:5x BST for the 09:00 report, the lossy-share curve at 1,000 to 1,300 eras per point: r rises 0.80, 0.88, 0.92, 0.96 as or, mul and mulhi go +1 to +4 points each; exhaustion appears at +3 (2 of 1,029) and reaches 1.4 percent at +4 (14 of 994); every exhausted era's class v5 last-resort scan passes at its first or second candidate (k = 256 or 257), so the band's edge is between +2 and +3 points of lossy weight and the scan does its job at the corner. Its cut 2a595e1b under the gate, then the mirror landing and the send to the research lane. The attack pass's F8 to 256 seeds landed at 12:37 BST: seeds p66 to p257 (192 new) at 2^24 on the freeze 1c420786 (binary 0f5c98dc, pairing e5a4ac5978462156), the window-model control, build-2 under class measure, validation 0 mismatches (hash_warp agreement on 37,440 warps). 184 of 192 within 1.2x at the top 0.1 percent (mean 1.023); 8 over (p110 1.3527x, p66 1.3403x, p234 1.3156x, p145 1.2750x, p77 1.2664x, p225 1.2457x, p248 1.2188x, p89 1.2065x), each with its hottest item at 263 to 432 reads of 2^31 and the hot-set verdict clear on the windowed control (largest excess X_f/f +0.60). Over all 256: 245 within (95.7 percent), 11 over; the rate at 256 (4.3 percent) is the gate's at 64 (4.7 percent) and the worst fell (1.3527x against p10's 1.5047x). The 6-sigma largest-bucket line flags 57 of 192 (p110 +61.67 sigma): the AP-F8-1 tail mechanism at its rate. Two seeds carry a predicted source, one-one-bit through a load, both passed by (c''') on the frozen tip: p212 (1.1915x, attempt 4, site instr 7, r5, last writer load at 2) and p225 (1.2457x, attempt 0, site instr 37, r5, last writer load at 36), to the hash lane for by-site attribution as the gate's tail was. Verdict PASS at the gate's reading: no card or chip gains a cacheable hot set on any of 256 epochs. The row and f8-uniform.md section (e) on the mirror's attack-pass. Still running: build-4's F9 (six chunks) and F1 (10^6), partials at 17:00. The node lane's named commit inside the 12:50 clock: 42ce0f07 on release-0.3.25-node, both mirrors, 12:39:37 BST, the sha with the steward and the shipper. Content: e0644958 (keygen, the record re-announce, the ceiling switch at 82,800; digest 1b37cb9d) plus four node fixes, nothing consensus: the ring self-check every 30 s over the last 2,000 records with the full scan on a generation change (node1's class, its known-failed test green); the snapshot digest stamp (a snapshot under another object or none refused, the node re-executing from genesis); the vetoed-node status (the count and the last veto on the status RPC and igneum_getNodeInfo, "stateFresh" false while any stands); the proof map's window (a proof leaves memory with its record at the 600-block window's end, the OOM class). Green before the squash on the same tree: exec 54 of 54, the kaspad check. The full gate set at gate priority on both boxes from 12:39:44 (every line by about 12:52), both canaries reading the Devnet 3 digest back at 1b37cb9d, the fast-time pair by about 13:00; the crossing watch at 68,400 on the seed from 12:50; the pin line after the last of those; the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15. The invention lane at 12:5x BST: the hash lane's 5090 rows for the two sound per-load packs reverse the GPU-side sign of rank 1: at class v4's own instruction count the per-load form costs the card 19 W MORE than the whole block unlocked (483.6 against 464.6 W) and 6.6 W more at the 1,300 lock, rate 1.3 percent under, 15 to 20 percent more per shadow instruction (19.7 to 20.8 pJ against 17.2); the dead 16 x 27 export's 13 to 14 W saving does not carry (a 16-instruction loop against a 144- or 256-instruction straight segment). Rank 1 keeps its place by the file's own rule (the chip's project cost about 2x against the card's 2 to 4 percent of watts) with the honest sign: the card pays, not saves. The second cut landed at 4315e992, the third (these rows) under the gate. The drawn-era re-read on 0ab27582 built on build-3 but starved (build-3's 16-core pool under lane D's three 24-core leases since 12:38): the coordinator moved it to build-4 at once through the lease pool under class measure (build-1 closed until the pin is named); the 15:00 numbers from build-4, the box named in the row. The class v5 lane's full gate on class-v5 79799452 (the tip on both mirrors) GREEN, 73 checks in 463 s at 12:47 BST, left to run to its end: 0.3.25's pairing row on the page (the freeze 1c420786, kit 65b47211 with the Intel worker held, the Arc read to 0.3.26 with the second PC dark), master merged through its latest (the 60x file taken whole from master after the merge reordered seven keys and duplicated three, values equal), the generated ledger files matching. Nothing of the lane's pending; the one future item the Arc B580 re-read on kit 65b47211 when the second PC is back, which moves the Intel row and sends the 0.3.26 upgrade line. 42ce0f07 reads every gate green at 12:48:10 BST: build 12:42 rc=0 (igneumd 8e17a60b, /srv/artefacts/0325-42ce0f07/node-lane), pow 19, consensus 134, core 177, miner 29, p2p-flows 38, exec 54, all at gate priority; the Devnet 3 canary set with digest 1b37cb9d unchanged, byte 6, the override refused, the 0.3.24 pin refused on the digest both ways; the testnet canary b2e856ed unchanged. The shipper has the line; the steward's matrix runs on it. Two inputs before the pin: the fast-time SUMMARY on 42ce0f07's artefact (about 13:00) and the 68,400 crossing on build-1's seed (the chain passes it about 12:54, the watch from 12:50). The reorg-unwind fix's 13:30 clock met at 12:48 on the same commit. The attack pass at 12:5x BST, the ends brought in: F1's 10^6 was one 40-thread census on build-4 (35 h); the harness now takes --start (attack-v5-frozen ebdb7d4a, smoke-tested: a 20-program census from index 5 writes rows 5 to 24), so the census is split by index range: build-4 keeps indices 0 to 349,999 (its running census, stopped by pid when its progress line reads 350,000; the flushed census.csv holds the lower range) and build-2 runs 350,000 to 999,999 at 80 threads under class measure (binary 42ee04c7, held since 12:48:40 BST after waiting 362 s for the pool to free on its own, no pre-emption). Both halves end about 23:30 BST. F9's six chunks hold on build-4 (48 cores); when build-2's F1 ends tonight the F9 remainder re-splits onto build-2 by seed range (rows keyed by seed, nothing lost), bringing F9's end from about 17:00 BST tomorrow to about 06:00 BST. Cores held: build-2 80 (F1 upper range), build-4 88 (F9 48, F1 40); build-1 and build-3 untouched. Partials at 17:00. RED, a first, at 12:48 BST: Devnet 3 STALLED AT THE CLASS V5 FLOOR. The seed's virtual DAA read 68,403 at 12:49:11, 12:50:23 and 12:51:09 with one sink (07055360), the last block accepted at DAA 68,399 as class v4 at 12:48:14; nothing at 68,400 or above reached the seed, node1 or the observer, no node logged a PoW rejection: no miner found an epoch-19 block on a chain that ran one a second. The nodes held epoch 19's state (the seed installed the streams for epochs 18 and 19 from its snapshot at 12:30). The cause (the fleet lane, 12:52): every miner's --worker is the hive package's igneum-worker-cuda, which runs generators 2, 3 and 4 only; the class v5 kit's worker (82b19cbde8557ea5, the one every v5 gate ran on) was never on any miner's worker path, only its packs were placed; the prepare of epoch 19 fails and the miner sits at 0 MH/s while the templates flow. The fast-time harness crossed this boundary green four times on pairs, which tests the node and the CPU engine, not the fleet's GPU workers or kits. The fleet places the kit worker on every box now; the 0.3.25 hive package and Windows payload rebuild with the kit's workers by 13:30 (the build-server lane); the Mac Metal worker's generator-5 read with the v5 lane by 13:10. The pin and the minute wait on the chain moving and the rebuilt packages; the 42ce0f07 gate set green, the matrix running, the ceiling cut's publish limit (DAA 75,600) standing still while the chain does. GATE RULE for the next cut (the record's and release-rules'): a cut's packages are smoked by preparing the current epoch's pack on every worker binary they ship, on every platform, against the live object; the packs' presence and the kit's own tests never stand for it. The 0.3.24 move's read-back ("36 of 36 FETCHED on the pin") was a node reading; no reading of a worker preparing class v5 existed before the floor. The research lane at 12:5x BST: section 10 ("the floor") open in the class v6 document (counter-asic-4 after 91117093) with each floor lane's term, what the document holds measured for it, the default at 19:30 and the row owed; two measured rows the floor lanes start from rather than re-derive: the SM-sparse lane from 20.3b (a quarter of the SMs holds 98.2 percent of the class v4 rate at the same draw, 460 against 451 W; 99.8 percent of class v3 at 4 W less; watts minus idle per MH/s never below base; the sparse shapes collapsing at the 1,300 lock; its new work the breakdown of the 99 W an idle SM does not save and whether an occupancy shape at full SM count moves it; the worker variants sp-w and the card-free --list-race check on counter-asic-4); the k lane from 15.1a (the GPU side measured per counted op: ARX 11.3 / 6.2 pJ, mul 13.9 / 8.3, mulhi 39.6 / 21.0, prmt 22.3 / 11.5, lop3 24.1 / 13.0, shfl 55.8 / 29.4, fp32 FMA 9.2 / 5.2, the int8 tile 1.4 to 4.1 per MAC; only the chip side claimed; the mix that maximises k priced against the GPU's own per-family cost, the shuffle 4.9x the add on the card). The thirty-ninth landing on master at 12:54 BST (26a3cbe6): the standing rule in CLAUDE.md. The node lane at 12:5x BST on the stall: the worker's refusal line is "program pack generator 5 is not a generator version this worker runs (2, 3 or 4)", faulting at 0 MH/s from the first epoch-19 template; the kit's class v5 worker was benched on 24 cards this morning and never placed on any miner's --worker path; the nodes read 0 PoW rejections and hand the right template (the CPU id-read from build-1 confirms epoch 19 as class v5). The fleet places the kit worker and its pack on every mining box, w-target first; the chain moves when the first card prepares. The record's lesson: a worker that cannot run the next class must refuse at the pack prepare, loudly, hours before the boundary (the plug, tune, play rule), and no hive tar ships without the class the object names. A second bug read off the stall: the pool admits at the next block's DAA (chain id 4464 past the floor) while eth_chainId answered the executed tip's id (4463 with the tip stalled at 68,399); the fix (eth_chainId and net_version answer the id a transaction sent now must carry, the status carrying both ids, the known-failed test on the stall's shape) a wip under its exec suite at gate priority since 12:54:27, landing as the SECOND commit on release-0.3.25-node over 42ce0f07 (nothing consensus, digest 1b37cb9d unchanged), its full gate set and fast-time pair by about 13:15; that commit the pin's node sha, 42ce0f07 if it reads red. THE CROSSING READS CLEAN. The first class v5 block (epoch 19, epoch seed a75c5624) was accepted on build-1's seed at 12:57:40 BST, 9 minutes 26 seconds after the last class v4 block, the minute the fleet's first kit worker prepared; then 13, 14, 71, 165 and 78 blocks a minute (the backlog clearing, the rate settling), DAA 68,547 at 13:01:37; seven stale-pack attempts refused between 12:59:24 and 13:01:10 (the harness's known-failed shape), none since; no state-wait, catch-up, stale-dataset or digest line on the seed, node1 or the observer; no honest block refused. Devnet 3 runs class v5 at byte 6 as the 0.3.24 object names (the v5 signal share 1,407 bps at the floor; the seed's template at 13:1x: epoch 19, class 5, version 1538, era the genesis, day 20,734; the executor serving epoch 19's stream, 869 records, root 0x1fd55139...4561). The pairing check holds three ways: the kit's igneum-pow (8f481459's tree, the freeze's hash object) names attempt 2, program id 3d375a55029e7e60 for epoch 19; the node lane's 0.3.24 pin miner (igneum-pow 1c420786) read the same id live at 12:56; the DMG's Metal worker on the Mac prepared epoch 19 against the live seed with the same id (869 leaves, 26 MH/s). The stall's two causes, both miner-side, neither in the object: every fleet miner's worker was the hive package's CUDA worker (generators 2, 3 and 4; it refuses a generator-5 pack with a line, the miner at 0 MH/s retrying, loud in the log and the plug-tune-play fault only on the dashboard), the DMG's Metal worker from the freeze's tree the same (the v5 worker path is the v5-kits lane's 5c9ed959, in class-v5 from e208dfea on; the freeze is the hash object, not the hosts); and a miner not told its node's exec RPC port cannot prepare class v5 at all, so every fleet loop needs --exec-rpc. The fix: the kit's workers (zip 65b47211) and --exec-rpc on every box; the hive, Windows and Mac packages from the kit tree (the hive and Windows payload carrying d84b1b6c / be23bc68 and e1bfd582 / 55722527 on the worker path; the Mac side closed on release-0.3.25 44d1815a, proto-metal from class-v5 79799452). The stall's cost: 9.5 minutes of blocks and every prover's share for that span. The standing rules from it (release rules 16 and 17 on ship-docs-0321 cb570365): the kit worker and --exec-rpc on every miner loop before any class boundary; a worker that cannot run the object's next class refuses at the pack prepare, hours ahead; a cut's packages are smoked by preparing the current epoch's pack on every worker binary they ship, on every platform, against the live object; memory against the container's cap. All of it on the class v5 page's section 0 at class-v5 2494f3f8 (both mirrors 12:59, master merged, its full gate running by pid). The second node commit 5f316c21 on release-0.3.25-node (both mirrors 12:56:22 BST) = 42ce0f07 plus the chain-id answer (eth_chainId and net_version return the id the pool admits at, the next block's DAA, 4464 past the floor; the status carrying both ids; the known-failed test on the stall's shape), nothing consensus, digest 1b37cb9d unchanged; EVERY GATE GREEN at 13:04:05 BST (build 12:58 rc=0, igneumd 3812b2a2, /srv/artefacts/0325-5f316c21/node-lane; consensus 134, exec 54, core 177, pow 19, p2p-flows 38, miner 29, all at gate priority; the Devnet 3 canary with digest 1b37cb9d unchanged, byte 6, the 0.3.24 pin refused both ways; the testnet canary b2e856ed unchanged). 5f316c21 IS THE PIN'S NODE SHA. The one input before the pin line: the fast-time SUMMARY on 42ce0f07's artefact (the run waited 796 s for build-1's pool, 88 of 88 leased at or above v5, nothing to pre-empt; running since 12:55:54, v5 from epoch 8 at 13:04:19, the line about 13:10), a run on 5f316c21 after it. The shipper's close: the app tip 9a71e784 (crate 89e83df2), the DMG 43cd8c94 staged, the tarball 1ae1810d, move id m5f31-1; the pin about 13:25 after the SUMMARY, the matrix and the hive; the minute about 14:00 to 14:20 inside 14:53. The TESTNET_PARAMS v5-at-0 re-cut's default moved under the rule by the node lane: it lands through its full gate set on release-0.3.24-node 30 minutes after the seed reads the first ten class v5 blocks accepted clean, so at 13:32 BST unless main says otherwise before then; a red crossing would have meant no re-cut. The audit lane's 9070 XT row on master at f37f497b (12:55 BST, gate green on 33b0ad06), ahead of 13:30: 18.96 MH/s, watts "149.3 with the 0.3.25 knob (195.8 stock)", 0.127 MH per watt, the tuned text with the 24 points' flatness and the date, the source the status row with the job id; the note carries the grid's stock point beside the app's 202 W reading of 7 October, the two single-lever points, and names both 5090 denominators (3.5x behind at the class v4 1,200 MHz lock, 0.43; about a fifth at the 1,300 knee, 0.60); the qualifier drops when the cut serves. With f37f497b: the complete class v4 watts rerun (22 rows), the /income calculator, the /economics page, the governance line, the two served-text corrections with their ledger rows. The build-server lane has it to deploy. The hash lane's kit b on the 5090 (12:49 to 12:58 BST, all PASS; with the research lane and the floor lane): the mixer multiplier x8 against x16 costs the GPU nothing (137.73 against 137.72 MH/s, 320.2 against 320.1 W unlocked; 127.44 against 127.46, 212.0 against 211.7 W at 1,300), so the verifier's 1.86x per doubling is the whole cost of that draw; the shuffle-heavy table on the base program moves 7 W unlocked and nothing at the lock (a 2 percent term); the pinned class v3 program at 2, 4 and 8 GiB costs a tuned 5090 5, 11 and 14 percent of rate at the 1,300 lock (4, 8 and 10 percent per hash) and 3 to 4 percent unlocked, which corrects the layer 2 line: the size term is real at the knee (the page-walk cost the latency-bound regime exposes). Kit c (the multiply-heavy table) running; kit d (both tables inside the shadow block, the row layer 1 needs) exports on build-2 and runs after, about 13:45. W = 8 for the floor lane: the crate's width set is three fixed word widths (1, 4, 16; WIDTH_WORDS, the mix arrays, the emitters for CUDA, OpenCL and Metal, the verifier's fold), so a 32-byte load needs a generator and emitter change before any pack exists (two to three hours of crate work on the readwidth line plus the PC 1 row); the ask to main with its default: say so by 14:00 and the lane starts it on the readwidth branch (a research class, no consensus object); silence means W = 4 pins and the floor lane hears so at 17:30. The F8-256 attribution runs for p212 and p225 on build-3 (the attack-pass crate d08e1e0f built there at 13:01), rows by 16:00. Main's ids for the floor lanes, for the record: SM-sparse af65f8187569666d0, shadow k a3c9601a6d4686fe1, SRAM and dataset floor acecab7195ea66621, honest denominator a4d39e20a0762646d, invention a734c5330f17be3c2; the research lane delivered the two starting rows to each with their 19:30 defaults. Two more master-only deploys from the builder stream, checks ok (38 miners rows, 18 asserted pages, the checkpoint API and the explorer stats API): d28cf8fc at 12:50 BST (the explorer wording c4ca746f, the audit lane's ace5c294 with /economics, the /income calculator and the class v4 watts rows, the DEX lane's 9126e4d6 and 825d19bd) and f37f497b at 13:04 BST (the reference-apps b7f1e0d7 with /oracle's BLS-verified root, the 9070 XT knob row on /miners). No chip text changed beyond the audit lane's own landings. The fortieth landing on master at 13:14 BST (90b180f2). Main's word on W = 8 at 13:1x: start it, research class with no consensus object; the order on the hash lane: the 0.3.25 lock rows and kit b first, then the readwidth generator and emitter, the PC 1 row by 17:30; a miss means W = 4 pins, the floor lane told, the W = 8 row later as a v6 sub-version check. The 13:32 testnet re-cut on its default. A RED THE MOVE ITSELF WOULD TRIGGER, read on build-1 at 13:05 BST by the node lane: a node re-executing from genesis (the fleet's 21 re-walks now; every node at the move under the snapshot stamp rule) has its executor thousands of blocks below the chain, so its pool admits at the executor's next DAA, names the old chain id 4463 below the floor, refuses every relayed transaction signed with 4464 as a state-free fault and disconnects the relayer as misbehaving ("wrong chain id: expected 4463, got Some(4464)" on the seed and node1 from peers at 13:05); for the length of its walk, about 8 minutes, it drops every peer that relays a transaction, and at the move every node would do it to every other: a partition. The fix, a wip under its exec suite at gate priority since 13:08:06: the admission height is the larger of the executor's next DAA and the chain's virtual DAA plus one (eth_chainId, net_version, eth_sendRawTransaction and the relay read it), and a mismatch between the network's own two ids is a refusal, never a strike; the known-failed test is the re-walk's shape. It lands as the line's third commit over 5f316c21 (nothing consensus, digest 1b37cb9d), the full gate set and the fast-time pair on it by about 13:35; the pin waits on it. The second thing in those logs is the stale class, not a bug: the 21 nodes with a divergent execution state compute a divergent class v5 dataset, refuse every honest v5 block as invalid PoW and ban build-1's seed for an hour ("Reject(BlockInvalid)" on the fleet's side), cured by their re-walks in progress; a node that cannot check a v5 header for want of the epoch's state holds off, as designed. The crossing is clean on the honest side; the chain runs. The fast-time crossing on the 0.3.25 pair 42ce0f07 (12:55:54 to 13:08:50 BST) read green on every claim (rung 1 at 13:02:22, v5 at byte 6 from epoch 8 at 13:04:19, 12 of 12 ids equal to the CPU verifier's, the stale node refused, the restart step resynced in 19.1 s with the catch-up done, four sinks equal, 0 PoW rejections on honest nodes); its SUMMARY read FAIL on one harness check: the final epoch's row held one miner's line when the run ended at that epoch's boundary (the id equal to the CLI's); not a node finding; the check now reads the final row by its id (v5-fasttime 130562a2); the clean rerun on the same artefact from 13:1x, SUMMARY about 14 minutes after its lease. Lane D's 17:00 cut LANDED on master at 238100b0 (13:13 BST), gate GREEN (73 checks, 355 s) on 2a595e1b, four hours early; the research lane has the layer-4 line; docs/analysis/class-v6/family-gate.md carries the measured coverage (24,000 drawn eras, per stratum and per axis, the bound arithmetic), the rows, logs, scripts and the harness diff under docs/analysis/class-v6/logs/. Build-3: w4lossybase done (3,000, 0 exhausted), shape256 1,910 of 3,000, shape64lossy 1,895 of 2,000, w4shape64 queued, then the point-B live census on the family attack-f8 build (74784428); build-1 the four lossy-share strata near done and the point-A live census. The class v5 lane's full gate on class-v5 2494f3f8 (the crossing row, master merged) GREEN, 73 checks in 407 s at 13:06, run to its end by pid, nothing killed. The third node commit inside the shipper's 13:20 clock: d5b68fae on release-0.3.25-node, both mirrors, 13:14:12 BST = 5f316c21 plus the admission fix (a transaction admitted at the larger of the executor's next DAA and the chain's virtual DAA plus one on the relay, eth_chainId, net_version, eth_sendRawTransaction and the status; a mismatch between the network's own two chain ids a refusal, never a strike; the known-failed test on the re-walk's shape), nothing consensus, digest 1b37cb9d unchanged, pairing 1c420786; exec 54 of 54 and the kaspad check green on the same tree before the squash. The full gate set at gate priority from 13:14:19, every line by about 13:26; the fast-time pair asked on it; the 42ce0f07 rerun's SUMMARY (about 13:24) the gate's record on the same object. The pin's node sha d5b68fae if green, else 5f316c21. The steward's 0.3.25 matrix at 13:17 BST: node 5f316c21 with app tree 89e83df2 GREEN on all seven suites on build-2, build-3 and build-4 (no RED); 42ce0f07 complete green on the same three; build-1 out; at 13:21 the third sha d5b68fae core and exec GREEN on the three boxes, six of six: the pre-pin suite read closed. d5b68fae reads every gate green at 13:22:43 BST (build 13:15 rc=0, igneumd b0e7b8b5, /srv/artefacts/0325-d5b68fae/node-lane; p2p-flows 38, pow 19, consensus 134, exec 54, core 177, miner 29 at gate priority; the Devnet 3 canary digest 1b37cb9d unchanged, byte 6, the 0.3.24 pin refused both ways; the testnet canary b2e856ed unchanged): THE PIN'S NODE SHA IS d5b68fae. The fast-time SUMMARY PASS (cross-0325-42ce0f07-2) at 13:22:57 BST on the 0.3.25 pair 42ce0f07 (13:10:07 to 13:22:57 on build-1 under class v5: rung 1 at 13:16:33, v5 at byte 6 from epoch 8 at 13:18:43, the stale node refused, the restart step resynced in 11 s with the catch-up done, four sinks equal, 0 PoW rejections on honest nodes); the d5b68fae pair running side by side since 13:16:13 on its own cores and port base, SUMMARY about 13:30, the last input before the pin line. The reading behind the fleet's partition line at 13:17 BST (hub-1 at one sink, dn2-1 alone on its own branch, w-poison a third, dn3-g2 and dn3-q03 stuck at DAA 68,403 refusing every v5 block): epoch 19's class v5 dataset derives from the execution state after the epoch's reference block, the last chain block below the cut 19 x 3,600 - 600 = DAA 67,800: chain block 28,462, hash a75c5624 (the epoch seed), state root 0x1fd551393d (build-1's seed, node1-dn3 and the fresh node agree; the kit's stream names the same root). Any divergence of state OR numbering between 26,294 and 28,462 puts a node in a cluster that refuses the other clusters' proof of work and bans their relayers for an hour; root-equal at 26,247 was not the gate. The census now reads hash and root at 28,462 on every box (epoch 20's height moves to the last block at DAA at most 71,399); every cluster but the one on a75c5624 / 0x1fd55139 re-walks; build-1's observer node, the explorer's only source, is one of the drifted (its 28,462 another hash at DAA 67,787: the orphan-append class during its 11:22 re-walk, so the explorer's numbers are off by a few; the shipper has it). The cure is the move itself: every node restarted on the pin's binary re-executes from genesis under the snapshot stamp with the ring self-check running and lands on the one state; the gate on the minute is the fleet's census at 28,462 after the re-walks (31 boxes on the one state at 13:19:44, the rest the numbering class the move cures), with an unban of every held address per box once its root reads equal, since bans persist on disk across restarts; a box whose root there differs after a re-walk on the pin's binary is a new class and a stop. Lane D's measured correction at 13:2x BST for the full report: the lossy-corner exhaustion is a shape-256 interaction, not corner-wide: at the lossy cap the per-candidate rejection is 0.877 at shape 64 x 108 (0 of 2,000 and 0 of 1,000 eras exhaust), 0.923 at 128 x 54 (1 of 1,010), 0.980 at 256 x 27 (36 of 990, 3.6 percent; 24 of 670 at width 4); at r = 0.98 the independent-attempt figure is 0.98^256 = 0.6 percent, so the per-era correlation is about 6x, not the 1,000x the mixed-shape average suggested; the band rule stands either way (lossy families never raised), and the cheapest shape for the draw is also the fastest on the cards. The hash lane's attribution: run 2 (the attack-pass branch's own crate) reproduces p225's 1.2452x but not p212's (1.57x against the gate's 1.19x, a different draw, the crate differing from 1c420786); run 3 on the 1c420786 crate is the authoritative one, running. The W = 8 pow suite on build-2; the three state-term packs (w4, w32, w64 on +sh256x27+state, the node1 state file, --era-widths 4/8/16) export on its green; the read-width kit (those three, the v5-genesis pack, the two 5 October packs, which are string-seed class v2 packs the worker accepted on 5 October, no re-export) runs on PC 1 after kit d; the L2::64B hint variant is not in the worker exes, so it is lane 5's kernel line, nothing to build. STANDING RULE from the founder relayed by main at 13:2x BST, applied to every lane the coordinator runs and every default clock: work as fast as possible; anything doable in 30 minutes to 2 hours gets a clock inside that window, never a target hours out; fan work out (one pod per point, one box per variant) rather than queue it. The floor close is 15:45 BST. The coordinator's re-read of the 16:00, 16:30, 17:00 and 19:30 lines: the F8 attribution rows 14:00 (run 3 running, three minutes a census); lane C's drawn-era numbers 14:00 (an 80-s census on build-4) and its cut 15:00; the class v6 per-tier cost rows and layer 4's tests 14:30 (kit d about 13:45); the W = 8 PC 1 row 15:30 (the crate work fanned: the suite on build-2, the exports on build-2's slot, PC 1 the moment kit d closes); the floor lanes' rows 15:30 for the 15:45 close; the synthesis and the served-line review table 16:30; lane D's full report 16:30 with every stratum fanned across build-2's and build-4's free cores rather than queued on build-3; the DEX lane's swap UI 15:00 and the Sepolia verifier 16:00; the reference apps already served (b7f1e0d7 at 13:04). Main's word at 13:2x BST to every lane: while GitHub is suspended, landings go to the box mirror's master through the gate, never to Forgejo master, which is a rewritten copy replaced at cut-over by the box mirror's final tip; pushing a branch to Forgejo for safekeeping is fine, landing there is not. Relayed to every lane with the pulled clocks. The SRAM and dataset floor lane's row is complete at 13:18 BST, two hours inside its pulled 15:30 clock: the full row at 7bc9de4b and the clock references at 8e9588de on the box mirror's branch class-v6-floor-sram (safekeeping, no master landing), gate green on every push, all arithmetic on build-3; docs/analysis/class-v6/floor/sram-and-floor.md. What the 15:45 close carries: the capex wall on the corrected project floor (no chip project below about USD 23 M a year of miner revenue, IGN 0.03, USD 62 K a day; every DRAM-board project at a third of the network above about USD 340 M a year, IGN 0.44, USD 0.93 M a day, where the SRAM project also starts); the read width as the only wire lever on the SRAM die (66x at the hash's 4-byte width at zero shadow, 44x at W = 4, 31x at W = 8, 19x at W = 16 if the 5090 passes the PC 1 job, 36x at the measured w64 row); the shadowed die at 6x to 10x at the honest cards' whole latency shadow on the k lane's synthesised core, kept beside the k lane's sequencer-core row as the floor-k worst case, never under 2x by any shadow; the floor as a ticket lever (5.5 / 8.5 / 11.5 GiB = 3, 5, 6 reticles, USD 1,500 / 2,500 / 3,000; USD 5,000 per store is 20 GiB and retires every card under 32 GB; the 5090 pays 4 / 8 / 10 percent per hash at its knee and the M5 Max 12 / 20 / 22 percent of rate at 2 / 4 / 8 GiB, both measured); the four other candidates (per-era and per-block re-fill, straddling atoms, a second hot table) dead with numbers. Amendments after the close, each labelled with its time: the W = 8 or W = 16 PC 1 row (the hash lane), the k lane's shuffle row and its re-fold, the Apple rate curve past 8 GiB. The DEX lane closed with every clock met before the pull, all on the box mirror's master through the gate: the AMM live on Devnet 3 at 12:0x BST; the swap UI serving at igneum.network/swap since 11:36 with the Igneum Wallet bridge live from the 12:50 deploy; the Sepolia certificate verifier live at 13:3x (0xAf74f3F512081291D663Bb1d6b6d37E99e37D744, suite 10 of 10 on build-3, Devnet 3 checkpoint 2127 recorded final and one Devnet 3 balance proven on it); the one named gap: no on-chain link from checkpoint to state root yet (docs/bridge/light-client-bridge.md); final master 825d19bd. The forty-first landing on master at 13:35 BST (937cc82ae); during its branch push the hook "died of signal 15" once more (the merge's own gate ran green and landed), so a kill by name on the Mac still reached a gate at 13:3x: the steward's TERM-sender log is the read. STOP ON THE PIN d5b68fae at 13:29 BST, the fast-time pair: SUMMARY FAIL (cross-0325-d5b68fae), the failing check v5_ids_equal_the_cli_v5_id, a node finding: on epoch 9's attempt-3 seed ec0a8cf9 the d5b68fae miner and nodes drew program id 65b57e3b847d362e (its nodes accepting 4 of 4 on it) while the freeze CLI 1c420786 and the ab6f980b CLI both draw ebf64b32e2d84c5b, state or no state; the three other v5 epochs agree with the CLI. A node on the freeze's igneum-pow would refuse that epoch's blocks: a split on the first divergent seed, a chain split class. The 42ce0f07 and 39f127a1 PASSes met no such seed, so they do not clear it. The cause from the box's build log: the d5b68fae, 42ce0f07 and 5b673577 pairs were built "pairs_with": "igneum 05b21835 (detached) with uncommitted igneum-pow changes", not against the freeze 1c420786 (39f127a1 and c8f9b383 were, against ca3-v4-node commits 4c24903e and 0e4ec18a); every 0.3.25 node binary embeds "igneum-pow-v5/src", not the freeze's crate; rule 7's pairing broken in the node lane's build path. The orders: the node lane folds the freeze pairing (a clean rebuild from the freeze's exact igneum-pow, the build row's pairs_with read before any lease) and the ceiling re-cut to 90,000 into one commit (sha by 14:05, the gates and a new digest by 14:20, the SUMMARY with the seed in the set by 14:35); the build-server and fleet lanes read the live 0.3.24 miners' pairing path by 14:00 (if the live network carries the same divergence, the move is its cure before the first attempt-3 seed; 5b673577 is the live pin); the artefacts rebuild on the new sha; the pin about 14:35, the minute about 14:55 to 15:10 BST. The coordinator's order to the v5 lane: the pairing read-back on the rebuilt pair by 14:30 (the freeze CLI against the new sha's miner on ec0a8cf9 and the three other v5 epochs, id for id, and the live miner's path the same way). The record's rule for the pairing gate: the fast-time set carries an attempt-3 seed on every run (the epoch seeds of a run are its block hashes, so the divergent seed cannot be forced; the pairing row is the check that reads first); a pair's build row names its igneum-pow commit, and "uncommitted changes" in pairs_with is a refusal before any lease. Lane D's fan-out at 13:4x BST, one stratum per lease, class measure (every box's pool read 0 free at submission, each waiting in the measure class ahead of adv work): build-2 w1band (width 1 under the band, 3,000 eras, the fg7 harness with the refused-ratio column) at 16 cores, and the mixer verifier rows mx4m4g, mx4m8g, mx4m16g with the 256 x 27 shadow, one core each (the x16 row); build-4 w4shape64 (3,000) at 16 cores; build-3 the point-B live census (64 seeds at 2^24, shape 64 x 108 with a band era's weights) at 24 of 64 seeds PASS, and w4band (width 4 under the band, fg7) at 8 cores, 179 of 3,000; shape256 (3,000) and shape64lossy (2,000) COMPLETE; build-1 untouched (the point-A live census at 31 of 64 PASS, no test fired; the four lossy-share strata complete at 3,000 each); build-3's queued copies killed and their partial rows marked PARTIAL. The full report by 16:30 on the mirror's master through the gate; what has not finished by 16:00 goes in as a partial with its count. The corrected line for main: at the lossy cap r = 0.877 at shape 64 x 108 (0 of 3,000 across the strata), 0.923 at 128 x 54 (1 of 2,000), 0.980 at 256 x 27 (3.3 to 3.6 percent of eras in three strata). The hash lane's clocks at 13:4x BST: p225 reproduces on the 1c420786 crate (1.2452x against the gate's 1.2457x, by-site rows in hand, the close by 14:00); p212 does not: the tool at d08e1e0f over the 1c420786 crate draws a program at 1.5715x with a hot set ("site instr 5, r7, one-one-bit, last writer add at 4"), not the gate's 1.1915x attempt-4 program, because the gate ran a chain path (class v5 with the dn3 state) the pushed tool has no flag for; the attack-pass lane's exact command asked by 13:50, default: p212 reported as unreproduced on the pushed tool, labelled so. Kit d: the first two exports hung on a build-2 slot (a stale lock of the lane's own run, cleared); take 3 direct and bounded, packs about 13:45; PC 1 held by floor lane 1's two jobs, so kit d's job starts the minute the card frees and closes 8 minutes later (rows by 14:00 only if PC 1 frees by 13:50, else PC 1's free minute plus 10, inside 15:30; past 15:30 the microbench arithmetic stands). The per-tier cost rows and layer 4's tests delivered at 12:0x (scratch v4/ca4-v6-cost-rows.md), the kit b and c numbers folded in at 14:15. W = 8: the suite on build-2 (restarted 13:23 after a slot wait); the three state-term exports follow it on the same box; the PC 1 read-width job after kit d; the 15:30 row holds if the suite is green by 14:00 and PC 1 frees by 14:30, else W = 4 pins. The explorer lane's correction at 13:4x BST: the explorer's source is no longer the drifted observer: the build-server lane re-pointed the indexer unit, the observer and the public RPC at node1-dn3 (EVM 26870) at 13:25, and the three indexer tables were wiped and refilled from node1-dn3 from chain block 0 at 13:27 (about 3 min); balances, receipts and accounts are node1-dn3's, the DAG tables the observer process's reading of node1-dn3 since 13:25. The notice landing by 14:00: the header names node1-dn3 as the source since 13:25 BST, the observer drifted at DAA 67,787 and re-executes from genesis, a block list read before 13:27 may differ by a few blocks until the move; the same line on /block and /tx. eth_chainId on node1-dn3 answers 4464 since the floor, so the explorer's chain id is read from the node; every page printing 4463 as a fixed string (/build, /swap, /metamask, the nav's title) is one off, told to the build-server lane at 13:28. The attack pass's split under the fan-out rule, running from 13:30 BST, every lease class measure: F9 (900,000 seeds left on 1c420786) as twelve chunks: build-4 keeps the lower 85,000 of each of its six 150,000-seed ranges, restarted from each chunk's lowest missing seed (rows keyed by seed, a merge dedupes), six leases of 8 cores; build-2 takes the upper 65,000 of each range, six leases of 6 cores. F1 (10^6 class v5 programs): build-4 keeps indices 0 to 349,999 at 40 threads (at 76,000 at 13:19; stopped by pid at the 350,000 line), build-2 393,662 to 999,999 at 52 threads (its first 47,000 rows from 350,000 kept, merged by idx at the end). Cores held at 13:36: build-4 72 (F1 40, four F9 chunks of 8; two chunks waiting on lane D's 16-core w4shape64 lease there), build-2 24 (four F9 chunks of 6; F1's 52 and two chunks waiting): build-2 contested (lane D's w1band 16, the invention lane's per-load acceptance census on 0ab27582 48, the hash lane's attribution at class adv, the hash lane's igneum-pow suite at class release for 88 cores, which pre-empts every measure lease there when it starts; the class order decides). Ends at the measured rates if every lease holds: F9 build-4 halves about 04:45 BST, build-2 halves about 07:00; F1 build-4 range about 23:20, build-2 range about 05:40; the build-2 ends slip by their waits. The 15:30 reading carries the counts and re-stated ends. THE EXPOSURE READ at 13:50 BST (the node lane's fingerprints, the shipper's correction): THE LIVE NETWORK IS ON THE FREEZE. The igneum-pow tree each binary linked is the untracked igneum-pow-v5 copy beside its release worktree (the .cargo/config.toml paths override); every copy fingerprinted against git archive 1c420786 igneum-pow by two methods (the node lane's: find src -name '*.rs' | sort | xargs sha256sum | sha256sum; the build-server lane's: find . -name '*.rs' | sort | xargs cat | sha256sum | cut -c1-12): the freeze reads cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 and 29106189ca1e; the 0.3.24 line's worktree (vendor/igneum-node-0321, where 5b673577 and every 0.3.24 pin was built, the gate pair a3b1a2c9/cfa9f5ca, build-1's seed, node1 and the observer) reads the same on the Mac and both boxes; the fleet's shipped pairs the same (29106189ca1e); the kit workers on the freeze (the freeze CLI built at exactly 1c420786 on build-1, binary sha256 7ba781db, names Devnet 3's epoch 19 as attempt 2, program id 3d375a55029e7e60, equal to the 0.3.24 miner's live read). So no live node or worker diverges, no attempt-3 seed can part them, epochs 20, 21 and 22 are safe, no hub-side holding action; the shipper's 13:45 line to main withdrawn and corrected. What diverged: the 0.3.25 line's worktree (vendor/igneum-node-v5) carried a pre-freeze copy (fingerprint e01ea128fab1: accept.rs without the (c''') per-site distinct-index floor, MIN_DISTINCT_RATIO_V5 0.995 and its HotItemSite refusal; generator.rs and memhard.rs older); every 0.3.25 gate artefact c6629572 through d5b68fae was built on it, none shipped; on an attempt-3 seed it draws attempt 2's id where the freeze goes to attempt 3, the fast-time FAIL; replaced by the freeze's tree on the Mac and both boxes at 13:34 (fingerprints equal). The builds.jsonl pairs_with rows name the parent repo's HEAD, not the override copy, so they never said which tree was linked; the fingerprint is the only reading. The predictability: an epoch's attempt and program id are a deterministic function of its epoch seed, fixed 600 DAA (ten minutes) before the epoch starts, so any two trees compare ahead on every seed by both CLIs; across the freeze and the pre-freeze tree the hash lane's census puts the share of seeds that differ at 2.4 percent (112 of 4,600), a per-epoch roll that only matters where a pre-freeze binary is live, and none is. The boundaries at 1.0 DAA/s from the 13:01:37 read: epoch 20 at DAA 72,000 about 13:59 BST (seed fixed 13:49), epoch 21 at 75,600 about 14:59, epoch 22 at 79,200 about 15:59. RULE 19 and the rebuilt sha inside the shipper's 14:05 clock: 6ccaf9e9 on release-0.3.25-node, both mirrors, 13:41:28 BST = d5b68fae plus rule 19's build-time half (consensus/pow/build.rs fingerprints the linked igneum-pow tree by the shell's method and refuses the build unless it equals packaging/pow-freeze.txt, "cbc5bd0a… 1c420786 class-v5-freeze 2026-10-07", unless IGNEUM_POW_FREEZE_CHECK=0; IGNEUM_POW_FINGERPRINT in every binary's strings, on igneumd's start lines and igneum-miner's engine line; the handshake field on the next commit with its own gate) and the Devnet 3 ceiling re-cut to 90,000 (the publish limit DAA 82,800, about 16:53 BST; the digest moves, named by the canary). The wip's check, pow and core suites read "igneum-pow fingerprint cbc5bd0aa10585c8 (the freeze)" at 13:40. The full gate set at gate priority from 13:41:35 (the build on build-1 with the fingerprint strings read back from both binaries, six suites on build-2, both canary sets), every line by about 13:55; rule 19's known-failed case on build-2 beside it (the pre-freeze copy under the override must fail the build); the fast-time lane's watcher fires on the artefact (about 13:45), reads the fingerprint string before its lease, its SUMMARY with the attempt-3 seed about 14:05; the v5 lane's flip case (the harness taking POW_BIN, the freeze CLI, beside FORK_BIN) reads every v5 epoch's id on the pair against the freeze CLI, 13 minutes a case, within 15 minutes of the sha. The testnet v5-at-0 re-cut landed by its default at 13:32 as 3ffcf83b on release-0.3.24-node (its pairing the freeze), its gate set from 13:40:39, its digest from its canary. The pin line follows 6ccaf9e9's last gate and the SUMMARY. The v5 page's section 0 carries the STOP and the pairing rule's new line at 3b894a4d. The counter-asic-4 documents landed on the box mirror's master at 13:35 BST as 868fea52 (full gate GREEN 73, the stamp on c21f1f38): docs/analysis/counter-asic-4-research.md, docs/design/class-v6-rotating-family.md (the branch's text at 08641162), docs/analysis/chip-model-v3.md (5.12 and the capex correction), tools/ci/export-exclude.txt (+4); igneum-pow/src, igneum-pow/tests and proto-cuda stay on counter-asic-4; no served page changed. The research-landing lane's next: floor-sram (8e9588de) about 13:55 from the Mac on its green stamp (the full gate RED 5 of 73 on build-3, all box-environment classes, the steward told as owner: the gate is the Mac-side script that reaches the boxes from inside), floor-k with tools/chip-model/rtl about 15:45, floor-sm documents by 15:30, the denominator and invention lanes on their words. The 6a5fa763 deploy at 13:42 BST (the explorer's source notice and chain id from the node, b092fa17; /swap reading eth_chainId at load, 46eb9e4b; /metamask on 0x1170 and the public RPC, the nav pill, /faucet and /build on 4464 with the floor dated): Devnet 3's eth_chainId moved from 4463 to 4464 at the floor; checks ok, 19 asserted pages. Lane C's 14:00 numbers: the no-era half in hand on 0ab27582 (the sound form 0.927, 234 of 256, unchanged on the fixed instrument; the control sh256x27 now reads sub-version 3's own 0.682 because the merge brought master's (a') pass to that spelling, so the two sit on one instrument); the era sweep on build-2 on the first free cores; the 15:00 cut after it. The attack pass at 13:46 BST: build-4's F1 lower range stopped by its pid file (83,000 distinct rows kept from indices 0 to 349,999) and restarted at 8 threads from its lowest missing index 78,082 (the 4,900 interleaved rows above it redone and deduped by idx at the merge), freeing 32 cores for the census lane; at 15:30 the shard restarts at 40 threads the same way; its end moves from about 23:20 to about 00:15 BST. A print-only move of the sha at 13:45 BST: c9ad753a on release-0.3.25-node, both mirrors = 6ccaf9e9 plus igneum-miner embedding the full IGNEUM_POW_FINGERPRINT=<64 hex> string on its engine line (igneumd carried it; the miner's binary had only the sixteen-character start-line form, so the pair's read-back on both binaries failed on the miner); no code path, object or digest change. The Devnet 3 digest on the pin: 2066aa57505e5ecbd585d061364abb0032d5b5b29cc41c54f4b38cb81c2ba6eb (the ceiling at 90,000; the publish limit DAA 82,800, about 16:53 BST); the fingerprint cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 (the freeze); the 0.3.24 pin refused both ways on its canary. Its full gate set at gate priority from 13:45:59 (every line by about 14:00, both binaries' strings read back in the build log); 6ccaf9e9's own gate set and rule 19's known-failed self-test by about 13:55; the fast-time SUMMARY on 6ccaf9e9 (the same node code and object) about 13:59 stands as the gate's record; the v5 lane's flip case on the pair follows; the pin line after the last of those. The forty-second landing on master at 13:54 BST (c340a9d4a). The shipper's pin candidate: c9ad753a on release-0.3.25-node (d5b68fae plus rule 19's build fingerprint against the freeze, the ceiling re-cut to 90,000, the miner's full fingerprint line; digest 2066aa57; the publish limit DAA 82,800 about 16:53 BST; the fingerprint cbc5bd0aa10585c8 in both binaries' strings); the app tip b5be4edf (crate 89e83df2); the gate set on c9ad753a by about 14:00; the fast-time SUMMARY on 6ccaf9e9 (the same node code and object) about 13:59; the matrix cells on 6ccaf9e9 stand; the v5 lane's read-back on the 6ccaf9e9 pair stands for c9ad753a; the fleet's binary the build-server lane's seed pair on c9ad753a (the freeze's crate, 29106189ca1e); move id m9ad7-1; the pin about 14:35, the minute about 14:55 to 15:10. PC 1's queue at 13:5x BST: floor lane 1's two jobs (floor-pc1-build-2 "build patched sp1-gpu-server", floor-pc1-restore) hold the card since 13:06; queued behind them, published and signed: kit d's fetch and run (9 minutes) then the read-width run (W = 4, 8 and 16 under the class v5 state term, each its own draw on generator 5 with the era and the node1 state, plus the v5-genesis reference and the 5 October w4 and w64; the W = 8 pack exported at 13:48 on the w8-v5 branch, efb68fce on the mirror, suite green; about 20 minutes). The coordinator's order: floor lane 1 names its end minute by 14:10; an end past 14:30 means its job yields the card at 14:30 (pid file, state restored first), kit d and the read-width run take 30 minutes, its job resumes after; so kit d's rows and the W = 8 row by 15:00 at the latest, inside the 15:30 close. The F8-256 attribution rows at 14:00 BST. p225 (the gate's 1.2457x): reproduced on build-3 with the attack-f8 tool at d08e1e0f over the pow crate at 1c420786 exactly, 1.2452x over the window model at 2^24 nonces, the hot-set verdict clear on both controls, the hottest item 0xb7e000 at 332 reads with no saturated or lossy source. By site: the excess sits at site 4 (instr 23, source r7, window 2^23 items, offset 1, last base writer mad at 21), 1.30 percent of its reads into the top 0.1 percent of items against 0.103 flat (12.6x), with site 9 (instr 37, r5, window 2^22, offset 2, last writer load at 36; the gate's predicted one-one-bit source) second at 0.38 percent (3.7x); every other site at its flat share. Both sites read full index entropy (15 of 15 and 14 of 14 bits) and a largest 256-item bucket at its window expectation, so unlike the morning's tail (a bucket concentration) p225's residue is a value-level concentration on specific items from a mad-written index, the class the gate's one-one-bit prediction names, carried mainly by the mad site and a quarter by the load site it predicted. p212 (the gate's 1.1915x, attempt 4): not reproduced; the pushed tool has no class, state or day flag, so its default path draws a different program for seed 212 (1.5715x with a hot set, the string-seed class v4 draw); the run on the gate's own line (its binary, day 20733, class v5, the dn3 state) on build-2 never started (0 of 12 cores free 13:29 to 13:54 with a higher class ahead; build-1 closed); the attack-pass lane runs p212 with --diag 1 on its own harness when its lease frees; default, p212 stays "predicted source only" in the record. No consensus object moves. THE PIN IS NAMED AT 14:08 BST: release-0.3.25-node = c9ad753a (the 0.3.24 pin 5b673577 plus igneum-miner keygen, the proof-record re-announce, the proving-fee ceiling switch at DAA 90,000 in the Devnet 3 object, the ring self-check every 30 s, the snapshot digest stamp, the vetoed-node status, the proof map's window, eth_chainId and the admission at the chain's height with the network's other id a refusal, rule 19's fingerprint, the testnet re-cut beside it); pairing the class v5 freeze 1c420786, fingerprint cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 read back in both binaries; Devnet 3 digest 2066aa57505e5ecbd585d061364abb0032d5b5b29cc41c54f4b38cb81c2ba6eb; the app tip b5be4edf. Every gate green at 14:01:14 BST (build 13:47 rc=0, igneumd 68526b25, igneum-miner d4f4c98d, /srv/artefacts/0325-c9ad753a/node-lane; miner 29, core 177, exec 54, pow 19, consensus 134, p2p-flows 38 at gate priority; the Devnet 3 canary with the digest, byte 6, override refused, the 0.3.24 pin refused both ways; the testnet canary b2e856ed). On the same node code and object (6ccaf9e9): every gate green at 14:00:56; the fast-time SUMMARY PASS (cross-0325-6ccaf9e9) at 13:57:35 with the pairing read before the lease as the freeze fingerprint on both binaries (13:44:45 to 13:57:35 on build-1: rung 1 at 13:51:10, class v5 by signal at byte 6 from epoch 8 at 13:53:28, 12 of 12 ids equal to the freeze CLI's, the stale node 73 of 73 refused, the restart step resynced in 10 s with the catch-up done after 5 s and nothing of its own mined during it, four sinks equal at 662, 0 PoW rejections and 0 submit timeouts); the v5 lane's read-back PASS id for id on epochs 8 to 10 (13a54a0dd793ca79 attempt 2, d35cd0e9cb186d00 attempt 1, 6104176723170d72 attempt 2, miners 3 of 3 against the freeze CLI at exactly 1c420786); the matrix green on build-3 (build-4's consensus cell unreadable under load 510, the steward's clean run once the load is under 96, its line by 14:25). The FAIL seed re-read: on ec0a8cf9 with the FAIL run's era, day and epoch-9 stream, igneum-pow at exactly 1c420786 draws attempt 3, program id 1f1cf82877f46ee6 (8f481459 the same), so NEITHER id in the FAIL was the freeze's ("cli v5 ebf64b32" came from the release worktree's pre-freeze copy, the pin miner's 65b57e3b from igneum-pow-v5/src); the fingerprint pairing is the gate that catches both; the miner's side of that seed cannot be re-read offline (igneum-miner reads ids from a node's template only), so the pin rests on the fingerprint equality and the record says the attempt-3 seed's miner id was not re-read. The ceiling lands at 90,000 (epoch 25) about 18:53 BST, the publish limit 82,800 about 16:53. The re-execution reading: 27,000 chain blocks in about 8 minutes, RSS peak 12.6 GB on IBD plus walk. The fleet fetches m9ad7-1; THE MINUTE = the last FETCHED plus ten, about 14:30 to 14:40 BST; the Mac and HiveOS entries at it; Windows on PC 2's return; the card after the Windows entry. The minute's gate on the fleet's side: the census at 28,462 (a75c5624 / 0x1fd55139) after the re-walks, the unban per box once equal, the first checkpoint lock after it. The attempt-3 rule's shape: the miner's half of a seeded read did not exist; today it is the v5 lane's kaspa-pow program-id binary on its fork branch (class-v5-node 22920380, the template prepare's own path); igneum-miner program-id with the same flags and output line is the first item on the next node line, after which the harness points at the miner. The testnet v5-at-0 re-cut, landed by the default and amended once for its pinned digest constant: 0d05e795 on release-0.3.24-node, every gate green at 14:03:47 (pow 19, exec 47, miner 28, consensus 134, p2p-flows 38, core 175; the testnet canary with digest 1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f, byte 6 from genesis, the old-object seeds refused; the Devnet 3 canary on that line cc902690 unchanged); the rows with the testnet lane, with the note that the go seeds should run the 0.3.25 pin's node code with that object (one merge commit onto c9ad753a and its gates after the move's read-backs). Rule 19's known-failed self-test waits on build-2's pool cores (it pre-empted the attack pass's F1 upper range at 14:03 by the class order, 48 cores, 2,023 s in, 4,000 fresh rows kept; re-queued from index 397,292 holding 52 cores; cost about 25 core-hours, the build-2 F1 end about 06:30 BST). The attack pass's p212 run alone on the gate's exact line with --diag 1 --by-site (build-4, 8 threads, 13:56 to 14:01; binary 0f5c98dc, day 20733, class v5, the dn3 state): ratio reproduced 1.1917x (the gate's 1.1915x); hot-set verdict clear; 6-sigma buckets64 flagged at +91 sigma. The excess is one site: site 9 (instr 35, src r6, k_off 2 offset 0, window 2^22) carries 1.789 percent of its reads into the top 0.1 percent, 16.4x its flat share, index entropy 13.981 of 14 bits, the largest 256-item bucket 1.75x the window expectation, saturated source 0; the eight hot positions are site 9 in iterations 0 to 7; every other site at full entropy and its bucket at expectation; the predicted-source site (site 1, instr 7, r5, one-one-bit through a load at 2) reads 0.237 percent, the ordinary 2x of a 2^23 window, so the prediction is not the excess; the hottest items (0x000010 at 296 reads, 0x00000d, 0x00000e, 0x3c001f, 0x18001a) low addresses near the window base. Verdict: p212 is the AP-F8-1 tail class (a per-site bucket concentration at one narrow-window site, 0.019 bits short), not a lossy source (the log at /srv/builds/igneum-wt-attack-v5/p212-diag/p212.log on build-4). The hash lane's reading of both: p212 the bucket class, p225 the value-level class the one-one-bit prediction names; in both the predicted-source line points at the wrong site, so the prediction stays a hint and the by-site histogram is the attribution. The consequence for class v6's layer 4 (to the research lane): the per-site bucket bound at about 2x that would refuse the morning's four refuses neither of these (1.75x and none); the value-level test catches p225; a bucket bound near 1.5x would take p212 at a clean-seed cost nearer 3 to 6 percent. The AP-F8-1 ledger paragraph amended with it on the hash lane's next gate run (ordered). The research-landing lane's landings: floor-sram documents on master as de3d32af (13:55 BST; the lane's text at 8e9588de; full gate GREEN 73, the light gate on the merge; the gate pid rule kept) and floor-invention documents as d28a7656 (14:03; the lane's text at 033ff8d8; full gate GREEN 73): docs/analysis/class-v6/floor/sram-and-floor.md and invention.md; waiting on floor-sm (15:30), floor-k (15:45, with tools/chip-model/rtl), floor-denominator (no word yet), then the counter-asic-4 close follow-up after 15:45. Two more deploys from the builder stream, checks ok (21 asserted pages): 9a029677 at 13:50 BST (/metamask reads eth_chainId at load, 0x1170 pinned as the fallback, read back equal to the public RPC's answer) and 7902e235 at 13:55 (/build's networks table and /faucet name 4464 since the class v5 floor; the faucet signs with the node's chain id); the build-server lane's lease-pool memory rule in its gate (a lease declares its GB, the box ceiling 100 GB with the hands' residents counted; the shipper's order after the 12:06 OOM kill of the seed). Lane C's drawn-era re-read on 0ab27582 at 14:0x BST, run on build-2 (build-4's pool never freed, the waiter withdrawn, named in the row): the sound per-load form (16 x 256 x 1) accepts 254 of 256 seeds under drawn eras at 0.819 rejection per candidate, mean accepted attempt 4.3 (no-era on the same binary 234 of 256 at 0.927); the form at class v4's count (16 x 144 x 3) 254 of 256 at 0.811; every sub-block of 36 instructions or longer 0.80 to 0.84 under eras; the iterated 16 x 27 form 66 of 256 at 0.991 under eras and 128 of 256 at 0.979 no-era, dead on both instruments; the class v4 shape through the same binary reads sub-version 3's own 0.666 and 0.682. So the per-load prototype's verdict of 00:0x was an instrument artefact as the record reopened it, and the sound form stands at 0.82 to 0.93 per candidate with the dataflow rule in execution order as the named fix. The cut with these rows and the 5090 rows lands by 15:00. Floor lane 1 (SM-sparse) at 14:00 BST: its PC 1 jobs are run-ca4-pc1-floorsm-5090-20261008 (the ladder at the 1,300 lock, since 13:07, a 66-minute cap, the card free by 14:13) and the memory-clock ladder at the lock (about 20 minutes); floor-pc1-build-2 and floor-pc1-restore are the prover-floor lane's; every rented pod of lane 1's destroyed (spend USD 27); the stock rows, the decomposition and the self-tune in docs/analysis/class-v6/floor/sm-sparse.md at ccafd9a4 on the mirror; the lock and memory-clock ladders the two rows owed for 15:30. The coordinator's PC 1 order at 14:12: floorsm to 14:13, kit d to about 14:22, the read-width run to about 14:42, memclk to about 15:05 (republished behind them), the 7600 card-in at 15:05 (the hash lane: any Thunderbolt housing on any PC 1 port, the job keys on the new card against the 10:04 baseline; the pass about 50 minutes, rows by 16:00: detect and VRAM, 8 GB: the 1 GiB prototype dataset and the genesis 2 GiB floor fit, 4 GiB fits at about 5.4 GiB needed, 8 GiB does not; the class v5 and v4 fingerprints and the stock bench on the OpenCL kit worker; the app's own rate and watts; the AMD knob grid as on the 9070 XT; the Efficiency, Balanced and Maximum rows; the dataset rows at 2 and 4 GiB from the class v3 packs ds29b, ds30b; the 5.5 GiB row by interpolation, labelled, since the exporter takes power-of-two datasets only; a 5.5 GiB pack is a crate change for tomorrow unless main wants it today, default not today). The founder's order through main at 14:4x BST: Devnet 3 comes back first, the users' cut second. The sink-age guard has no switch (service.rs:1131 hardcoded), so the node lane cuts the hotfix now; the fleet, hub-1 and build-1's four nodes move onto it by a +0 file on the fast-time PASS alone (about 15:00), the full gate set and both canaries running behind for the node-only 0.3.26, a re-move if the set finds a red (nothing risked, the chain being dead). release-0.3.26 open at 822f8767 (the version bump only, the app crate unchanged); its DMG, hive and Windows entries re-cut on the hotfix sha and published at a minute after the network is back. PC 2 back and mining as of 14:4x: its queued jobs run on logon (the 0.3.25 install take first, the sign.ps1 self-test, the UI lane's two, the hash lane's Arc read); the 0.3.25 Windows entry on a clean take, the 0.3.26 one on its own. The DEX lane's /swap fix in its gate at 14:4x (the pools table 640 px wide at 768 px with no overflow, the sentence in a wrapping line under the table). The record's forty-fourth landing's merge gate killed by signal 15 at 14:4x BST on the Mac, a second kill since the rule landed; the steward's TERM-sender log is the read; the merge re-run. THE HOTFIX landed at 14:42:44 BST as f8da7515 on release-0.3.25-node (cold_start_replays: Err only for a node that synced nothing or whose retention root is above genesis; a node holding the chain from genesis replays with a stale sink, one line said; the known-failed test cold_restart_tests::a_node_holding_the_chain_from_genesis_replays_whatever_the_sinks_age; nothing consensus, digest 2066aa57 unchanged); the guard was 10 * 60 * 1000 hard-coded at exec/src/service.rs:1131 with no env, flag or config field; the shipper's prepared 4831c372 dropped. release-0.3.26 = 602bce8c (the bump plus the pin f8da7515; the app crate unchanged). The clock: the seed pair and tarball about 14:52, the fleet fetching from then, the fast-time PASS about 15:27, the fleet, hub-1 and build-1's four on it at about 15:35, the gate set and canaries behind for 0.3.26, a re-move on a red; the users' 0.3.26 entries after the network is back; the testnet go cut re-cut on f8da7515 after. The first block's time to main from the shipper. The 1.5x test's measured row ahead of 15:30 (the fleet hand on RunPod secure cloud, 14:28 to 14:39 BST, pods destroyed, USD 0.62 of the 60 incl. a re-rent loop fault that rented five extra 4090s for 14 pod-minutes, all destroyed by 14:36): the class v5 base (v5-genesis) against knob 3 (hl-k3-sh1024: the 1,024-instruction shadow block at 27 passes, 4x the shadow ops, a class v5 research pack on generator 5), the kit worker d84b1b6c, --batches 250 --batch-log2 24 --block-warps 1, watts the mean of nvidia-smi power.draw over the busy window. RTX 5090 (driver 595.91.07, sm_120): base 140.83 MH/s at 442.7 W (3.14 µJ per hash, fingerprint ae74193ddad19e19 equal to PC 1's), knob 3 111.07 MH/s at 551.1 W (4.96 µJ; at the full 60 s it sits on the 575 W limit at 110.0 MH/s, 5.23 µJ), fingerprint d0d9eccde24b30af. RTX 4090 (driver 570.195.03, sm_89): base 62.41 at 279.3 W (4.48 µJ), knob 3 62.64 at 439.2 W (7.01 µJ), the same fingerprints. Reading: knob 3 costs the card 1.58x the energy per hash (5090) and 1.57x (4090), the same on both architectures; on the 5090 it is power-bound and reads as 21 percent fewer MH/s, on the 4090 the rate holds and the watts climb 61 percent; per shadow instruction the long block costs 0.40x the 256-block's (the per-pass overhead amortised); the 4090/5090 rate ratio 0.44 on the base, 0.56 on knob 3. For the founder's 1.5x: the GPU pays 1.58x for this knob while the k lane's chip-side figure for the same knob is its row; knobs 1, 2 and 4 not benched today (2 has no GPU knob, the k lane agrees; 1 and 4 are new ISA, priced by the microbench until a generator line exists). Logs under the scratchpad's 1p5x/fb-1p5x-5090 and -4090. The DEX lane's /swap fix committed on dex-devnet3 (the syncing and no-answer sentences out of the pools table into a wrapping line under it; both tables fixed layout and normal white space; the row reads "RPC syncing" or "no answer"), checked at 768 px with the public RPC at block 0: no overflow; its first landing's full gate killed at 14:4x by another lane's pkill -f tools/ci/pre-push.sh (the kill-by-name class again), the landing re-running, on master before 15:00 unless killed a third time. The record's forty-fourth landing's re-run merge gate read RED at 14:5x on that same /swap clip at 1600 px dark (the sweep renders the live page while the RPC re-executes), so the record lands after the DEX fix is on master. The forty-fourth landing on master at 14:5x BST (e694030f, after the DEX lane's /swap wrap 92b6da6f reached master at 14:48 and cleared the sweep's red). THE INTEL ROW CLOSES at 14:46 BST: the Arc B580 on the second PC reads the rebuilt kit 65b47211 EQUAL at its logon turn (run-ca3-pc2-v5-intel-bench-20261008: v5 fingerprint 82b19cbde8557ea5 = expected, match True, check PASS, 10.794 MH/s quiet; the v4 control 892b6d55a7ddcfcb PASS at 10.718; both self-tests 96 of 96; the host's "rotr_var rewritten to the shift form before the build" line present, sub-group size 32 with sub_group_shuffle_xor), so the rotate fold was the whole Intel fault, the sub-group patch stays unapplied, and the class v5 kit reads one fingerprint on six platforms: CUDA (RTX 4090), Metal and Apple OpenCL (M5 Max), AMD (RX 9070 XT), Intel (Arc B580), the CPU verifier. The page's Intel row at class-v5 916925f5 (both mirrors 14:51); the 0.3.26 line to the shipper by its rule: the post-freeze class-v5 line with the Intel kit in, 0.3.25 on 1c420786 as published; the shipper carries the Intel kit into the first app cut after 0.3.26. PC 1 at 14:50 BST: no job taken since 14:13 (kit d, the read-width run, the memclk ladder, the card-in detect all "no uploads"), the default ran at 14:48: the signed restart job kind for the app (restart-app-pc1-20261008-cardin); if the app is polling it restarts itself and the queue drains in order; if it is hung or gone only the founder's hand at PC 1 brings the runner back (the ask with main since 14:36). At 15:00 with no job started: kit d's rows and the W = 8 row miss the 15:30 close (the op mix the microbench arithmetic, W = 4 pins), the 7600 pass and the 5.5 GiB rows move to PC 1's return. Floor lane 1's close row to main and the research lane at 14:50 with the memclk ladder labelled owed; its file complete at 32132943. Floor lane 2 (shadow k), the design sweep at 14:5x BST (synthesis-only, 8 lanes, ASAP7 TC 0.70 V, gate-level random-input VCD at two run lengths with the steady state solved; k absolute at N3 against the 5090's 6.2 pJ at the 1,300 lock, 11.3 at stock, the M5 Max 6.9): base (32 regs, 256 imem) 186k cells, 6.9 pJ per lane-op (2.4 clocking), N3 3.5, N2 2.5, k 0.31 / 0.56 / 0.50 (stock / lock / M5 Max); (1) the 64-register file (40-bit word) 268k, 9.7 pJ, N3 4.8, k 0.43 / 0.78 / 0.70, a new ISA on the GPU side (in energy about free on NVIDIA, 255 registers per thread; rate paid only when occupancy drops below the latency-hiding point); (3) the 1,024-instruction imem as built (a flop array) 325k, 12.0 pJ, N3 6.0, k 0.53 / 0.97 / 0.87, measured on the GPU at 1.58x energy per hash for 4x the shadow instructions; (3) with the imem as a 4 KB SRAM macro (2 to 4 pJ per 32-bit read, shared by the lanes) about 7.2 pJ, k about 0.32 / 0.58 / 0.52; (4) the drawn select tree 187k, 6.85 pJ, k 0.30 / 0.55 / 0.50, nothing on either side; (2) 32 lanes and (2') 32 lanes at 16 regs in sim, clock 15:30; (5) all four together in ABC on build-3, clock about 16:00. The reading: the 64-register window is the one robust knob (+0.22 of k at the lock, per lane, not amortisable); the long block adds little once the imem is SRAM; the select tree adds nothing; (1) + (3) as built reaches k about 1.2 at the lock but a chip maker builds the imem as shared SRAM, bringing it to about 0.81 (0.45 at stock), and wider SIMD amortises the fetch further; k 0.85 is not reached by any knob a chip maker cannot amortise away; the DRAM board under 2x at the lock needs the register window AND the long block AND the honest card at its knee, and holds only if the chip's imem cost stays unamortised, which it does not. The node column (claimed from TSMC's headlines: N7 to N5 x0.70, N5 to N3E x0.72, N3E to N2 x0.72; the 5090 and 4090 on 4N, N5 class; the M5 Max N3): base 6.9 ASAP7 / 4.8 N5 / 3.5 N3 / 2.5 N2, k at the lock 0.78 / 0.56 / 0.40, the GDDR7 board at the lock 2.4x / 2.8x / 3.2x; the 64-register core 9.7 / 6.8 / 4.9 / 3.5, k 1.09 / 0.78 / 0.56, the board 2.0x / 2.4x / 2.8x. The one line: of the 2.8x at k 0.56, the N5-to-N3 node step is worth 0.4x (a factor 1.17, claimed); the rest is the memory system (3.6x at zero shadow at the lock) less what the class v4 shadow takes back on the card's own node; on the card's own node the base core sits at k 0.78 and the 64-register core at 1.09, so "near 0.9" is reached node-for-node by the window alone; what it does not survive is the node step a chip project buys (an N3 core gives back the 0.4x, an N2 core 0.8x). The placed 8-lane core in detailed route on build-4 at nice 19 (about 16:00). Branch class-v6-floor-k. The hash lane's reading of the 64-register window: not exportable inside 20 minutes: eight registers fixed in four places that must agree bit for bit (the generator's operand draw modulo 8 and the register init from one seed word each; the three kernel texts r0 to r7 selected by (i + 1) & 7; the CPU verifier's register array; the warp's hash fold over the eight), a 64-entry window needing an init rule for the 56 extra registers (a design choice) and a fold rule for the output, then the emitters, the verifier and the vector check: a half-day line; the GPU-side figure modelled: 64 live registers a lane on top of the kernel's forty-odd puts a thread at about 110 of its 255 registers, occupancy to about half, the rate expected to hold under the latency-bound read chain (the 5090 hides about 330,000 ops a hash, chip-model-v3 5.7), the energy per hash to move little, the per-lane register traffic the unmeasured term; the half-day line can start after the 7600 pass if main wants it tonight (default not tonight). The research-landing lane: class-v6-floor-denominator at fc265d8d landed on master as d461e365 (14:50 BST; denominator.md plus the three app/igneum-app/tiers files; full gate GREEN 73); floor-sm (32132943, sm-sparse.md only, 717 lines; the worker patch on the branch) in its gate, landing about 15:03; k by 15:45; the close rows within 30 minutes of 15:45. Two deploys at 14:53 BST, checks ok (21 asserted pages): d461e365 (the DEX lane's 92b6da6f: /swap's RPC-syncing and no-answer lines under the pools table, both tables wrapping) and c8ce4b52 (the UI lane's site-fee-words on main's order: the dev fee as the fixed 1% fee with the app's Settings sentence on /miner and /dev-fee, "switch" and "switchable" gone from the fee card, the "Off with" row and the description metas; no "switch" string served on /miner). No chip text changed. The hotfix f8da7515's full gate set and both canaries read green at 14:50 BST (exec 55 with the dead-chain test, the mixed-version step HANDSHAKE on the unchanged digest), so THE SECOND MINUTE IS 15:05:00 BST, named on the gates rather than waiting for the fast-time pair: every box at +0 (81 of 97 fetched at 14:57, the rest by the pull), hub-1 and build-1's four by hand; the fleet's tarball 29f11d85 (igneumd 07a522f3, the miner unchanged eead4d0c, both fingerprints the freeze's). The merge default taken: 33 solo miners stopped at 14:53 to 14:57 (the fastest branch 122 under the epoch 21 cliff at 75,600, past which branches never merge); they restart with the move and the branches merge inside epoch 20. The 0.3.25 Windows entry skipped for good (a 0.3.25 Windows node would deadlock); the Windows line lands with 0.3.26 (602bce8c; the installer's copy-step fix on that tree by 15:30). The next readings: the first block on the rejoined chain, the replay rate, the first lock. Floor-sm (32132943, sm-sparse.md only) landed on master as 69335fc1 at 14:58 BST (full gate GREEN 73); the landings today: 868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1; open: floor-k by 15:45 with tools/chip-model/rtl, the design document's close rows within 30 minutes of 15:45. PC 1 is back: kit d closed on the 5090 (run-ca4-pc1-v6d-packs-5090-20261008, 14:51 to 15:0x BST, all PASS; rows with the research lane and floor lane 5), the runner's stall 38 minutes (14:13 to 14:51, the founder's hand or the restart job). The op-mix row inside the shadow block: against the same worker's w4 base (119.95 MH/s at 308.2 W unlocked; 100.55 at 190.5 W at 1,300), the shuffle-heavy table costs the block 155.5 W unlocked and 80.6 W at the lock (level with the stock table's 152 and 84 this morning), the multiply-heavy table 104.6 W and 62.0 W (31 and 26 percent less), the rate flat within 0.4 percent: the weight table is a 30 percent lever on the block's watts on Blackwell, with the sign the microbench gave for the multiply end and smaller magnitudes than its arithmetic on both ends. Floor lane 5's hinted w64-l2: 92.35 MH/s at 369.1 W unlocked (23 percent under w4, 1.56x its energy per hash) and 37.59 at 164.1 W at the lock (2.3x), dead at the knee as at stock. PC 1's queue: the read-width run (the W = 8 row about 15:30), floor lane 1's memclk ladder, the 7600 detect about 15:5x and its pass (the first 7600 row about 16:00, the stall's slip); the register-window hand for 16:30; the 5.5 GiB kit from the worker lane at 16:00 with the rented 5090 row behind it. Lane D at 15:1x BST, every stratum COMPLETE: w1band 3,000 (build-2), w4band 3,000 (build-3), w4shape64 3,000 (build-4), shape256 3,000 and shape64lossy 2,000 (build-3), the four lossy-share points 3,000 each (build-1), the F8 label space's p2 to p65 and p212 to p225 through the sigma form (build-2); point A DONE on build-1 (64 seeds: 45 PASS, 3 beyond 1.2x, 2 hot sets p38 and p54, both REFUSED by the class v5 floor at 0.9932 and 0.9945 in the floor read on build-3); point B at 54 of 64 on build-3; the x4/x8/x16 verifier rows resubmitted on build-3's free cores after waiting on build-2's pool since 14:5x; 38,000 drawn eras in all today, about 90 core-hours; the 16:30 report holds with sections 6.4 (the lossy curve per shape), 6.5 (the width-4 floor decision), 6.6 (point A), 6.8 (the seven known-failed seeds through the sigma form, the bucket bound retired into the bit read) in the tree; point B and the verifier rows by 16:00, as partials if not. The floor-invention knee-row amendment (3951528d) landed as 66c3401e at 15:12 BST (full gate GREEN 73); the landings today: 868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1, 66c3401e. The fast-time SUMMARY PASS (cross-0325-f8da7515-2) at 15:17:51 BST on the hotfix f8da7515 (the freeze fingerprint on both binaries read before the lease; 15:04:51 to 15:17:51 on build-1: rung 1 at 15:11:28, class v5 by signal at byte 6 from epoch 8 at 15:13:20, 12 of 12 ids equal to the freeze CLI's, the stale node 78 of 78 refused, the restart step resynced in 6 s with the catch-up done after 3 s, four sinks equal at 662, 0 PoW rejections); the first run on the same artefact (15:03:21) read the crossing green too, its FAIL line the late joiner's wait letting two epochs past the observation window into the id rows (harness scope, fixed); the cold-restart class is the node lane's unit test, the pair cannot read it. The shipper's preview 1 at 15:1x BST: preview-26-1 at 57476931 on the mirror = the coordinator's f2781776 plus app-ia-26 e4773cf0 (item 4, the Tune page), release-0.3.26 f44baa25 (602bce8c plus install-detach-26 b39d5dd5, the take-3b copy-step fix) and the preview mark (state.preview from IGNEUM_PREVIEW at build time, appended after the version on the About line and the footer, empty on a public cut; no constant on any branch); the build-server lane cuts the kit, the cross with the env, the payload with the f8da7515 Windows pair and PC 1's host (host-0326 ahead in PC 1's queue), the install takes on PC 1 and PC 2; the Mac DMG by the Mac chain and the install over the founder's app by the shipper's hand; each machine's version and time to main. One red on e4773cf0: ui/heat-region.test.mjs:137 (a resting card's wording), the UI lane's by 15:35; the preview ships with it named, the public 0.3.26 app cut waits on green; take 3c (the public 0.3.26 Windows entry) on f44baa25 behind the preview takes. PC 1 at 15:14 BST: the founder's restart of the app at 15:06 ended the read-width run at 194 s (exit -1, "script was ended") after its three stock rows landed: v5-genesis 118.83 MH/s at 423.5 W, W = 4 under the state term 117.54 at 430.9 W, W = 8 117.54 at 451.5 W; so THE W = 8 ROW EXISTS AT STOCK (the rate equal to 0.01 MH/s, 4.8 percent more energy per hash; with floor lane 3 and the research lane); the 1,300 lock rows and the W = 16 state-term row owed from a republished run (run-ca3-pc1-readwidth-5090-20261008-b, behind the detect and the memclk ladder, about 16:30). The runner had already resumed at 14:51 on the signed restart job (kit d 14:51 to 15:02, the read-width run from 15:03), so the founder's hand restarted an app that was polling; no harm beyond the lost rows. PC 1's queue: the 7600 detect, the ds55 kit fetch, the memclk ladder (about 25 minutes), the read-width run b, the shipper's host preview build, then the 7600 pass (the OpenCL bench with --cards-off on the new key, the grid, the tier rows, the 5.5 GiB rows on the 7600 and the 5090). A caveat on every PC 1 row since 14:2x: the 5090 reads about 13 percent under the morning on the same packs and worker (v5-genesis 118.8 against 135.9), a host-side change with the eGPU swap; the next job's card line reads the PCIe link, the first suspect. The 5.5 GiB kit done (the worker lane, ds55-v5 at b57045fb, the emulated worker's self-test PASS on the 5.5 GiB pack; the kit on build-1, sha 2d7f55e8) and with the fleet lane for the rented 5090 row. The forty-fifth landing on master at 15:27 BST (6ae577e40). THE CLASS V6 FLOOR CLOSED at 15:28 BST, 17 minutes ahead of the 15:45 clock on the ship-on-green rule, every lane's last row in, on the mirror's counter-asic-4 (docs/design/class-v6-rotating-family.md section 10; the tip 725d2945 at 15:27; the full gate green on the branch; the landing on master by 16:30). THE TABLE (10.0 with 10.0e), the honest tier's measured class v4 joules per hash over the chip's modelled joules, the chip's core the k lane's synthesised sequencer core with the 64-register window (10.0c: the one knob a chip maker cannot amortise, k 0.78 at the lock at N3; the card's window cost modelled, labelled) and the per-unit floor (k 0.18) beside it as the worst case: the RTX 5090 at its 1,300 MHz knee (2.33 µJ): GDDR7 board 2.4x (2.8x without the window; 4.0x at the unit floor), HBM3 stack 2.9x, SRAM die at the genesis width 4.3x; the RTX 5080 at its 1,100 MHz lock, the honest NVIDIA floor (2.06, measured; lane 4's finding that the floor is the 16 GB Blackwell card, not the 5090): 2.2x, 2.5x, 3.8x; the Apple M5 Max (1.40): 1.5x, 1.7x, 2.6x; stock rows: the 5090 3.5x / 4.1x / 6.2x, the 4090 and H100 in 10.0. The node row: 2.0x against a chip on the GPU's own node, 2.4x a node ahead, 2.8x two nodes ahead (node-for-node the window core is k 1.09); the honest tier moves to the next node with every GPU generation while a chip must re-tape-out. SM-sparse: no change on any card (measured on the 5090, 4090, H100: 1.3 to 3.9 percent at best; the residual the clock domain). W = 16 killed on measured energy on four cards at stock and at the 5090's knee (+25 to +34 percent per hash on the card against the chip's +33). STATED PLAINLY: the GPU-tier floor is about 2.2x to 2.4x per joule at the knee against the chip anyone can build, under 2x only against the Apple tier; Monero's RandomX measured 1.0x to 1.5x beside it. THE CAPEX WALL (10.3): no rational chip project of any kind below about USD 23 M a year of miner revenue (IGN 0.03); every DRAM-board project at a third of the network above about USD 340 M a year (IGN 0.44); the project cost moves the threshold 5x, the chip's edge 1.4x. THE SERVED LINE in two units: under 3x per joule at the knee (2.2x to 2.4x with the window), under 1x per hash over its 180-day class life only above about USD 300 M a year of miner revenue (10.0a). THE FOUR CLASS V6 CHANGES: (1) the op mix stays class v4's with the lossy families capped at base (0 of 3,000 eras exhausted under the band; a multiply-heavy table lowers the card's premium a quarter but the chip's further, mul and mulhi k 0.03 to 0.08; the shuffle weight costless to the card and can rise inside B = 4 if the chip's butterfly k reads high); (2) no SM-sparse default (--sm-sparse auto off, on in Efficiency and Balanced at its measured 1 to 2.5 percent); (3) the dataset schedule 5.5 / 8.5 / 11.5 GiB (the 5.5 GiB step measured on a rented 5090 at stock: 3.5 percent of rate, about 4 percent of energy, the non-power-of-two mapping no cliff on sm_120, safe to adopt at the v6 epoch; about 9 percent at the knee, interpolated) with the read width pinned at 4 words (8 measured not free at +4.8 percent of the card's energy for 0.2x of the die's shadowed edge, 16 never); (4) the 64-register window per lane as the core shape, its GPU side modelled until measured. The rotation schedule adopted (10.0d): hourly 8,766 / weekly 52.18 / family 2.03 / vote at most 2.03 extra boundaries a year, the 6 h vote window. Precedents sourced (10.0b): RandomX 46 months to a chip at 1.0x to 1.5x; Ethash 36 months to a chip worse than a GPU, 14x today; Kaspa 21 months, 167x to 725x. MISSING AT THE CLOSE, each with its default in the document and owed as an amendment with its own minute: the k lane's 32-lane rows and placed core (about 16:00; the +30 percent placement and the register-file gating roughly cancel, provisional); the card's measured window cost (a half-day generator line); lane 1's memory-clock ladder; the W = 8 lock row (16:30) and the RX 7600 8 GB-tier row at 5.5 GiB (16:00 to 16:30); lane D's full report 16:30; lane C's drawn-era F8-form read. THE 5.5 GiB ROW measured two hours ahead of 17:30 (the fleet hand on a rented secure 5090, 15:19 to 15:23 BST, USD 0.32, the pod destroyed; the kit igneum-ca3-ds55-kit-20261008.zip sha 2d7f55e8 with its own worker d43be462, program id 73bcbfe8ccf988f1 in both packs): the pinned class v3 program at 1 GiB 141.48 MH/s at 325.6 W (2.30 µJ, fingerprint 90f794dd556f7a3b, the pin, 1,914 MiB used) against 1,476,395,008 words (92,274,688 items, not a power of two: loads are (src * words) >> 32) 136.56 MH/s at 305.3 W (327.6 steady; 2.24 to 2.40 µJ), fingerprint 23ced07a4d28b465 (the new pin, stable over two passes), the self-test PASS 96 of 96 lanes, 6,522 MiB used; the --batches 500 passes 141.38 and 136.54 with the same fingerprints. So the genesis floor costs a 5090 3.5 percent of its rate at stock, about 4 percent of energy per hash, no cliff from the mapping, on the 2 and 4 GiB stock rows where the interpolation put it. Caveat: that host capped the card at 328 W on both packs (the 1p5x 5090 on another host pulled 443 to 575 W), so the µJ figures are capped-card numbers; the rate and fingerprints stand. The emulated worker's known-failed counterpart reads 96 of 96 bad lanes on the old mapping. The 7600's 8 GB reading and the 5090's knee rows at 5.5 GiB from PC 1 after its queue, as amendments. The attack pass's 15:30 reading (counts at 15:21 BST), two non-zeros sent at once: F9 to 10^6 on 1c420786: 135,836 of the 900,000 new seeds drawn (build-4 99,456 across its six lower chunks, build-2 36,380 across its six upper), 0 exhausted, 0 panics, max attempt index 32: one seed, 718097 (build-4 chunk 4), accepted at index 32, past the record's "0 past 31" line but nowhere near the 256-attempt cap; the histogram tail 24: 5, 25: 2, 26: 2, 27: 1, 28: 1, 32: 1, the geometric tail at its rate (one in 136,000 at 32 against the 10^5 record's one at 30); not a finding: the exhaustion gate is the cap and the deterministic last resort, both untouched; the record carries the max as read. F1 to 10^6 class v5 programs: 172,310 distinct programs done (build-4 83,000 of its 350,000 lower range, build-2 89,310 of the upper on four 13-core parts), differential mismatches 0, verifier mismatches 0, 0 panics, programs over 5 percent: ONE, attack-f1/392513 (attempt 0, 6,912 to 6,561 per iteration, 5.0781 percent, 13 of 256 per pass), the same saving to the digit as the v4 10^5 letter miss attack-f1/37341 (AP-F1-1); the next worst 369298 at 4.6875, 373345 at 4.2969. Under the ruling on AP-F1-1 (gate (1) re-worded to compressible beyond the honest compiler's own simplification; a letter miss at honest-compiler parity is a PASS) a letter miss to be read at parity: the section 7.3 and 7.4 readings (explain, emit-c, the compiler pass) running, the parity verdict within the hour; if the compiler does not find the same 13 it is a finding on the v5 bound (AP-F1-1's v5 half reopens). Ends: F1 about 05:00 BST (build-4's lower range back at 40 threads from 15:30, about 01:30; build-2's parts about 04:40); F9 about 11:30 BST tomorrow (build-4's lower halves at 3,400 seeds per hour per chunk the long pole; build-2's upper halves about 08:30, taking more of build-4's range when F1's parts free their cores). Two pre-emptions on build-2, none on build-4. The shipper at 15:2x BST: the founder's Mac runs preview 1 since 15:21:53 (the DMG 94327b68 from preview-26-1 57476931, installed over 0.3.24 by the engine's own helper, the state reading version 0.3.26 preview "preview 1", the node on the f8da7515 pair replaying); PC 1 and PC 2 follow through the job runner once PC 1's host-0326 lands. Build-1's seed and node1 replayed on f8da7515 from 15:06:39 to the sink at 15:13:47 (7 min 8 s), 94 peers, the sink advertised again; the chain stands at 72,001 until one miner runs; the one-miner word to the fleet lane at 15:23 (the heaviest branch's box, the rest as their sinks converge; dn3-q03 and dn3-relay to a wipe and resync, their branch mined past the floor under the old rule). The 0.3.26 public stage complete (DMG 6f717c78, hive e3e4482c); its minute after the first block. MAIN'S CLASS V6 BUILD ORDER at 15:3x BST (the close 725d2945 in; the no-consensus-code hold lifted by the order), five lanes fanned under the founder's clock rule, each sent with its default: (1) the hash lane, the generator: the 64-register window per lane with its init and fold rule, the index fold (layer 1's remedy for the era-stride bit; the known-failed set p4, p8, p10, p15, p34, p212, p225), the op-mix re-weight table (13,11,6,10,8,8,7,2,6,4) behind the fold, W = 4 unchanged, the ds55 mapping as the dataset form; four packs (window, fold, re-weight, all together) exported by 21:00; (2) the census lane re-spawned on the four packs through the sub-version 3 harness on build-3 and build-4, PASS or FAIL by 22:30, a dry PASS on the freeze's pack by 18:00 as its readiness line; (3) the node lane, the object: the class v6 object with the dataset schedule 5.5 / 8.5 / 11.5 GiB tied to state at the era cut, the family bank's first entries as admissible flags, the floor DAA on Devnet 3, the digest, the worker-smoke rule and the fast-time crossing with the cold-restart and template cases, by 23:30; (4) the shipper, the cut: 0.3.27 as the class v6 line, the pin tomorrow morning on the gates, the Devnet 3 flip at a floor at least 90 minutes after the pin, the fleet on the kit workers first, Mac, HiveOS and Windows at the minute, the card after; release-0.3.27 opened tonight after 0.3.26's minute; (5) the audit lane, the served chip page rewritten to the close's sentence and the node column, the harness and the scoring rules published with it, on master by 17:30 (the 20:00 hold lifted by the order). The first packs and the census verdict to main with their times. Floor lane 2's remaining sweep rows at 15:2x BST (synthesis-only, ASAP7, N3 claimed, GPU measured; absolute k at the 1,300 lock): (2) 32 lanes, 32 registers: 5.55 pJ per lane-op ASAP7, 3.9 N5, 2.8 N3, 2.0 N2; k 0.63 / 0.45 / 0.32; the GDDR7 board at the lock 2.7x / 3.1x / 3.5x; (2') 32 lanes, 16 registers: 4.2 / 2.9 / 2.1 / 1.5, k 0.47 / 0.34 / 0.24. The register-file cost is linear in its entries (16 to 32 entries +1.35 pJ, 32 to 64 +2.8 pJ per lane-op at ASAP7), the one term a chip cannot amortise; the imem and sequencer amortise 1.35 pJ from 8 to 32 lanes. The shuffle (routed): 1.24 pJ per lane-op ASAP7 against the card's 29.4 at the lock, k 0.021, the lowest drawn family. The mix optimiser over the layer-1 band lifts the unit-floor k_eff from 0.097 to 0.137 (add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0) and the core's k by about 15 percent. (5) all four together in ABC on build-3 (about 16:15); the placed 8-lane core in detailed route on build-4 (about 16:00); the crossbar, scratch and int8 tile rows after them. Amendment 1 to the class v6 floor close (15:3x BST, counter-asic-4 after 725d2945): the k lane's routed 32-lane butterfly reads k 0.011 to 0.021 (the card pays 29.4 pJ at the lock for a move the chip does for 0.63), the lowest of every drawn family, and its mix optimiser over lane D's band puts the best genesis table at add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0 (+42 percent of k_eff on the unit floors, +15 percent on the core: 0.56 to about 0.64, the window core 0.78 to about 0.9); change (1) moves from "the op mix held at class v4's" to "the band's best mix as the genesis table", subject to one acceptance pass through lane D's harness (ordered by 18:00; the census lane's neighbouring table at 256 of 256 both ways the fallback); the edge moves about 0.1x in the card's favour at the knee (2.4x to about 2.3x with the window); the core32 row in (k 0.45 at the lock at N3). The coordinator's default to the hash lane: the re-weight pack on the amended table unless main says otherwise by 17:00, both tables exported if free. The shipper took lane 4: release-0.3.27 opens tonight after 0.3.26's first block and minute (the bump only; the node line release-0.3.27-node from the object cut); the runbook at scratch r0327/RUNBOOK-0327.md: 0.3.25's twelve steps plus the worker smoke per platform and the attempt-3 read before the pin, the fleet on the kit workers first, the root gate off for a move after which executors start from nothing, every node with --unsaferpc, rules 16 to 19 in their places; tomorrow's pin clock stated as a time on the three inputs (packs 21:00, census 22:30, object 23:30), the flip's floor at least 90 minutes after it. The forty-sixth landing on master at 15:38 BST (3ce4fd7e5). MAIN'S AMENDMENTS to the class v6 build order at 15:5x BST, from two external reviews the founder accepted: (1) the generator's 64-register window carries the liveness rule (the fold forming each load address consumes all 64 registers; the result depends on the whole window; a liveness tool is an acceptance test beside the census) and the op-mix target is the k lane's optimiser split (add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0); (2) the served chip text does NOT take the 725d2945 sentence: the close is amended by 17:00 into three separate statements, energy, economic and response capability, with the lifetime claim and the USD 300 M / 340 M safety-boundary wording withdrawn (a programmable chip survives epochs on firmware), and the audit lane serves the amended text by 18:00; (3) three research lanes beside the build (connected state a4d3518190ad011fc, mixed FP32 aa943688eaa06c538, multi-family adversary a1a9876a88f5a72fc) with rows from 18:30, feeding v7 not tonight's cut unless the connected-state row passes its gate before the object closes at 23:30. Relayed to the audit, research and hash lanes with the clocks. The five lanes' takes: lane 1 (the hash lane) fanned at 15:50: hand A (the window) on reg64-v5 off w8-v5 with the amended spec (the address fold consuming all 64 registers, the end fold over the whole window; ptxas registers, occupancy and spills on the 5090 and 4090 beside rate and watts for the k lane by 18:00), hand B on class-v6-fold off ds55-v5 (the index fold before the stride rotation with the known-failed seven as the per-site index-bit test; the re-weight on the k lane's split, 16,14,4,12,4,11,10,2,10,0 in draw order, sum 83, as hl-v6-rw, the census lane's 13,11,6,10,8,8,7,2,6,4 as hl-v6-rw2 if cheap, hl-v6-foldrw on the k lane's table; the suites on build-3; the packs byte-seed on the node1 state with a drawn era, generator 5, to build-1, the fold pack first); hand A's hl-v6-win and the all-together pack by 21:00. Lane 2 (the census lane afb2fb655385dc259) at 15:4x: per pack (1) the sub-version 3 acceptance with the (c''') per-site floor and the bit-level era-stride read (lane D's fg7 harness, the class v5 crate plus the family-gate diff), (2) attack-f8 at 2^24 on 64 seeds with the window control by site against the pack's state, the hot-set verdict and the known-failed set (p212 and p225 added for the fold pack), (3) the attempts census over the pack's epoch stream; fanned one pack per box, class v5; the f8 point the long pole (45 to 100 core-hours per 64-seed point, about 90 minutes on 48 cores; four packs on two boxes fit 21:00 to 22:30 only with 48 free cores each, which build-4 under the attack pass's 88 and build-3's 24-core pool do not give now); the dry PASS on the freeze's pack by 18:00 as the readiness line, the clock stated when it lands. Lane 3 (the node lane) at 15:4x: the object on the fork branch class-v6-node off release-0.3.25-node at 6e04f7fc (carrying the cold-restart and genesis-stream fixes), program-id first (lifted from the v5 lane's kaspa-pow bin as igneum-miner program-id by 19:00); the fields, each with its own digest arm entered only when set and a key in override-60x.json: program_class_v6_activation_daa (the floor; Devnet 3's value set tomorrow by the floor cut at the pin's publish minute + 7,200 rounded up, at least 90 minutes after the pin; tonight u64::MAX on every network, the devnet-suffix profile for the crossing at 60x), class_v6_dataset_steps ((height, GiB) pairs 5.5 / 8.5 / 11.5 with the state rule's constants: 64 bytes a record, the era-cut read, the genesis ceiling; the item count derived by the ds55 mapping's rule), class_v6_family_flags (a bitset: bit 0 the window, bit 1 the fold, bit 2 the re-weight, bit 3 the lossy band at base; off means not drawable), the class signal byte 7 (CLASS_SIGNAL_V6) stamped from the floor, packaging/pow-freeze.txt as a per-class list with the class v6 entry, tools/ci/worker-smoke.sh for the worker rule (reads the object's fields from the node binary, refuses a cut without one PASS line per platform), the fast-time crossing by the fast-time lane with the --cold and template-at-boundary cases (in its harness since 336639b1); its three questions to the hash lane by 21:00 with defaults (items = floor(GiB x 2^30 / 64); the four bits as listed; the freeze = the last green commit on ds55-v5 at 23:00, class-v6-freeze). The 6e04f7fc go-cut pair landed at 15:33 (the testnet lane's thread). Lane 4 (the shipper): release-0.3.27 opens after 0.3.26's minute; the runbook r0327/RUNBOOK-0327.md. Lane 5 (the audit lane): the old sentence's anchors on every served page staged (home, the litepaper's chip model and table, /miner, evidence row 17, the X35 and X36 ledger rows and pins), the 10.0 scoring definition (whole-card joules per hash over whole-chip joules per hash, the card measured under class v4 with the shadow on, the chip's memory modelled, the chip's shadow priced on the synthesised core and on the per-unit floor), the class v5 harness links to the class-v5 branch's sections 14, 13 and 0 on the git host (moving to master's path on a merge); waiting on the research lane's amended text by 17:00, the landing by 18:00. The register window's first measured row ahead of 17:00 (the hash lane's hand on a rented secure 5090, 16:1x BST): the pinned class v3 base 141.74 MH/s at 303.1 W (2.139 µJ, 30 registers a thread, 24 blocks per SM) against the arithmetic-only window pack hl-reg64 (two interleaved 32-register programs, twice the work per hash by construction) 80.38 MH/s at 308.6 W (3.839 µJ), 96 registers a thread by ptxas and the worker, 0 B spill, 20 blocks per SM (3,400 of 4,080 resident warps, 83 percent). Per unit of work the card is level with the base (160.8 base-equivalent MH/s against 141.7; 15.0 nJ a load against 16.7; the watts level): on Blackwell the 64-entry window costs no energy, no spill, and the 17 percent occupancy loss does not reach the rate under the latency-bound chain; the "half occupancy" model was pessimistic. The 4090 row and the full-chain form on both cards (the address fold over all 64 registers, hl-reg64c) before 17:00. The build-server lane's lease-pool memory rule on master as 5636a0d4 (15:36 BST) and installed on the four boxes at 15:37 (lease sha 82cc0564): a lease declares its resident memory (--mem N or "about N GB" in the label, default 8), the pool waits rather than take the box past 100 GB with the hands' residents counted, the holder line carries the figure; the cause the 12:06 OOM kill of the seed under a 31 GB attack binary. THE REGISTER WINDOW'S MEASURED SET, complete at 15:45 BST on the hash lane's rented secure 5090 and 4090 (the lane's own stamps read CEST; the record carries BST; USD 1.22, the pods destroyed): the 5090 arithmetic-only window pack hl-reg64 (two interleaved 32-register programs, twice the work per hash by construction) 80.38 MH/s at 308.6 W (3.839 µJ), 96 registers a thread, 0 B spill, 20 of 24 blocks per SM (83 percent occupancy), against the pinned class v3 base 141.74 at 303.1 W (2.139 µJ, 30 registers): per unit of work level (160.8 base-equivalent MH/s against 141.7; 15.0 nJ a load against 16.7; the watts level); the 4090: base 62.67 at 208.9 W (3.333 µJ, 29 registers) against the window 31.57 at 210.3 W (6.663 µJ), 104 registers, 0 B spill, 16 of 24 blocks (67 percent), per unit of work level to the digit (63.1 against 62.7; 26.0 nJ a load on both); the 5090 full-chain liveness form hl-reg64c (every load's address mixes all 64 registers, id 3deee2320e70e1bf, fingerprint 4e7cc25967eba280, PASS, on build-1): 70.96 MH/s at 320.3 W, 4.513 µJ, 88 registers, 0 B spill, 20 of 24 blocks; against the arithmetic-only window the 2,016 extra ALU ops an iteration cost 12 percent of rate and 4 percent of watts (the mix in the load latency shadow); against the base the loads a second level (18.2 against 18.1 G) at 17.6 nJ a load against 16.7; the 4090 full chain 31.38 MH/s at 216.5 W, 87 registers, 0 B spill, 20 of 24 blocks, fingerprint equal. THE SINGLE NUMBER THE SERVED LINE TURNS ON: the GPU loses at most 5 percent per load to the liveness window (5 percent on Blackwell, 4 on Ada) and no rate per unit of work, no spill, the occupancy cut (83 and 67 percent) never reaching the throughput; the "half occupancy" model was pessimistic; the 2.0x or 2.4x is the chip side's k, which the k lane holds. The sound class form (+reg64c, the full chain, the only form the liveness rule passes) exports as hl-v6-win on build-3 with its acceptance test in the suite. PC 1 at 15:44: the runner on floor lane 1's memclk ladder (from about 15:20, 25 minutes), the shipper's host-0326 preview build next, then the 7600 detect (about 16:10), the ds55 kit fetch and the read-width run b; the first 7600 row about 16:30, the grid 17:10, the ds55 rows after. Floor-k (bfccc26ed) landed on master as cc49bc6e at 15:39 BST (shadow-k.md plus tools/chip-model/rtl, 78 files; full gate GREEN 73): ALL FIVE FLOOR DOCUMENTS ARE ON MASTER (868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1, 66c3401e, cc49bc6e). The 15:45 close landing dropped by the research-landing lane: nothing from 725d2945 lands; the close rows land as a documents-only delta from the research lane's amended "complete " by 17:00, replayed from 08641162 onward. Lane C's drawn-era F8-form row on master at 5cd69d3d (15:41 BST; invention.md section 3.5): under drawn eras the sound per-load form (16 x 256 x 1, 64 seeds, 2^20 nonces, build-2) is NOT the clean row the no-era read gave: 7 of 64 seeds carry a load site under the (c''') floor of 0.995 (min 0.940 at seed 50; seed 27 at 0.956 with one item at 1,938 reads, 67x the uniform control's maximum), the few-item hot-set class and the era-stride class the in-house pass bounded for class v4 at the same order, structurally because the per-load class as built runs neither (c'') nor (c'''); the share column against a uniform control (median 1.15x, max 1.49x) is the window layer, labelled so. Consequence: layer 5 must take the (c''') floor with the dataflow rule, layer 4's generalisation and nothing new; G5-draw's pass line now "0 of 64 seeds with a site under 0.995 under drawn eras" with the seven seeds as the known-failed case; the acceptance figures (0.819 under eras, 0.927 no-era) stand as the pre-floor rate; the chip model does not move (a 1 MB hot set at 0.3 percent of reads is the in-house pass's 1.002x). Lane C closed: five landings (a9f03598 to 5cd69d3d), the harnesses under tools/attack/v6-invention/, six TSVs; owed at 09:00: the Apple footprint of the 4,096-line block, the 4070 and 9070 XT rows, the F8 read under eras against the window-model null. LANE D'S FULL REPORT LANDED on master at 81b90128d (15:46 BST, gate GREEN 73; a first landing de184157a at 15:39 lacked the point-B row by an edit fault), 44 minutes ahead of 16:30: family-gate.md with every row measured and its log. The rows since 13:13: (1) the lossy-share curve per shape at 3,000 eras a point: the exhaustion a 256 x 27 interaction (3.3 percent of its eras at the +4 corner, r = 0.98, about 6x the independent-attempt figure; 0 of 5,015 shape-64 eras at any share), the band's edge at +2; every exhausted era passed class v5's last-resort scan at k = 256 to 258. (2) The width-4 floor: with W = 4 pinned at genesis, (c''') at 0.995 stays at its measured cost (14.6 percent of the candidates reaching the 2^20 pass, +0.3 attempts an epoch), because the width-4 pre-floor spread has a real tail (10 percent under 0.991 against 2 percent at width 1) no single floor removes at the width-1 cost, and the floor refused both hot sets of the live point-A census. (3) Ring C, 128 live epochs of the band at 2^24: point A (shape 256, a band table) 2 hot sets (p38, p54), both refused by the class v5 floor at 0.9932 and 0.9945; point B (shape 64, a band table) 0 hot sets, 5 over 1.2x (the shipped class's own tail seeds), the floor refusing 1 of 64; the bit-R bucket class on 36 of 128 live epochs against the shipped class's 4 of 64. (4) The seven known-failed seeds through the sigma form: p4, p8, p10, p212, p225 all at z = -511 to -567 at address bit R (the product's bit 0, z = -512 exactly), the bucket bound seeing only the three on narrow windows above bit 12; one value-level test ships (the per-site index-bit read as a per-era record and the structural fix's known-failed set), the bucket bound retired into it; a refusal band of 300 sigma catches five of seven at 16 percent of epochs redrawn, 6 sigma would redraw half. (5) The verifier rows on one build-3 core: x4 3.73 ms, x8 4.12, x16 7.13 per warp (1.73x), so x16 scales over the 10 ms gate on the 2019-class core and the half-core proxy: the mixer band is {4, 8}. (6) Bounds: 9,000 band eras with 0 exhaustions and 0 under the floor bound the failing fraction at 3.3e-4 at 95 percent; the floor's miss rate on hot sets under 0.27 on 11 of 11 cases. Running for the 18:00 amendment on build-3: the best-mix genesis table (renormalised 14,13,4,11,3,10,9,2,9,0) through attack-f8 at 2^20 on 64 seeds (16 cores) and the attempts census with the refused-ratio column at widths 4 and 1 (1,500 eras each, after the fg8 build; the fg7 harness could not hold a fixed non-base table at B = 0). Lane 5's served text at 15:4x BST on branch spec-accept-23 be21940f5, read by the coordinator (the IGN-price lines held out by the standing rule; one verb queried, "retains" against "adopts"; the landing by 18:00). The sentence from 10.0h, on the home line, the litepaper abstract, chip section and limits item, and the miner page: "Class v6 retains the 64-register window. Current modelling estimates a 2.2x to 2.4x energy-efficiency advantage for the strongest specialised designs assessed against the GPU tier (2.0x on the GPU's own node). The long-program and select-tree proposals were rejected. Economic resistance depends on development cost, deployment economics and productive hardware lifetime; family transitions receive an obsolescence benefit only where a loss of competitiveness is demonstrated; programmable multi-epoch designs are included in the assessment." Beside it on /litepaper#chip-model: the labels paragraph (2.2x to 2.4x modelled; the GPU side measured, the RTX 5080 at its 1,100 MHz lock 2.06 µJ per hash, the 5090 at 1,300 2.33, class v4, 8 October 2026; the chip side claimed, the synthesised 8-lane sequencer core with the window, ASAP7 scaled to N3 on the foundry's headline factors, the window's k synthesis-derived and not a lower bound; the memory modelled; 2.0x node for node modelled, k 1.09; the 32-lane rows pending); the three-row table (energy resistance 2.2x to 2.4x a node ahead, 2.0x own node, 2.8x two nodes ahead on the 8-lane core, the honest tier moving with every GPU generation while a chip must tape out again; economic resistance on development cost, deployment economics and productive hardware lifetime, the first cut: the price at which a project pays scales as project cost over share times discounted life and moves by under 5 percent with the per-joule edge, a fixed-lane chip under rotation needing 4x the price a programmable one needs, "stated as the conditions under which development is attractive, not as a forecast"; response capability: a passed boundary proves the rotation works, not that hardware dies; the schedule hourly / weekly / 180-day family / emergency vote); the measured cost paragraph unchanged; the precedents as 10.0b sources them (the Antminer X5 46 months after the fork at 6.37 J per kH at the wall, "an observed comparison, not a ceiling"; the X9 pre-order, withdrawal, no benchmark; RandomX v2 released 25 March 2026, activation pending; Ethash 36 months, the iPollo V2H about 14x; Kaspa 21 months, 167x to 725x; the commodity cohort = discrete GPUs, the Apple row beside, never the headline); the scoring rule (min over workloads of max over free adversarial designs of E_GPU over E_adversary under the 10 percent GPU-cost budget at the lock, the verifier limit, cross-vendor correctness, hardware accessibility; the rejected long program, select tree, wide read and scratchpad as negative controls with their rows; the next programme: connected state, mixed integer and FP32, the multi-family programmable adversary); the links to the close on master and the class-v5 branch's sections 14, 13 and 0. Struck from every served page: the 2.1x/3.4x launch line, the 5x to 9x baseline, the ladder's 2.8x rung row, the USD 100 M pay-back row, the k about 0.33 column, the "band Igneum's model sits in" sentence; never served: the lifetime claim, USD 300 M/340 M, any chip-arrival probability, the 725d2945 sentence, W = 8. Evidence row 17, ledger X35/X36 and the ledger-text-check pins move with it; docs/plans/counter-asic-3-public-text-2026-10-07.md section 1 superseded on the served pages (the coordinator's to amend). The hash lane's clock corrected at 15:49 BST (its afternoon stamps about fifty minutes fast, the hands' and the box's CEST copied in; every minute read off TZ=Europe/London date from here). Its open minutes: the 7600 detect about 16:10 (PC 1's runner on the shipper's host-0326 preview build; the memclk ladder closed done at 15:4x), the first 7600 row about 16:30, the grid 16:40 to 17:10 with the tier rows, the ds55 rows on the 7600 and the 5090 by 17:40, the read-width lock rows between them; hand A's hl-v6-win and hand B's fold pack about 17:00, the re-weight packs by 18:00, the class-v6 merge, the all-together pack and the freeze sha to the node lane by 21:00. The forty-seventh landing on master at 15:58 BST (022bc52bd), the 7 October public-text file marked superseded. THE PUBLIC 0.3.26 CUT: release-0.3.26 = 1f4904e0 (app-ia-26 ebb20c46 whole, the audit's PASS, the detach fix, the node pin f8da7515; the preview mark empty; the push gate green 15:50; the crate gate green on d1edf2ad at 314+35+8 and running on 1f4904e0 on build-3). THE MINUTE for Mac and HiveOS is 16:00:00 BST on the founder's "push now" (the DMG building on the tip, the hive e3e4482c staged); Windows host-less by main's word about 16:15 (the PC 2 installer build on 1f4904e0), PC 1 and PC 2 by their update checks. The founder's Mac runs preview 2 (a96efbab = effc48e9 whole + the mark) since 15:40:22. The node side: the snapshot short-capture class (the node lane's read at 15:48: every converging node refused its own epoch's blocks after a mid-epoch resume) cured on the fleet by the snapshot-aside restarts running now (24-minute replays; the first hub block about 16:10), its fix acaf08b0 under gates for the fleet's +0 move and the users' next node-only OTA; 0.3.26 ships on f8da7515 since an updating user replays from genesis. release-0.3.27 opens after the 16:00 minute. THE FIRST TWO CLASS V6 PACKS on build-1 and with the census lane at 15:58 BST, an hour ahead of the 17:00 line: hl-v6-fold (id 482dc0dad937135b; the seven failing seeds fire at -58 to -567 sigma on the plain address and read under 3.5 sigma with the fold, the same attempt accepted both ways) and hl-v6-rw (id 30628f8adcf6035e, the k lane's table, the op counts within 0.1 point of the table over 1,000 draws, the plain path byte-identical to the pinned pack); hl-v6-foldrw and hl-v6-rw2 next, hl-v6-win from the window hand on its suite's green. THE CENSUS LANE'S READINESS LINE met at 15:53 BST, seven minutes inside 18:00: a dry PASS on the freeze's class v5 pack (v5-dn3-epoch0, program id e5a4ac5978462156 re-drawn from the pack's own seeds, class and era) through the whole pack harness on build-4, the known-failed set reproducing the record to three places. The harness (branch class-v6-census-fg at 3602d4ad on build-3 and build-4; ds55-v5 b57045fb plus lane D's family-gate diff 3dc3117c plus a sitestats command and the attack pass's f8 tool with a --load-class path; binaries pinned on both boxes, byte-identical): per pack (A) the program re-drawn and judged by the whole rule with (c'''), then per site over 2^20 evaluations the distinct ratio, the 256-item bucket sigma and the index-bit era-stride sigma (4 s on one core); (B) the attempts census over 256 chain-shaped seeds of the pack's class under its era and state (16 cores, 2 minutes); (C) the F8 census on the live state-keyed dataset: the known-failed set at 2^24 one program per 8-core job (4 to 5 minutes each) and 16 seeds at 2^22 on 16 cores (about 30 minutes); class v5, nice 19, pid files under /srv/builds/v6-census/pids/. The dry rows: (A) accepted, min site ratio 0.99923, bucket sigma max +5.5, one site at bit 9 at -448 sigma (the era-stride class on today's load_index, the record's own); (B) 256 of 256, 0 exhausted, r 0.716, (c''') 1.66 percent of candidates; (C) p4 1.2163x FLAGGED (+67.7 sigma bucket), p8 1.3787x, p10 1.5052x, p212 1.1917x (+91 sigma) FLAGGED, p225 1.2457x BEYOND the 1.2x gate, p15 and p34 PASS at 0.9999x, the hot set clear on all seven; the 16 seeds 2 of 16 done, both PASS, max 1.0064x. The per-pack pass line: (A) accepted with every site clear of 0.995; (B) 0 exhausted of 256 and r under 0.90; (C) every seed within 1.2x over the window model and no 6-sigma bucket outside the known-failed set, the known-failed set reading as it does here (the fold pack expected to move p212 and p225). Per pack one box, the next pack the other. Two defaults: the all pack's F8 point at 1,476,395,008 words needs the hash lane's DatasetGeom threaded through the tool (at 2^28 today), threaded after the three single-feature packs or named owed at 22:30; the 64 x 2^24 point per pack (45 to 100 core-hours) owed in every case, the 16 x 2^22 plus the known-failed set standing in. THE RX 7600 READ (the card-in run on PC 1, 15:46 to 15:50 BST; the detect script of 10:10 still switched the card through /api/cards before the morning's fix, so it ran the whole pass at once): the new key amd:gfx1102 "AMD Radeon RX 7600", 8,176 MB, discrete, the 9070 XT gone, the OpenCL device [1] gfx1102 on AMD-APP 3683.0 (a duplicate [3] on the older 3652.0 platform hidden); the class v5 and v4 fingerprints MATCH on the kit worker; the stock bench 13.88 MH/s at 113 W quiet (0.123 MH/W); the app's own row 13.4 MH/s at 113 W mining; the 1 GiB dataset fits. Per tier: an 8 GB AMD card at 0.123 MH/W sits level with the 9070 XT's 0.097 stock and 0.127 tuned, a quarter of a 5090's per watt; the knob grid (IGNEUM_GRID_CARD=7600) and the 2, 4 and 5.5 GiB rows follow on PC 1 behind the read-width run b (the grid about 16:50, the sizes and the ds55 rows by 17:40); the tier rows from the grid, to the denominator and UI lanes. Lane 5's landing state at 15:5x BST: the gate green on be21940f5; the "retains" verb with the research lane (the default: the review's text verbatim at 17:15; "adopts" re-gated as one word and landed by 18:00); the served link to the close points at the design document on master, so the landing waits for the research lane's master sha (its 17:00 line) and falls back at 17:30 to the branch path. The review's manifest order on the next branch (release-manifest-8, its gate running): site/release-manifest.json served at /release.json with the chain id (4464, 4463 below the floor), the node commit f8da7515 with the pin c9ad753a and acaf08b0 pending, igneum-pow 1c420786 with the freeze fingerprint, the mining class (v5 since DAA 68,400, v4 at genesis, the ladder at rung 0), the dataset parameters, finality rule v3 (two thirds of active and two thirds of total, the frozen table from checkpoint DAA 0), the SP1 program ids from the ELF manifest, the verifier off per P21, the fee schedule, the versions per platform with SHA-256, every block labelled; /build, /economics, /miner, /evidence and the litepaper's Devnet 3 line read from it at build (held by a new gate check); /light, /receipt and the light client now say two thirds of total weight; 4463 marked historical in spec 07 and six older docs; every dated /bench entry with a "Historical record of " line; the evidence page's sixth label "activated" and the reference-repository wording; landing after lane 5, before 19:30; the economics "who pays for proving" section by 21:00. The floor-sm amendment (66bc6ca7, the memory-clock ladder) landed as b1b8d833 at 15:57; the denominator amendment 6d0f11e5 about 16:07. THE AMENDED CLASS V6 CLOSE LANDED on master at 16:12 BST as cbf5aa46 (the merge of counter-asic-4 0c8a0625, full gate green 73, pushed to all three box mirrors), 48 minutes inside the 17:00 clock: docs/design/class-v6-rotating-family.md section 10: 10.0 the table; 10.0a the lifetime unit marked superseded; 10.0b the precedents sourced with the RandomX wording; 10.0c the sweep; 10.0d the rotation schedule; 10.0e the window with the card's cost MEASURED (within 5 percent per load, no spill, on a rented 5090 and 4090); 10.0f the first review's five corrections with lane 3's profitability surface; 10.0g the second review's seven; 10.0h the served text, the one word made honest with the audit lane ("Class v6 adopts the 64-register window and retains it across every rotation"); 10.0i the adversary's re-optimised core and the bracket the served figures sit in until the k lane's placed gated rows (17:30; the audit lane holds for them and serves once, 18:30 if late). The coordinator's earlier copy of the design file on master superseded in the merge. An amendment after the landing, on the branch for the next landing: the multi-family adversary lane's first core puts the 64-register window in a macro at k 0.40 node-for-node for the whole draw and reads that the window knob buys the card nothing against a macro file; the k lane's own SRAM-banked model says the opposite (8.5 to 10.5 pJ, not cheaper than its gated flops); carried as a disagreement the two lanes' placed rows settle (17:30 and 18:30), the served window line read as: measured cost under 5 percent, about 0.13 of k against a flop-file adversary, possibly nothing against a macro-file one. The multi-family adversary lane's first rows at 16:4x BST (synthesis only, ASAP7 TC, random-input gate-level VCD; the SRAM macro term modelled; node factors claimed): one in-order SIMD core with the 64-register window in an SRAM macro per 8 lanes and the imem in two macros, every unit operand-isolated, a 5-phase single-port slot, every bank entry as firmware (fold constants, select tree, shapes, W = 4, atoms as programs). The genesis-only variant (10 families, 8 lanes, 66,973 cells plus 3 macros) on the class v4 draw: 5.9 pJ per lane-op at ASAP7 (5.1 to 7.7), 4.1 at N5, 3.0 at N3; against the card's measured 10.3 pJ per op on the same draw at the 1,300 lock, k = 0.40 node-for-node (N5) and 0.29 a node ahead (N3); at stock 0.22 / 0.16. Per family at the lock (k N5 / N3): add, sub, xor, rotl, rotr 0.45 / 0.33; or 0.36 / 0.26; mul 0.32 / 0.23; mad 0.55 / 0.40; mulhi 0.12 / 0.09; shfl 0.083 / 0.060; the load with the fold 0.43 / 0.31. The whole-hash shadow at 102,612 ops: 0.42 µJ at N5, 0.31 at N3, so the GDDR7 board with this core reads 2.33 / (0.466 + 0.42) = 2.6x against the 5090 at its lock node-for-node (2.9x a node ahead), the 5080 at its lock 2.3x / 2.6x. Meaning: the adversary's re-optimised core (SRAM state, port time-multiplexing, operand isolation) sits 15 percent under the k lane's 32-register flop core and 40 percent under its 64-register flop core at the same node, so the 64-register window is not the robust knob it read as; the review's rule 5 holds. The full 18-family variant (95,678 cells, +43 percent) in the power step, the placed 8-lane core at CTS, the 32-lane cores in synthesis; six rented hosts, USD 1.2 an hour. The connected-state lane at 16:55 BST (class cs64s27x16, research, behind --class, never a chain class; branch class-v6-connected 69649ab45): a 64-register window per lane; per step a 4-byte load from a window register, then a block of 27 distinct instructions run 16 passes, the next address from the block's last instruction on a fresh spine, the result folding all 64 registers; 128 loads + 55,296 ALU per hash (v5: 128 + 55,680); text 448 per iteration (v5: 320). Liveness (seed igneum-v6c/0): 63 of 64 registers necessary for a later address at every one of the 128 addresses until the last iteration's tail, the result reading 64; per step an address depends on 1 to 15 registers of the previous address point (mean 11.2): the chain narrow per step, the whole window necessary over the hash; each block touches 16 to 24 registers, every register read 384 to 3,208 times and written 128 to 1,664 times per hash; a specialist must hold 64 x 32 bits live per lane and can bank them (about 20 hot per step, the set moving with the text). Census (the sub-version 3 harness, (c''') on): no era 256 of 256 accepted, 0 exhausted, 0.28 rejections per candidate (the control mx8+sh256x27 0.67), mean attempt 0.39 (control 2.0); eras 0 to 7 at 32 seeds each with the window-bit refusal on: 256 of 256, 0 exhausted, mean attempt 1.7 (control 4.9), 306 window-bit refusals (control 218): the product-bit class the layer-1 index fold removes, present as in v5; F8 form at 16 seeds x 2^20: the top 0.1 percent share 0.999 to 1.002 of the uniform control. GPU at stock on a rented 5090 at its 575 W cap (the class v5 nvcc harness, 250 batches of 2^24, both packs minutes apart): cs64 64.93 MH/s at 574.8 W against v5-genesis 65.30 at 574.8 W, energy per hash +0.6 percent (8.85 against 8.80 µJ in this harness); ptxas 80 registers per thread (v5 48), 0 spills, 24 resident blocks per SM; fingerprints cs64 ad0cec2a42c84aff, v5-genesis ae74193ddad19e19, vectors 3 of 3 PASS. Meaning: the window costs the card under 1 percent of energy per hash at stock, far inside the 10 percent budget, and a chip a 64-entry live file per lane. The 4090 row by 17:15, the PC 1 lock row owed (the bound emitter building); the k lane's score and KEEP or KILL at 18:00; connected-state.md with every row by 17:45. The 0.3.26 Windows entry live at 16:11:04 BST (installer 8e674bd5 from 1f4904e0, host-less, both folders and the public alias, read back live): EVERY PLATFORM ON 0.3.26 (Mac and HiveOS 16:02:53, Windows 16:11:04), the PCs by their update checks. The network: dn3-g1 refused dn2-1's branch at 16:06:55 with a genuine InvalidPoW after its full replay (dn2-1 sat in the held group and mined on 5b673577's object through the stall, so its branch's state past e1f65284 and its epoch 21 reference are foreign to every f8da7515 node); the fleet's default taken at 16:12: the chain is p1-4090's branch (sink 486a7cb6, mined on c9ad753a's object from 14:50, under the epoch 21 line), its miner at its sink, the rest by IBD, the hubs as they converge, dn2-1 wiped after. The rule candidate for the next line (the node lane's reading asked): a held box never mines on the old object past a digest-moving minute. The denominator RX 7600 delta (29df04cf, denominator.md plus class-v5-tiers.json at 31 classes) landed as c3911a8c at 16:12; twelve research landings today. The class v5 lane's ask at 16:4x: no class v6 order had reached it (the shipper's relay named its items second-hand); the coordinator sent the order's text at 16:45 with the lane's item: the class v6 kit, the six-platform fingerprint read on the hash lane's class-v6 merge on the all-together pack, the known-failed case first (the plain-address pack reading a different id from the fold pack on every worker), the kit zip on build-1 with its sha by 23:00, the Arc and the AMD through the PC job runners, the Mac by the Mac chain; a miss means the kit ships tomorrow morning on the merge's last green commit with the platforms read so far named, and 0.3.27's pin waits on six equal reads. The enforced-proving lane (ledger P21) at 16:15: the test set and the full crate suites green on build-2 ahead of 18:30 (igneum-exec 64/64, kaspa-consensus 138/138, kaspa-consensus-core 171/171): a valid SP1 proof a condition of payment in consensus behind the named switch verifier_in_consensus, false on every compiled object (the live Devnet 3 object unchanged; igneum-testnet-1 gains the payment rule on its DAA floor 0; the class v6 object carries the switch true); six consensus-side and seven executor-side tests named per refusal, known-failed first; branches enforced-proving (b6a538b65: docs/spec/proving-enforcement.md, the P21 and P22 rows, the 60x switch listing, infra/fast-time/proving-enforcement.mjs) and enforced-proving-node (the fork, edf45887 plus one import fix, off acaf08b0 with f8da7515). The coordinator's word at 17:00: the main-repo branch lands on master through the gate now; the node commits take release-0.3.27-node, the line the node lane cuts from the class v6 object tonight, the branch tip and its suite lines to the node lane for the merge under the object's gate set; the verify-cost row by 20:00 (the stated 0.26 to 0.53 s cold verify per record labelled stated if no core by 19:00). The record's forty-ninth landing's merge gate killed by signal 15 twice more at 16:1x BST on the Mac (rule 4 refuses the class in scripts; a hand command still reaches it); the third run in the background. The three gate kills at 16:14:24, 16:17:20 and 16:18:15 BST found by the coordinator in the lanes' transcripts: the site audit lane's shell ran pkill -f "tools/ci/pre-push.sh" in its spec-accept-23 scratch tree each time, the kill-by-name class the CLAUDE.md rule forbids since 12:5x; the lane told to end its own gate by its pid file only; the record's forty-ninth landing re-run a fourth time. The steward at 16:33: the class v6 matrix on the node lane's first sha 617cb441 (class-v6-node, app tree 89e83df2, the class v5 freeze tree linked, the parent's 60x file at bf2c878d's three keys) started 16:33 on build-2 and build-3 at gate priority, seven suites each, the line by 16:55; the object commit's matrix the same way the minute its sha lands. A SHARED-DEVNET FACT FROM THE FLEET (not this lane's, with the shipper and the infra lane): the Hetzner live seed 188.245.5.161:26611 is still on the old override object (digest eada4bda) 1 h 40 min after the 0.3.20 sweep (the fleet never touches Hetzner nodes, so it was outside the sweep); the 0.3.21 wipe canary c22-1 took five digest-mismatch rejects from it; an app with the packaged peers is refused at the seed and syncs through node1 and the hub only, a fresh joiner with only the seed cannot join, the 14 voters and the hub are unaffected; the owner puts the floor file ov16-floor-900000.json (sha 294f1f80) and the c4459193 pin on it. 0.3.21's STAGING (the node lane): the order dry-merges onto 55768f88 with nothing moving to 0.3.22; the late-join fix is 52e96c94 (70e4601e rebased onto 55768f88, exec suite 33 green with both new tests); f067f7c1, b0444f51 and 437f0438 merge clean in order; 2e32d5f6's one conflict (DST_ADDRESS beside pool-finish's DST_BINDING in consensus/core/src/finality.rs) kept both; the live-file digest eada4bda after each (every switch at never); the staging waits on the shipper's sweep-end word; the re-pin held. PC 2 DOWN AGAIN (main, 16:5x UK): the founder takes PC 2 down for cable work (PC 1 back but his desk); both PCs out of the sweep's waves, each updates on its poller on return; no PC job to PC 1; the Windows G1 completed before the outage, nothing reruns. 0.3.21's SECOND GATE LINE on 55768f88 (sha256 279b1b690e854fc9): the ten-minute mixed-version gate beside the 5899f603 pair, 13:37:40Z to 13:47:52Z, SUMMARY PASS (one digest b0afb2ee on five nodes; 223 new and 381 old blocks accepted by the old hub, 0 rejected; counts equal at 319, 486 and 604 through both clean joins and the restart step at 13:45:22Z; no panic); the node lane's two lines on 0.3.21's first candidate complete, in plan 6.9 on ca3-v4-node; the fleet's set on it (the bare-child 12 GB line, the wipe, the kept read, the cases) is the fleet's. 0.3.21's FIRST GATE LINE on 55768f88 (sha256 279b1b690e854fc9, the string read back; pairing igneum-pow 8c728ca3 at byte 5): the digest gate 13:35:41Z to 13:37:19Z SUMMARY PASS (a89be8a7 on both binaries with the peers; db9a85f9 refused, no peer; the live file's eada4bda unmoved); the ten-minute mixed-version gate from 13:37:40Z, line about 13:50Z. The 0.3.21 order as the shipper sent it: 55768f88; f067f7c1 and 70e4601e; b0444f51; 6eb21fc9; db28d331; then the re-pin from 8bdcbdd8 on the coordinator's word; suites between, the digest read after every one; the mirror's release-0.3.20-node back at the pin c4459193, release-0.3.21-node open at 55768f88. THE LATE-JOIN COMMIT (N9's second half, the node lane): 70e4601e on the box mirror as branch proof-hold-fix, from c4459193, two files (igneum/exec/src/proving.rs, protocol/flows/src/v10/proving.rs); the gap was the fetch side on the joiner (the served record ran the native check against the joiner's trailing exec state before anything was stored, the check refused it, the proof was never held, the body rule read "not held" for 20 s and failed the IBD); the fix holds the proof by hash before the checks (the pool entry still needs them) and the serve side says when it holds fewer than asked; the exec suite 32 passed at 13:26Z with the known-failed shape first, the flows check green 13:28Z, igneumd on build-1 at the 0321 worktree path built 13:32Z, sha256 17649eeb2f7d1290, string read back; with the testnet lane (the resume form, B alone); it joins the 0.3.21 staging as its own commit. THE WIPE CANARY ON c19-1, c4459193 (sha 45be9b02d1b002f5, string read back): FORM END rc 0 at 13:50:53Z. Wipe synced 13:35:50Z (57 minutes, inside the 98-minute class); mining 13:36:00Z to 13:47:07Z, 66 mined, 66 accepted, 0 rejected, isSynced true at the tip throughout; the hub holds 41 of its blocks in its last 700 with 0 rejects (13:47:09Z); the restart on its kept datadir at 13:47:15Z: the old process stopped at once (the new process's first lock line seven seconds after the marker; the watchdog held nothing, the b7cc37e7 fault closed), synced again at 13:48:39Z after 84 s, 109 templates read with max 3,432 ms and 0 timeouts; the kept read on pool-1's 0.3.17 copy on the same pod passed at 13:38Z (the rewrite line once, a clean second start). The pin's set on c4459193: the digest gate PASS, the mixed-version gate PASS, the wipe canary PASS, the kept read PASS, the restart PASS, the 12 GB line proves and verifies (paid is a race, not a gate); CASES END from c20-1 (about 14:50Z) is the last pin line. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | +The knee by main's rule (more than 1 percent lost against unlocked): 1,300 MHz on both classes (the rate within 1.5 percent of unlocked down to it; v3 falls 5.1 percent at 1,200, v4 10.5 percent at 1,100); the best MH per watt one step past it: v4 at 1,200 MHz (133.80 MH/s, 305.1 W, 0.439 MH/W, 168.6 W recovered for 2.2 percent of rate), v3 at 1,300 (134.62, 223.3 W, 0.603, 106.6 W for 1.4 percent). The v4 premium 143.8 W unlocked, 81.8 W at the best points; the v4 rate 0.25 percent over v3 unlocked and 0.61 percent under at the best points; the residual at the floor is the shadow's ALU work, not the clock. Per tier: a 5090 owner on class v4 locked at 1,200 to 1,300 MHz draws 305 to 313 W instead of 474 for 1.5 to 2.2 percent less rate, MH per watt up 49 to 52 percent; the Ember knob (0.3.24, the hash lane on the engine side, the UI lane's drawing) carries these as its reference rows. A FAULT FOUND AND FIXED: the steps 1,000 down to 300 and the closing reset got no answer from the Power Helper and the card sat at the 1,100 lock for about five minutes after the job (118 to 122 MH/s live); the installed app's own Ember tune on the 5080 wrote the same cmd.txt with higher sequence numbers while the script wrote lower ones, and the helper skips any sequence at or under the last run; the restore job run-ca3-pc1-clocks-restore-20261007 (exit 0 at 20:45:58Z) put the 5090 back at 2,865 MHz; the fix 45f9497f on the mirror (the sequence base from helper.log and cmd.txt, re-based after a timeout, an unanswered lock stops the grid, the task restarted before every reset); the rule for the knob: it takes its sequences from the engine's counter and no script shares the file with a running tune. The driver's floor below 1,100 is unmeasured. THE PC 1 QUEUE after the shipper's 0.3.23 host job (main, 21:5x UK): the 5080 full grid with the fix; the research lane's SM-sparse kernel job (the hash on a fraction of the SMs, several chains per thread, the rest clock-gated; the research lane hands the kernel to the hash lane); the third 5090 pass from 1,100 down to the driver's floor at the tail; then the 9070 XT G1 and ladder, the v5 AMD bench, item 6 on AMD, the 5080 and 9070 XT tunes, the L2 cache-policy hot table; each exit line to the shipper and the coordinator; the honest site sentence (the premium at the knee and the floor it buys, labelled measured, the Ember knob named as how a user gets there) once the 5080 reads. THE DERIVATION FINDING FIXED (the hash lane, 15008aca and 0f45c8be on the mirror): one byte recipe (generator::IdRecipe) builds the id and the printed text; program.json states the generator 4 suffix and the rung form; spec 1.4.6 corrected (class v5 = generator 5, no suffix); tests/derivation.rs re-derives all 18 pinned packs from their own text (the plain text gives 8aa9f185d63f269e for the devnet v4 pack, the known-failed case); 38 packs' program.json re-exported with ids, kernels and fingerprints byte-identical; the full igneum-pow suite green on box 2. CLASS V5 FROZEN: class-v5 1c420786 on both box mirrors at 21:53 UK (the (c''') floor with its number; section 14 with seven of seven live hot sets refused at 0.9821 to 0.9919, seed 170 at 0.9880 the seventh, and the three mild residuals at 0.9992 to 0.9997 named at about 1.0004x; the pinned pack unchanged; the flip-stale harness PASS on the matched binaries at 21:03 UK; the AP-F4-1 first form and the AP-F1-1 shadow rule, the latter's measured trigger 11 permille maximum over 6,000 first draws against the 30 bound, 0 redraws; the igneum-pow suite green on box 2: 73 unit, packs 20, derive 7, mixer 4, recheck 2, scratch 7; the gate GREEN at 58 checks). The kits lane: the 0.3.24 kit is packs-ca3-v5-20261007T183921Z.zip sha256 e6c088bb34fecdc3ff297dbb06438a14ade7d8c55273357726d28f7a1334a25e, byte-identical to the frozen 1c420786 (state.igsd1 included), fingerprint 82b19cbde8557ea5 on Metal, Apple OpenCL and a CUDA 4090; AMD on PC 1's queue, Intel deferred; the shipper has the line. The attack-pass lane runs F8 at 2^24, F9 at 10^5 and F1 on 1c420786 under class v5. The v5 lane's next commit on the freeze: AP-F4-1 in the agreed form (cost at most 205 against the median 226, w32 without the position-32 digit, k >= 1 and all-ROT-equal rejected, the known-failed day 29,337 = 2050-04-28) and the verified last resort (part (a) repaired by re-sourcing stale loads, then the whole rule over a 256-candidate scan, known-failed first on adv-accept-3's adv3/steer/2); both move the stream only on days and seeds the chain never reaches. THE FOURTH EXCEPTION ON THE RESTART STEP (the fast-time lane's held-miner run on the third pair 63524e28, 20:4xZ): the IBD catch-up's body sync anchored on the node's own sink and moved only on a whole chunk's successful join, so with the honest headers arriving as one chunk failing on its v5 tail it fetched nothing and the executor never reached the seed block; the relay hold-off and the mining hold from the earlier fixes read green on that run. FIXED by the node lane at f0c56f50 (the refused chunk split by consensus's own record, the anchor moved to the highest validated header, the honest v4 prefix through the seed block, only the unvalidated headers deferred; kaspa-p2p-flows 38). PAIR 4 = v5-object-0323 c8f9b383, re-archived from the frozen 1c420786 (generator.rs and accept.rs moved since ab6f980b, memhard.rs not), building on build-1 at gate priority since 20:54:32Z with the line's gates beside it; the restart step's PASS must come from pair 4; the object commit lands the minute it does, with dn3-g1's DAA at the cut plus 7,200 rounded up to the 3,600 boundary and its UTC clock named; the testnet lane told to pair its re-cut with 1c420786. The crossing clock is not yet a reading: about 22:15Z (23:15 BST) at the earliest if every line reads green on its first pass. The site audit lane: no other "12 days" form served; its row-17 edit keeps main's outside-check clause and adds the 5090 efficiency numbers. THE CHIP TEXTS, THE X9 WORDING RETIRED (main's order from the counter-asic-4 research file d7721ebe, 22:0x UK): the withdrawn Antminer X9's claimed ratio ("a third of a CPU's energy per RandomX hash") is against a CPU core (about 100 pJ per instruction, Horowitz and Dally, claimed), not a GPU lane (6.5 to 10.4 pJ measured), so a chip three times better than a CPU is worse than a GPU lane per op and the X9 is not a pessimistic chip core against us. The served texts (the home line, the litepaper's lead, chip table, ladder sentence and chip bullet, /claims through it, the miner line, evidence row 17) now give the floor and the premium as measured numbers at the 5090's knee: the chip at 2.1x per joule with a core as good as a GPU lane (k = 1) and 3.4x with one three times better (k about 0.33), no core below about 1.8 pJ per op in the model's range, the shadow's premium 81.8 W at the best points (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W against class v3 at 1,300 MHz 134.62 at 223.3 W, 7 October 2026), Ember Tune's core-clock knob named as how a user gets there; the ledger text check's pins X35 and X36 moved with the wording; no "3.9x" remains on any served page. One number stated against main's wording: main's line read "2.9x with one three times better", which in the research file is the figure for the RE-WEIGHTED op mix (row 3, held by the coordinator until the SM-sparse read); today's mix at a core three times better reads 3.4x in the same file, so the served text carries 3.4x and the 2.9x waits for the re-weight to ship. THE RESEARCH FILE's TWO ORDERS: (1) the texts as above; (2) one zero-code measurement at the PC 1 tail after the third 5090 pass: the 5 October hot-table packs (packs-ca2-hot, 32 and 64 MiB) with the worker's `--variant ldcs` (dataset loads streaming, evict-first; the hot loads plain and L2-resident) against base on the 5090, the rate ratio g and the watts (the 5 October rows without the hint g 0.84 to 0.87); the one class where a chip's cost per op (a 64 MiB SRAM read, 0.2 to 0.5 nJ approximate) may exceed the GPU's (an L2 hit, 0.1 to 0.3 nJ); Metal has no such hint. The shadow stays at rung 0; the op-mix re-weight waits for the SM-sparse read (the research lane's worker variants sp170/85/43/21/11-w32, one block of 32 warps per SM, run through the hash lane's efficiency script in its ca4 mode at 4f3a064e; the no-prompt and sequence rules hold by the same code). THE 0.3.24 PAIRING RULED (the shipper, 22:1x UK): the v5 object commit pairs with the frozen class-v5 1c420786 as it stands (the gates and the attack-pass lines run on it); the post-freeze fix 8ca66afa is 0.3.25's pairing. 0.3.25's FIRST ROW: class-v5 8ca66afa (both mirrors, 22:10 UK, on 1c420786): (1) AP-F4-1 in the agreed form (decc7c17): the day's draw rejected when cost A = 64 + sum(w32(MUL_i) - 1) is at most 205 against the median 226, w32 over bit positions 0 to 31 (the position-32 carry digit dropped), any MUL with w32 at most 3 rejected (k >= 1), the eight ROT all equal rejected, a rejected block redrawn whole from the continuing stream; known-failed first on chain day 29,337 (2050-04-28): the sub-version 3 block of that day read cost 203, rejected at 205 and redrawn under class v5. (2) Class v5's verified last resort: the rewrite, then repair_stale_loads (a stale load re-sourced to the lowest register written since its last load, to a fixpoint), then the whole rule over a 256-candidate scan from the cap; the unchecked fallback past the scan under 1e-300; known-failed first on adv-accept-3's adv3/steer/2 (the sub-version 3 rewrite fails part (a) at instruction 47 reading r3; the repair restores (a) moving only load sources; class v5's last resort passes at attempt 256, id 9b29c9481f6941d4; steer 11, 33, 56, 58 and 77 pass too); sub-version 3's path untouched. The stream moves only on days and seeds the chain never reaches: the pinned v5 packs byte-identical, the fingerprint 82b19cbde8557ea5 and the epoch-0 id e5a4ac5978462156 unchanged; the igneum-pow suite green on box 2 (74 unit, packs 20, derive 7, mixer 4, recheck 2, scratch 7), the gate GREEN at 58 checks. The harness's class-walk case (v4 floor 0, v3 never) read FAIL on the unfixed fork 546fe4b5 (the known-failed shape, 22:08 UK) and runs on pair 4. THE IN-HOUSE PASS, THE EIGHTH HOT SET (adv-accept, 22:06 BST, the wider sweep over 88,051 accepted programs): seed 122960 (id 4be7393ab6c84802, the lowest 256-unit ratio at 0.9885) reads live at 2^24 X_f +0.111 percent, X/f 1.11, 1.54x the window model, with the heaviest single item measured tonight (0x81ad88 at 475,616 reads, 0.022 percent of all reads, 16x 100767's hottest) from an all-ones source at instruction 4 (writer shfl at 3); site 12's saturated-source share 0.353 percent, a third of (c')'s limit; the other four lowest 256-unit proxies clean live, so the 256-unit proxy is noise at its own extreme and the 2^20 ratio is the selector; the tally 8 hot sets in 30 tail seeds against 0 in 20 random; the price unchanged (0.34 percent of reads on 1 MB, 1.002x); its minimum-site ratio at 2^20 against the 0.995 floor OWED (ordered first), deciding whether the freeze record reads eight of eight refused or names the first hot set the floor misses. THE 5080 AT STOCK (run-ca3-pc1-v4-eff-5080-20261007-b, exit 0 at 21:03:02Z, the card alone, 60 s, both fingerprints matched): class v4 71.43 MH/s at 255.1 W (0.280 MH/W, sm 2,958, mem 14,801 MHz); class v3 71.30 at 170.7 W (0.418); the v4 premium 84.4 W (49 percent over v3's draw), the rate 0.18 percent over v3; against the fleet's rented 5080 (71.16 MH/s at 143.4 W on class v4, driver 580) the rate agrees to 0.4 percent and the watts do not (255 against 143), a question to the fleet lane (its sampler, a cap on the rented card, the memory clock) before either row enters the public table; the lock grid did not run in -b (a PowerShell function defined below its first call left the script without the helper path; nothing set, nothing to restore), republished as -c at 21:07:10Z with the full grid (unlocked to 300 MHz, about 58 minutes). The site audit lane's row 17 and litepaper paragraph carry the 1,400 MHz rows labelled measured, with the best-points clause asked beside the 88 W at 1,400. THE 0.3.24 OBJECT COMMIT AND PIN: v5-object-0323 774f16c9 (21:26:35Z, both mirrors; the fork 432ea3d6 + f0c56f50 + 9ad1d9c6 + 294e3670 + the pool lane's 95ae3e50), paired with the frozen igneum-pow 1c420786: program_class_v5_activation_daa 28,800 (the Devnet 3 seed node at virtual DAA 16,208 at 21:22:24Z; the publish minute 22:30Z = DAA 20,264; plus 7,200 = 27,464; the next 3,600 boundary 28,800, epoch 8), byte 6 counted exactly, the window 86,400; the crossing on Devnet 3 by height about 00:52Z on 8 October (01:52 BST) at 1.0 DAA/s; the constant holds while the publish DAA stays at or under 21,600 (22:52:16Z), past which the node lane re-reads dn3-g1 and re-cuts to 32,400; chain id 4463 below the floor and 4464 from it; the three heights stay, the pool split never. Its gates: core 155 of 155, miner 28 of 28, pow 19 of 19, p2p-flows 38 of 38, exec 46 of 46, consensus 126 of 126 on the gate-priority rerun at 21:44:24Z (the earlier one red at 205 ms on the latency bound under a box load of 127, the known load class); the canary set on build-1 (21:29:38Z to 21:31:18Z): the digest moves to 4a284b1d on igneum-devnet-3 as the v5 arm requires, "this node stamps object version 6 into its headers (block version 1538)", the override file refused, two empty nodes handshake on 4a284b1d, the shared-devnet node refused on network mismatch, a 0.3.23 node refused on the digest both ways; every Devnet 3 node restarts inside one minute at the fleet's named clock on pre-placed binaries. release-0.3.24-node OPEN at 774f16c9 on both mirrors (21:45:19Z, the shipper's word), artefact /srv/artefacts/0324-774f16c9/node-lane (igneumd ed36f246...); the testnet staging 47b9b229 on the pin all green (consensus 134, core 175, exec 47, miner 28, p2p-flows 38, pow 19, digest b2e856ed). THE FAST-TIME GATE CLOSED: SUMMARY PASS (cross-c8f9b383-2) at 21:36:35Z on the matched pair c8f9b383 (igneumd f1b5b32c..., igneum-pow 1c420786), every check green, none skipped: class v4 sub-version 3 from genesis at rung 0; rung 1 by signal from epoch 6 at 21:29:39Z; class v5 by signal at byte 6 counted exactly from epoch 8 (DAA 480) at rung 1 at 21:31:33Z on 4 of 4 nodes, 9,985 bps, before the floor; the second rung at epoch 12 the rule's earliest allowed; 11 of 11 program ids equal to the CPU verifier's; 0 PoW rejections on the honest nodes; the stale node 69 of 69 refused; the restart step: n2 stopped at DAA 455, restarted on its own datadir at DAA 500 at 21:31:56Z, no lock fault, no IBD refusal, "class v5 catch-up done: 19 deferred headers validated after 6 s", nothing of its own accepted during the catch-up and 75 after, at n0's sink 12.1 s after its start; four sinks equal at 660; the digest-compat PASS from 20:08:30Z stands; records on v5-fasttime 4419e8d3. The three earlier pairs (959b57c9, 63524e28, 432ea3d6) each failed the restart step on a node defect fixed in the next (the IBD refusal, the catch-up's anchor at the node's own sink, the node mining while its catch-up waited). THE FLOOR READS EIGHT OF EIGHT (adv-accept, 22:41 BST): seed 122960 (the deepest live hot set) reads minimum site 12 at 0.9824 at the acceptance's 2^20 sample (live 0.9822), REFUSED by (c''') at 0.995 (its site 12 puts 1.31 percent of its reads on word indices read 8 or more times, the largest repeated-index share measured; 100767's site 6: 0.17); every live hot set by X_f at or above f found in the tail of 88,051 accepted programs is refused (minimum sites 0.9821 to 0.9919) against 0 hot sets in 20 random programs; the floor misses the three mild concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x; the v5 design's section 14 and the ledger's AP-F8-1 carry the line. THE 0.3.24 CUT waits on the attack-pass verdicts on 1c420786 alone (F8's two halves on build-2 since 21:17:41Z, about 22:20 to 22:35Z; F9 at 10^5 and F1 on build-1); the lease pool now pre-empts adv holders at any size for a v5 or release waiter after 120 s (lease ce30e357). PC 1 EXCEPTION: the Power Helper task dies within seconds of each start since 21:08:34Z (six starts, zero commands, the task Running while no helper process exists; the last good command the 20:45:52Z rgc, its idle exit clean at 21:05:52Z); the suspect the shipper's 0.3.23 host job at 20:51Z replacing the install folder's exe under the registered task, the second a panic in the helper's start path; a read-only diagnostic plus a 20 s unelevated probe placed; the locked grids (the 5080 full grid, the third 5090 pass), the SM-sparse job and the tunes wait on the helper; the lock-free jobs run (the 9070 XT G1 and ladder from 21:27:41Z, then the family run and the v5 AMD bench); nothing raises a prompt to get round it. THE 5080 AT STOCK (two runs agreeing, -b and -c): class v4 71.42 MH/s at 254.5 W (0.281 MH/W, sm 2,960, mem 14,801), class v3 71.30 at 170.8 W (0.418), the premium 84 W; against the fleet's rented 5080 (71.16 MH/s at 145.4 W busy mean, cap 350 W not binding, 1 Hz power.draw instantaneous on Linux driver 580, bench batches with host gaps) the rate agrees to 0.4 percent and the watts do not (110 W apart, the sampler field on Blackwell under two drivers or the load shape); the public table carries the method per row and takes neither as the card's figure until both power fields are sampled on both sides (the fleet's re-measure, PC 1's next NVIDIA pass). THE CA4 SECOND PASS (bca23f96, sections 15 to 19): the tensor-tile k column (2.1x at k = 1, 1.6x at k = 1.5, the k 0.3 column removed for a tensor shadow; a design candidate needing a SIMD byte-dot verifier) and the capex column (the f = 1 GDDR7 chip USD 2.8 per MH/s, at most 4.3 with the hot table, the shadow core and an interposer; capex-dominated 7x; the break-even cap moving only through the project cost) carried into chip-model-v3 as section 5.11. THE PUBLIC TEXTS (main's two orders, 22:3x UK): the served sentence "the one outside check is staged and waits on its escrow and the publish word" read as an escrowed prize to a reader and is replaced everywhere it is served (evidence row 17, the litepaper and /claims through it, the public text file) by "no outside review has run yet", the in-house pass sentence kept; the forbidden-strings gate gains the phrase class ("outside check", "waits on its escrow", "staged and waits", "the publish word"; the bare words stay allowed, since the proving pool's escrow and a staged build are ordinary). THE /miners DESIGN PASS is on the mirror's ca3-coord at e88edae4 with the full gate GREEN (the overlap check clean at 390 to 1600 px after two fixes: the phone grid gives every cell its own area; the desktop row is six columns with the class v4 cost and the date as the muted second line under the card name, the card layout below 1,100 px, the wrapper scrolling as a safety); the 1440 and 390 dark captures go to main for the word on the look; nothing deploys from the branch before it. The in-house pass: four lanes complete (adv-cache, adv-accept-2, adv-cache-3, adv-mixer; adv-mixer's Q1 BOUND on the commutation probe at 0 in 1,454,080,000 over 1,024 days, its SAT row a solver-reach bound at the one-hour cap); adv-mixer-2 one row from complete; adv-accept, adv-accept-3, adv-cache-2 and adv-mixer-3 sweeping to 00:00 BST. F8 ON CLASS V5: PASS (the attack-pass lane, 22:03Z; the frozen igneum-pow class-v5 1c420786, binary sha256 0f5c98dc41a1b3aa...; the pairing bit for bit on 66 validation lines, the library drawing Devnet 3's epoch-0 program as e5a4ac5978462156; 64 seeds p2 to p65 at 2^24 nonces each, chain path, the v5 dataset from v5-dn3-epoch0's state.igsd1 on day 20,733, window-model control, build-2 under lease pool class v5 as two halves of 32, ended 21:58:43Z and 22:03:21Z): 61 of 64 under 1.2x of the window model (0.9919x to 1.144x, p75 1.0024x); 3 over, all inside the named four-seed residue and none new: p10 1.5047x (hottest item 0x4018f5 at 346 reads of 2^31, no predicted source), p8 1.3787x (419 reads), p4 1.2166x (363 reads); p34 reads 0.9997x under the (c''') floor; every strong seed of sub-versions 1 and 2 at 0.9997x to 1.0001x (p23 1.0000, p19 0.9997, p15 0.9998, p18 1.0001, p56 1.0000); seed for seed the ratios equal sub-version 3's within 0.001 except where the floor moved a draw: the state leaves change the words, not the read addresses. F9 (10^5 exhaustion) and F1 (10^5 redundancy) on 1c420786 and F4's 2^24 on 8ca66afa hold or wait in build-1's pool as strengthening lines. THE 0.3.24 NODE PIN MOVED on the shipper's word to 47b9b229 (the object 774f16c9 plus the testnet re-cut 34892a36) after the Devnet 3 canary set read clean on its own binary (21:59:04Z to 22:00:43Z: digest 4a284b1d, byte 6, the override refused, shutdown 725 ms, the handshake, the shared-devnet dialler and a 2720d8d2 node refused); release-0.3.24-node at 47b9b229 on both mirrors (22:01:05Z), igneumd 6bc18ac2..., pairing 1c420786; the build-server lane builds the pairs and the hive from it; the Devnet 3 digest 4a284b1d, the testnet b2e856ed; the floor 28,800 and its slip rule, the dn3-g1 re-read armed for 22:30Z. THE AMD HALF OF G1 PAID (run-ca3-pc1-v4-sub3-amd-g1-20261007, exit 0 at 21:46:14Z, the RX 9070 XT alone): 14 of 14 fingerprints equal to the Mac's Metal and Apple OpenCL and to the 5090's (the control, the seven sub-version 3 packs, the five ladder packs), self-test PASS on all; the ladder rows flat within 2.3 percent from 930 to 330,700 ops per hash (18.8 to 19.2 MH/s; the installed worker's control cross-check 18.96), the card latency-bound on the whole ladder; the watts row owed (the ADLX sampler read 0 samples in the per-pack windows). THE HELPER FAULT READ: not the shipper's; the task's exe is the install folder's 0.3.20 (mtime 12:24:42Z, sha256 0443ae17..., untouched by the host jobs); the helper's code path runs (an unelevated probe answered a dev line in 4 s); the scheduler refuses the ELEVATED instance from a non-interactive start (Last Result 0x800710E0, the task's logon mode interactive only); at 21:41:32Z the 0.3.20 engine's own tune took its legacy "task not registered" branch (the old sweep.rs helper.ps1 written, cmd.txt truncated), the prompt path, so whether a prompt stood on the desk is for the founder's screen in the morning; the class (the engine's registered() check and its fallback, the scheduler's logon mode) is the update-return lane's for 0.3.24; the locked PC 1 jobs stay parked. THE CA4 PROTOTYPES (the research lane, counter-asic-4 6404f62b): two experimental classes behind the pack, no consensus change: +shlx (the shadow's 256 instructions and 27 passes split into 16 sub-blocks of 16, each run after its load) and +mm (R int8 mma u8 tiles per iteration after the shadow; CUDA native PTX, the shuffle reference on Metal and OpenCL; the verifier scalar plus AVX2, SIMD pinned equal to scalar on 64 seeds); the suite green (64 + 7 + 4 + 19 + 2 + 7), the pinned packs byte-identical; packs exported with every OVERALL PASS (mx8_sh256x27 control, mx8_shl256x27, mm128, mm512, mm1430 at 11,440 tiles per hash); their card rows on PC 1 behind the helper; by construction neither lowers the premium (the per-load placement moves the chip's capex, the tile block its k floor). THE LEDGER CLOSE landed the chip rows on the mirror's master at b94a77ad (22:56 BST): X35 and X36 restated, AP-F8-1 with the eight-of-eight sentence, X37 new (the class v4 premium: measured, levers in flight). THE RECORD LANDED (23:24 BST): the regroup 2336a3c5, the outside-check rewrite and chip model 5.11 (6c19c790) and the status 015cc839 picked onto ca3-coord-record from the mirror's master and merged as ddfaf7a7 through the gate (GREEN, 7 checks in 30 s on f252b514); the first pick hit the audit lane's best-points clause in the litepaper, claims and evidence pages and the resolution keeps master's text with only the escrow sentence replaced by "No outside review has run yet." (main: the right sentence); the design pass stays on ca3-coord for its own landing on main's word after the captures. ADV-ACCEPT-3 CLOSED (the v5 lane, 23:12 UK): 8ca66afa closes its class as stated (the 9.0 percent of rewritten 256th-attempt programs the rule refuses are repaired for part (a) and re-drawn under the 256-candidate scan; the known-failed test on adv3/steer/2, five more steer rows passing); ledger row AP-F8-3 written (sub-version 3's last resort recorded unreachable and unverified, class v5's verified) at class-v5 7f58af97 with the v5-kits branch merged (the OpenCL, NVRTC and Metal hosts with the leaves upload, the kit scripts); the kit zip rebuilt from the merged tip, /srv/artefacts/packs/packs-ca3-v5-20261007T221001Z.zip sha256 4aaf9b9edfad0e466f6b6b59051250afad6a8e0a340728ec068bec48113c0fc9, the packs and the fingerprint 82b19cbde8557ea5 unchanged; Metal, Apple OpenCL and CUDA agree; AMD and Intel fingerprints owed. A GAP: tools/ledger-page.mjs renders only [A-Z]\d+ ids, so no AP-* row (AP-F8-1 to AP-F8-4) reaches /ledger; the site audit lane widens the regex tonight as its own commit with a known-failed case. THE SPEC SPLIT: the site audit lane holds 1.4.3, 1.4.6 and 1.13 (the acceptance-rule rewrite on spec-accept-23) and builds tools/ci/spec-constants-check.mjs, a constants table in the spec parsed against the crate's pub consts (known-failed first) with the class v4 test vectors stated in 1.4.6, since the attack-pass lane has no read-back test and writes none; the hash lane sent it the file and line of every constant from 017e7037 (= master's igneum-pow byte for byte, cf7d6ccb) plus ACCEPT_TAG, the window cap literal in distinct_ratio_pass and the full Devnet 3 genesis hex, no wrong values, one text quirk: the (c) reject prints "limit 163" while MAX_SATURATED is 164 (the first refused count); main's ruling: the spec words the constant, the message string is corrected on the post-freeze line, never in the frozen 1c420786. The v5 lane's 1.4.7 and 1.8.6 are on both mirrors at class-v5 73daadc2 (23:23 UK; full gate GREEN 58 checks at 066c9cbb): class v5's load class, generator 5 and the id, (c''') with the 0.995 floor and the census, the verified last resort, AP-F4-1 and AP-F1-1, the activation object byte 6 and the seven-window 95 percent signal, the test vectors (the three pinned packs, seed 100767, day 29,337, adv3/steer/2), 1.4.7.6 the constants table in the audit lane's shape (Constant, Value, Where); the state leaves (IGSD1 stream, leaf derivation, keyed sample, the leaf line before M_0, the per-epoch refresh and the witness, the measured cost). THE ERA-DRAW MECHANISM (the crypto lane's adv-cache-2, 6e34ebe3, 23:1x to 23:3x BST; report-chained-cache-2.md section 2.3, the 61-program table: 2 real, 27 drawn-era with epoch and era hex, attempt, id, R, site and ratio, 32 devnet-era controls): the mild residual class has its mechanism; a product's biased low bits (P(bit 0) = 1/4, measured exactly) survive the odd stride multiplier and the stride rotation places them at address bits R and up, inside the 28-bit item index unless R is 28 or more; the devnet era draws R = 29 and cuts them off, so 2 of 32 devnet-era programs carry a site over 1.04x while 13 of 27 drawn-era programs (R 3 to 22) do, 8 over 1.2x, worst era-drawn-28 site 15 at 1.7451x and era-drawn-25 site 11 at 1.3571x; under the 2 GiB genesis dataset (D = 29) R = 29 would show it too; the devnet's cleanliness is an era-draw accident, the chain prevalence is the drawn-era figure. The price to a partial-store chip stays under 0.1 percent of a hash's reads per site, so no chip number moves. Disposition: the class v5 (c''') census was already across drawn eras (each of the 4,600 f8 seeds carries its own era bytes), so the 2.435 percent and the eight of eight stand; the pointed reading runs on box 2 (the v5 lane, about 20 minutes from 23:3x): the 2^20 floor read on the 27 drawn-era programs plus era-fixed-20 and four devnet controls, reporting how many of the eight over 1.2x and the band 1.04x to 1.2x the 0.995 floor refuses; the value-level question (biased product bits feeding an address, independent of the distinctness ratio) and the era draw's R range go to the CA4 file as a named requirement with this reading as its evidence, and the research lane's per-load census gains a drawn-era split; nothing in class v4 or v5 moves without main's word. THE ATTEMPTS CENSUS on the frozen sub-version 3 rule (adv-accept row 90, 23:24 BST, 10,000 seeds): 21,119 rejected candidates, by first failing part (a') unfresh 83.3 percent, (a) stale 11.7, (b) no injecting write 3.1, (c'') low-entropy site 1.1, (c) constant bit 0.4, (c) saturated 0.3, (c') 0.1, the distinct-address floor 0.04, lane-constant and bias 0; per-candidate rejection 0.6787, flat at 67.5 to 68.7 percent over attempts 0 to 3 (independent draws); accepted-attempt mean 2.112, max 24; 0 exhaustions; P(256 consecutive rejections) 8e-44 per seed, so the last-resort draw is unreachable by chance and the attempt index is no lever for a seed-steering attacker; accepted programs' distinct-item mean 127.95 of 128, minimum 123.67; spec 1.4.6's 5.14 percent (the class v3 census) is stale against it, the audit lane rewrites; the second 10,000 queued on build-1. Also PASS: the line census at 2^35 + 3 x 2^33 and the 16,384-day weak-day scan. THE PC 1 QUEUE TONIGHT (the hash lane): run-ca3-pc1-amd-family-20261007-e exit 0 at 22:09:25Z (the 9070 XT alone, gfx1201, driver 3683.0, 32 CUs, three runs every row exact against the alu chain; step costs as a ratio to alu 741 G steps per second: rotr 1.05, shflx 0.89 (bperm native), shl 0.92, shr 0.99, bfe 1.03 native and 0.83 C sequence, andn 0.93, perm 1.21 emulated (perm_amd refused), popc 0.85, clz 0.83, sel 0.72, shfla 0.77 (bperm), dot4 0.75 native (dot4_khr refused), mm8 1.20 (gfx12 path, unverified); the khr and intel shuffle builds refused as on 6 October); the shipper's 0.3.24 host slot holds PC 1; on its "slot closed": fetch-ca3-v5-kit-20261007 (the 4aaf9b9e zip), then run-ca3-pc1-v5-amd-bench-20261007 (the v5 lane's script, the 9070 XT by name, beside the miners, about 3 minutes), lock-free and non-elevated, quiet. The Intel fingerprint: main first routed it to PC 1, the hash lane's device lists (the 22:09Z --list, the kit README) show no Arc on PC 1, and main's second word places the Arc B580 as PC 2's eGPU (tonight's PC 2 crash was an Intel driver install over that card while it mined); the job (tools/class-v5/pc1-intel-v5-bench.ps1 at a4b08245) moves to PC 2 by job after the shipper's 0.3.23 take 3 smoke and the update-return lane's scheduler proof have reported on that box, never concurrent with an install or a build there, the same lock-free class; a fingerprint that differs from 82b19cbde8557ea5 holds that card's v5 kit out of 0.3.24 and the crossing time is stated on its page row. PC 2 carries the RTX 5080 since about 15:00Z (tonight's stock row is that card). THE HASH LANE'S LANDING (the derivation fix, the no-prompt rule, the PC 1 job scripts, the Ember core-clock knob 74585c91: the ladder below 45 percent in 100 MHz steps to a 20 percent floor, the stop rule at the knee or on a faulted row, lock_result and the card's lock_* fields, 18 Ember tests and the app crate's 158 green on box 2, the 1 percent tolerance landing the 5090 at 1,854 MHz on tonight's rows and 1.5 percent at 1,300, the tolerance the manifest's; ledger row AP-F8-4) went RED once on the pre-public scrub (the founder's name in a ledger row and two script comments), fixed, the mirror's master merged in again, the gate rerunning from 23:2x; the merge commit follows. THE FLOOR'S FULL TALLY (adv-accept gap-deep4, 23:25 BST): the four deepest remaining 256-unit seeds all read under 0.995 at the acceptance sample (148927 at 0.9814, 150347 at 0.9896, 34501 at 0.9929, 29307 at 0.9912); the first three clean live (0.9998x to 1.0028x), 29307 at 1.29x on one item from a non-saturated source, no hot set by X_f. Over everything the lane read at 2^20: 8 of 8 live hot sets refused; 6 clean-live programs refused (false refusals) and 1 clean passed among the 9 deepest 256-unit seeds; 3 mild residuals missed at about 1.0004x. The lane's reading of why both sides exist: (c'') counts repeated word indices on the stand-in, which the live set usually spreads thin rather than concentrating, so a low ratio is not a hot set; that is the 2.4 percent clean rejection the floor pays, and a true hot set needs the value-level source test to be caught without it (the CA4 requirement). THE SPEC REWRITE committed on spec-accept-23 (the audit lane, 23:3x UK): 1.4.3 and 1.4.6.1 to 1.4.6.6 to the shipped rule at 017e7037, the shadow block in 1.7, the ninth era draw in 1.13.1, ledger AP-F8-5 (the stale spec text) with the public ledger regenerated, the two tables in the check's shape (Constants of the shipped rule: Constant, Value, Where, 17 rows; Pinned program ids: Seed, Attempt, Id, Note, 6 rows with Devnet 3's full genesis hash and the three must-differ ids); the full gate running; it merges the mirror's master after the hash lane's landing so the check and the text arrive together. THE PER-LOAD FIX (the research lane, counter-asic-4 2f718001, pushed 22:24Z; the fixed pack mx8_shl256x27_v2 22:29Z, attempt 3, id bd64b207a30413fb, the first export 854050a4293f0615 kept as the known-failed record): known-failed first at 22:16Z (tests/ca4_trace.rs on build-2): the first export derived 10,728 distinct items of 12,288 over three units (the class v4 shape 12,286), 1,482 same-iteration duplicate lanes at sites 8, 10 and 15; the mechanism from the 64-seed census (29 of 64 seeds failing, up to 620 duplicate lanes a seed, sources collapsed to 1 to 17 distinct values in 32 lanes): a lossy base writer (mulhi, mul, or) followed by 27 passes of the 16-instruction map collapses the register before the next load, so the static last-writer rule catches only part of it. The fix in two layers: the static redraw (a sub-block writer of the next load's source drawn from the injecting families when it is mul, mulhi or or) and the dynamic acceptance test stepping the per-load sub-blocks in the order the class executes (accept.rs alu_step inside run_unit) with a new rejection DuplicateLanes (any load reading one address in two lanes of a unit), a rejected candidate redrawing the attempt. After, 22:23Z: 12,287 of 12,288 and 0 duplicate lanes on the genesis seed; the census (64 seeds x 2 units on a second dataset, 16,384 load rows) 1 duplicate pair in all (seed ca4-census/49 site 3, the chance floor of a 2^24 index space, about 0.5 pairs expected; the class v4 shape's own trace shows 2 of 12,288 from the same floor); the suite 64 + 2 + 7 + 4 + 19 + 2 + 7 passed on build-2. Owed: the Metal fingerprint (the Mac, one at a time under the measure lock), the F8-form uniformity on the fixed export through the attack-pass harness, the drawn-era split of the census (R 3 to 22 against 28 to 31) and the biased-low-bits requirement row from adv-cache-2, the PC 1 card row on both exports. Nothing in class v4 or v5 moves. THE "LIMIT 163" FIX (the hash lane): the one-line fix on a post-freeze branch off the mirror's master, pow-reject-text-24 at 79c5c07d (pre-push GREEN): the (c) saturated reject text prints its limit as MAX_SATURATED - 1 and names 164 as the first refused count, with the test the_saturated_reject_text_prints_its_limit_from_the_constant reading the printed limit back (green on box 2); the frozen 1c420786 line untouched; it lands with 0.3.25's line. The derivation fix's landing: the second gate run RED on the public-ledger check (AP-F8-4's last paragraph must start with one of the six status words), the row now closing "Status: Fixed (7 October 2026, night)" and docs/ledger-public.md regenerated; the third gate run from 23:3x UK. PC 2's Intel job prepared as run-ca3-pc2-v5-intel-bench-20261007 (the kit fetch to PC 2 first) behind the shipper's "PC 2 clear"; the CA4 packs job on PC 1 runs both per-load exports (dir and id on every row). THE FLOOR RE-CUT (main's ruling, the shipper 23:3x UK): the 28,800 floor lost to the clock (the pairs, the hive kits, the fleet's fetches and the ten minutes after the last FETCHED cannot land before 23:52 BST, past the 22:52:16Z slip point), so the node lane re-cuts program_class_v5_activation_daa to 32,400 (epoch 9) on release-0.3.24-node, the same object otherwise (pairing 1c420786, chain id 4464 from the floor, the testnet re-cut inside); the new pin and its gates about 25 minutes from 23:3x; the crossing on Devnet 3 by height then about 01:52Z on 8 October (02:52 BST) at 1.0 DAA/s; the move minute after F9 and F1 PASS and the last FETCHED. THE ERA READING ON THE FLOOR (the v5 lane, box 2, 23:3x BST, igneum-pow at 73daadc2, the 2^20 acceptance sample): 0 of 29 of adv-cache-2's programs are refused by the 0.995 floor at their listed attempt, and the class v5 draw lands on the same attempt as class v4 for all 29; the six over 1.2x read minimum sites 0.9965 to 0.9997 (era-drawn-15's 1.51x site 14 at 0.9965 the lowest), the 1.04x to 1.2x band 0.9986 to 0.9998, the clean ones 0.9999 to 1.0000, the devnet-era controls 0.9996 to 0.9999. So the floor's statistic does not reach adv-cache-2's class: the distinct-index count at 2^20 reads concentration on FEW items (adv-accept's hot sets put 3 percent of a site's reads on 512 word indices, moving the collision count by thousands), not a diffuse excess over the top 0.1 percent of items (era-drawn-15's 1.51x is about +0.08 percent of the site's reads spread over 16,384 items, a few hundred collisions, inside the clean spread). Two classes, two instruments: the floor closes the few-item hot sets (8 of 8); the era-stride diffuse class needs the per-site item-share test at live scale or a draw rule on R and the shadow block's last write (the next class's row); its chip value is bounded by its own diffuseness (a 1 MiB hot table of the top 0.1 percent of items serves about 1.0024x at the worst site read so far, under the AP-F8-1 bound by an order). The v5 design's section 14 gains this paragraph with the 61-row log (era-drawn-25 to -28 and the 32 controls running; era-drawn-28 at 1.75x the one to watch) and its bound sentence corrected (the "top-0.1-percent share under about 1.3x" form, never served, lived in section 14 only); a ledger row for the miss asked. Nothing in the freeze moves. MAIN'S ROW WORDING for Devnet 3: a 0.3.23 node that has not updated falls off at the digest move minute (the fleet's named minute, about 00:52 BST at the latest), not at the 02:52 crossing; the row reads "update before or the node stops following Devnet 3; class v5 begins at DAA 32,400, about 02:52 BST". F4 ON CLASS V5 PASS (the attack-pass lane, 8ca66afa, build-1 under class adv, 379 s, ended 22:3x UTC; the agreed w32 convention, median 226, 2^24 chain days from 20,729): M1 0 of 2^24 days over 1.1x, the minimum cost 206 (day 27,016, 1.097x), so the bound holds with no margin and no day over the line, mean 225.79, sd 6.07 (the pre-rule census 5.69e-4 over, min 203); M2 0 days with k >= 2; day 29,337 redrawn under the rule (203 to 228), day 20,729 at 219 unchanged; AP-F4-1 FIXED-AND-PASSED; F9 and F1 under class release on build-1, lines within the hour. THE CA4 FILE (the research lane, 22:3x UTC, sections 20.2a and 20.2b): the drawn-era split of the per-load census: 16 eras over the fixed class, 2 units each, R under 28: 12 eras, 3,072 rows, 0 duplicate pairs; R 28 and up: 4 eras, 1,024 rows, 0 pairs; every era accepted at attempt 3; the adv-cache-2 reading written as a named requirement (value-level bit-bias of the index at a product-sourced site, judged across drawn eras split by R, owed for every CA4 class and the same item as class v5's acceptance; the per-load dynamic rule covers distinctness, not bias). Metal fingerprints (22:30 UTC, M5 Max under the measure lock): the fixed per-load pack ee5d7c71180e5ea7, vectors 3 of 3, 26.88 MH/s against the control's 27.01 (the placement costs Apple nothing); the tile packs bit-exact against the Rust verifier on the Metal reference path (mm128 270e4ae36b37e9a1, mm512 a1c1ff3148d775d1); the Apple cost is the finding: 1,024 tiles per hash take 35 percent of the M5 Max's rate, 4,096 take 78 percent, so a tile shadow at the ALU shadow's premium would take the Apple tier out unless Metal gains an integer matrix path; the tile class moves from rank 3 to beside rank 5 until that path is measured. Main's rule: no served number mentions the per-load fix before its F8-form uniformity and drawn-era split (the split now read; the uniformity owed). THE PUBLIC SENTENCE ON THE FLOOR (main's wording, 23:3x UK): "eight of eight hot sets refused; the diffuse era-stride excess, bounded under 0.1 percent of a hash's reads per site, is not caught by the floor and is the next class's test", the same words on ledger row AP-F8-1 (landing from ca3-coord-record 6d09d96e with the two-instrument reading and the AP-F8-6 pointer), on AP-F8-6 and in the v5 design's section 14 (the v5 lane, class-v5 54e52b8a at 23:36 BST carrying AP-F8-6, F4's PASS in the attack row and its clock corrections: build-2 prints CEST, every page time re-read to BST); no served page carries a hot-set sentence tonight, so the sentence reaches readers through the ledger once the AP-* regex fix lands. F4's no-margin hold (the minimum accepted cost 206 against the 205 bound at day 27,016) is a record sentence, not a served number. ADV-MIXER-2 CLOSED (the crypto lane, 2a632579 on build/adv-mixer-2, 23:37 BST; 0.31 box-hours, 0 pod-hours): the redraw rule (continue the stream and redraw all 40 draws when the LUT cost A is 205 or less, or a 2-adder MUL, or all ROT equal) over 2^24 and 2^28 days leaves 0 days over 1.1x; 6.0e-4 of days redrawn once, 3e-7 twice, never three times; the mean cost unchanged; verdict BOUND for every chip, GPU and the verifier (gain 1.0 every day at 9,360 ops per item), FINDING on the per-day FPGA LUT-area reading only (2^-10.8 of days over 1.1x, worst 28 April 2050 at 1.113x), closed by the redraw rule or by the spec's O-1.10 day derivation; five lanes closed (adv-cache, adv-accept-2, adv-cache-3, adv-mixer, adv-mixer-2), four to the 00:00 reading (adv-accept, adv-accept-3, adv-cache-2, adv-mixer-3). THE HASH LANE'S BRANCH ON MASTER: da2fc101 at 23:37 BST (ca3-v4-amend a7ff10a2; the full gate GREEN, 69 checks in 351 s): the derivation fix with AP-F8-4 and the regenerated public ledger, the no-prompt rule (publish-jobs.sh refuses --elevated; playbook-quit-check rule 3), the PC 1 and PC 2 job scripts, the Ember core-clock knob for 0.3.24 (ember.rs, state.rs, engine.rs; 18 Ember and 158 app tests green on box 2), the ca3-v4-uniform parallel census; igneum-pow against 017e7037 differs in generator.rs (the recipe refactor, every id and pin unchanged), emit.rs (the one print) and tests/derivation.rs only; the shipper's tip for 0.3.24's engine work is this master. THE 0.3.24 NODE PIN RE-CUT (the node lane, every gate green at 22:39:31Z): c9e385eb on release-0.3.24-node (47b9b229 with Devnet 3's class v5 floor at 32,400, epoch 9, the same object otherwise; pairing 1c420786): build 22:34Z rc 0 (igneumd 7a841b20..., /srv/artefacts/0324-c9e385eb/node-lane), consensus 134 at gate priority, core 175, exec 47, miner 28, p2p-flows 38, pow 19; the Devnet 3 canary set with the new digest d0d6a4754f3bfc4a173aeaddbab0e151583047283932b70cbb8e27878c115e91 (byte 6, override refused, handshake, the shared-devnet dialler and a 2720d8d2 node refused); the testnet canary on b2e856ed unchanged. The floor from the 22:30:17Z read (DAA 20,268, 1.0 DAA/s): about 01:52:29Z on 8 October (02:52 BST), holding for a move minute up to a publish at DAA 25,200 (23:52:29Z, 00:52 BST). The fast-time SUMMARY on c9e385eb asked; the fleet lane asked whether its hub or any reader depends on build-1's three old-object Devnet 3 nodes (the seed on 27632, the observer node, node1), whether they join the move or retire, and which 0.3.24 node the DAA is read from after it; the crossing read at 32,400 and the TESTNET_PARAMS v5-at-0 re-cut follow on that node. THE FAST-TIME GATE ON THE RE-CUT: SUMMARY PASS (cross-0324-c9e385eb) at 22:49:32Z (23:49 BST) on the shipped 0.3.24 re-cut c9e385eb (igneumd 7a841b20..., igneum-miner 1e209b9e..., igneum-pow at the freeze 1c420786), build-1 under lease pool class v5, 22:36:25Z to 22:49:32Z, every check green: rung 1 by signal at epoch 6 (22:42:54Z), class v5 by signal at byte 6 from epoch 8 at rung 1 (22:44:54Z, 4 of 4, 9,985 bps), 11 of 11 ids equal to the CPU verifier's, the stale node 86 of 86 refused with 0 accepted after the first refresh, the restart step across the boundary on a kept datadir resynced in 28.1 s with the catch-up done after 10 s and 0 of its own blocks during it, four sinks equal at 660, honest nodes 0 PoW rejections; record on v5-fasttime 76276be6, docs/design/class-v5-harness/fasttime/cross-0324-c9e385eb.json. The 0.3.24 move's gates left (the shipper's correction of this record): not F9 and F1's full 10^5 PASS (landing about 00:40 BST, too close to the 00:52 ceiling) but an F9/F1 interim line from the attack-pass lane read inside the five minutes before the minute showing 0 exhausted, 0 panics and 0 redundancy failures over everything drawn so far (16,003 seeds at 23:35 BST, max attempt 25), any non-zero holding the move, the full 10^5 the record line after; the minute named by the fleet on the last FETCHED plus ten once the build-server lane's c9e385eb pairs land. THE 61-ROW ERA READING (the v5 lane, box 2, 23:4x to 23:5x BST, docs/design/class-v5-harness/v5-listed-adv-cache-2-full.log): 0 of 61 refused by the 0.995 floor at the table attempts (the two real programs, 27 drawn-era, 32 devnet-era controls), every class v5 draw on the class v4 attempt; era-drawn-28 (id 5e9eb01efbbf653e, attempt 6, R 15, the worst of adv-cache-2's census at 1.7451x) reads its biased site 15 at 0.9969, over the floor by 0.0019; era-drawn-25 (1.3571x, R 21) site 11 at 0.9994; the eight over 1.2x span 0.9965 to 0.9997 while the eight few-item hot sets sat 0.003 to 0.013 under the line. Main's sentence opens AP-F8-6 and section 14 verbatim with the two-instrument reading under it. THE CLASS V5 ATTEMPTS CENSUS for 1.4.7 (1,000 f8 seeds through the chain draw, v5-attempts-census-1000.log, the crypto lane's form): 3,219 candidates, 2,219 rejected, per-candidate rejection 0.6893 (sub-version 3: 0.68), accepted attempt mean 2.219, 0 exhaustions, P(256 consecutive) 4.4e-42; first failing part (a') 83.4 percent of rejections, (a) 10.7, (b) 3.0, (c'') 1.2, (c''') 1.0 (0.7 percent of candidates, one in 140: the floor's own share, 0.045 on the attempt mean), (c) 0.7 together, (c') none; the 5.14 percent of class v3 that 1.4.6 quotes is the audit lane's to replace. Both on class-v5 at 3b1dffd6 with main's sentence (891dd008), the mirror's master merged (e0471019: AP-F8-1's update and AP-F8-4 taken, the program-id recipe form with the state tag, no conflict), the design page's pre-public scrub (the founder's name six times, gone), M35's status word and the regenerated public ledger; the push waits on the full gate and the pinned-packs test on the merged tree (the proof that e5a4ac5978462156 and the other ids still derive under master's recipe form). THE 00:00 BST READINGS (the crypto lane; the verified roll-up of all nine lanes in section 13 of in-house-pass.md on crypto-engage, every branch tip read from the mirror and igneum-pow identical to 017e7037 on each). adv-accept, tip a7c49399 (about 5.5 box-hours, 0 pod-hours): 182,646 distinct accepted programs drawn (18 percent of the 10^6); eight pass every part of the frozen rule and flag the live hot-set test at 2^24 (X at 0.1 percent +0.102 to +0.221, 1.54x to 2.24x), all in the lowest 34 stand-in-ratio seeds against 0 in 20 random; each about 1 MB of items holding 0.26 to 0.41 percent of reads, 1.002x at the largest; the mechanism a near-saturated source at one site mapped by the era stride to one fixed item (plus two lesser shapes); the exemplar reads the same under the class v5 dataset. Against the class v5 floor: 8 of 8 refused; 3 mild residuals missed (adv-cache-2's rotation class, a load_index question not a floor question); 6 clean programs refused among the 9 deepest (the 2.4 percent). Q2 BOUND (54 programs plus 17 reads, 0 disagreements). Row 90: 0.6787 per candidate, (a') 83.3 percent, 0 exhaustions, P 8e-44. Partial named: 18 percent of seeds, 54 live rows, row 90 at half; a longer pass adds rows of the same shapes, not a different answer, unless a seed reads a hot set over 1 percent of reads, which 182,646 draws did not produce. THE PER-LOAD CLASS CLOSED (the research lane, for main; clock readings UTC): the per-load shadow fix held for distinctness and then met the value-level requirement from adv-cache-2, and the construction did not survive it; the per-load 16 x 27 class is dead as a chain class. 22:44 the attempt verdicts on four seeds (igneum-genesis 0 of 32 accepted); 22:47 the 64-seed census under the full rule (duplicate lanes at a load row plus the one-count of every index bit per site over the 64 units, 6-sigma band): 22 of 1,621 candidates accepted (1.4 percent), 42 of 64 seeds exhaust the chain's 32 attempts (an epoch without a program); the first failing test per candidate: biased index bit 775, duplicate lanes 643, the base rule 110, (b) 43, (a) 28; candidate 0 of the class carries index bit 0 set in 40 of 1,024 addresses (z 29.5); 22:52 the suite green (64 + 5 + 7 + 4 + 19 + 2 + 7); the acceptance rule with BiasedIndexBit for this class and the tests pushed as the record, the file's 20.2a closed. The structural reason: 27 passes of a 16-instruction map right before a load is an iterated small function and collapses or biases the load's address register before any base instruction re-randomises it; the class v4 shape has 64 base instructions and 16 loads between its block and every load. Both exports were accepted only because the rule did not model the placement; their PC 1 rows stay as an energy reading of the placement, labelled unsound. Rank 4 and the USD 200 M capex row rest on a construction not shown to exist (chip model 5.11's clause marked so in this landing); the sound form is one pass of a 432-instruction sub-block per load (a program segment, not an iterated map), a new class to draw, accept and measure, not tonight's. Replicated by a second instrument: the class v4 shape on this pre-amendment generator carries the adv-cache-2 product bit at address bit R exactly in 14 of 17 drawn eras (one-count 250 or 780 of 1,024, z 15 to 19), 0 duplicate pairs across the eras. What stands from the two prototypes: the tile block (bit-exact on the Metal reference, the AVX2 verifier at 0.047 us per tile, the Apple emulation cost 35 to 78 percent) awaiting its 5090 rows; the per-load placement closed. THE SPEC REWRITE ON MASTER (the site audit lane, 8b834634 at 23:56 BST; gate GREEN on 64e2a91b, 71 checks; the igneum-pow suite green on the box for that commit with derivation.rs and spec_readback.rs): spec 01 sections 1.4.3 and 1.4.6.1 to 1.4.6.6 rewritten to 017e7037 with the 20-row constants table (ACCEPT_TAG, the window-cap literal, MAX_SATURATED as the first refused count with the 163 message noted) and the 6-row pinned-ids table with Devnet 3's full genesis hex; the shadow block in 1.7; the ninth era draw in 1.13.1; tools/ci/spec-constants-check.mjs in the gate (known-failed first, every Constant | Value | Where table, pending rows skipped while absent); igneum-pow/tests/spec_readback.rs (ids derived through the crate, each class v4 row drawn to its attempt); ledger AP-F8-5 after AP-F8-4; the ledger-page fix (both heading forms, the pass as its own section, known-failed self-test in the gate; AP-F8-1, AP-F8-4 and AP-F8-5 render on /ledger); the fud-ledger's two prize clauses and "paid independent cryptanalysis" removed at the source so the regenerated page carries neither (commit 90424d5a, merge 64e2a91b). A HARDWARE FACT IN DISPUTE, for main: tonight's 5080 efficiency rows came from PC 1 jobs (run-ca3-pc1-v4-eff-5080-20261007-b and -c), the audit lane's record reads the RTX 5080 and the Arc B580 on PC 1, the hash lane's 22:09Z device list on PC 1 shows the 5090, the 9070 XT and the 4070 only, and main places the 5080 and the B580 on PC 2; identity-check.sh's "PC 2" substitution text names cards and is left card-free until the PC 2 job's own --list settles which cards sit where. THE IDENTITY CHECK'S PC 2 TEXT (the CI steward, 00:05 UK on 8 October): tools/ci/identity-check.sh rewrites "PC 2" card-free as "the second Windows rig" (commit 40f2be54, merge 0d2cf334, gate GREEN 71 checks, identity grep 0 hits over 306 export files and 52 served pages); line 69's PC 1 list untouched; the reason recorded in a bash comment above the perl call. THE 32,400 FLOOR LOST (the node lane, 00:0x UK on 8 October): dn3-g1's chain read DAA 25,126 at 23:52:03Z and 25,169 at 23:52:38Z, so the publish DAA passed 25,200 at about 23:53:09Z with no 0.3.24 move made (build-1's three Devnet 3 nodes last restarted about 21:31Z on the 0.3.23 move; the old seed holds 38 peers on ba75bf6f; no move minute was named). The next boundary is 36,000 (epoch 10), about 02:52Z on 8 October (03:52 BST) at 1.0 DAA/s, holding for a publish up to DAA 28,800 (about 00:53Z, 01:53 BST). Two routes put to the shipper and main: the same re-cut script on release-0.3.24-node (program_class_v5_activation_daa 36,000, nothing else, the same gate set, about 20 minutes to the pin line), or the fleet names its minute first and the floor is cut from it in one go (publish DAA plus 7,200 to the next 3,600) instead of a fourth chase; the pin c9e385eb stands meanwhile. THE FLOOR RE-CUT FROM A NAMED MINUTE (the shipper, 00:1x BST on 8 October, under the slip rule main set with the object commit): the floor re-cuts once more to 39,600 (epoch 11, about 04:52 BST) from a move minute the shipper named: 02:00 BST on 8 October, or the fleet's last FETCHED plus ten if later but before 02:53 BST (DAA 32,400, the ceiling); the node lane's pin line in about 20 minutes with the new Devnet 3 digest; the F9/F1 interim read at 01:55 BST; the publish minute equals the move minute (the apps' entries at or after it); the fast-time SUMMARY PASS reruns on the new pin as part of its gate set; the cause of the lost floor named: the c9e385eb pairs and the two PC jobs unreported for forty minutes, so the fleet had nothing to point its move file at. "slot closed" on PC 1 still waits on the host job's exit. THE 0.3.24 NODE PIN AT 39,600 (the node lane): dfbd1e10 on release-0.3.24-node (both mirrors, 23:54:13Z) = c9e385eb with program_class_v5_activation_daa 39,600 (epoch 11), nothing else; pairing igneum-pow 1c420786; every gate green at 00:01:52Z (build 23:56Z rc 0 at gate priority, igneumd 4870ccf2..., igneum-miner aa8c2978..., /srv/artefacts/0324-dfbd1e10/node-lane; pow 19, consensus 134, p2p-flows 38, exec 47, core 175, miner 28); the Devnet 3 canary set (23:56:33Z to 23:58:13Z): digest b1ba78229b069dc395fa666638a686a66615eb760d251798adfa6a654a415f82 on igneum-devnet-3 from ba75bf6f, object version 6 stamped (block version 1538), the override file refused, shutdown 2,015 ms, two empty nodes handshaking on it, the shared-devnet dialler rejected, a 2720d8d2 node refused on the digest both ways; the testnet canary b2e856ed unchanged (byte 7, a live old-object testnet node refused). The cut's read: dn3-g1 at DAA 25,169 at 23:52:38Z (1.0 DAA/s), the publish DAA at the named minute 01:00Z about 29,211, plus 7,200 = 36,411, the boundary 39,600 about 03:53:09Z on 8 October (04:53 BST), holding for a publish up to DAA 32,400 (about 01:53:09Z, 02:53 BST). The one gate running: the fast-time pair on dfbd1e10 (about 13 minutes from its start). c9e385eb is void as a pin; the F9/F1 interim read armed at 00:55Z. THE TWO PC QUEUES AT 01:03 BST (the hash lane): PC 1's "slot closed" has not come (the shipper's 0.3.24 host job, the build-server lane's, took the slot at 22:13Z for an expected two to three minutes; nothing reported in 110 minutes); nothing of the hash lane's has run on PC 1 since 22:09:25Z; the v5 kit fetch and the 9070 XT v5 bench are prepared and unpublished (tools/ca3-v4-amend/pc1-publish-20261007.sh, steps v5-kit and v5-amd), so no 9070 XT class v5 fingerprint exists yet; the lock protocol holds unless main says the lock-free pair goes ahead of the silent host job. PC 2's "clear" has not come either (the 0.3.23 take 3 smoke and the scheduler proof unreported by either lane); the Intel job is prepared and unpublished. THE HARDWARE FACT, read from tonight's PC 1 lines: nvidia-smi on PC 1 lists GPU 0 RTX 5090 (bus 01:00.0) and GPU 1 RTX 5080 (bus 0D:00.0); its OpenCL list carries the RX 9070 XT (gfx1201) and the integrated gfx1036 and no Intel platform; so the 5080 is on PC 1 (the audit lane's record right, the 22:09Z device-list summary short by one card) and the Arc B580 is not, which agrees with main's word that it is PC 2's eGPU; the kits row, the bench notes and identity-check's card-free PC 2 text stand on that. The locked PC 1 jobs stay parked (the 5080 full grid, the third 5090 pass, SM-sparse, the microbench and packs knee states, the two Ember tunes, the hot-table ldcs rows); the lock-free CA4 rows queue after the v5 bench on the same "slot closed". THE 00:00 BST READINGS, THE OTHER THREE (read by the crypto lane from each branch's report on the mirror at 01:03 BST; the roll-up section 13 of in-house-pass.md at crypto-engage c84ba51b with adv-accept's reading at 1b4e07ff; all nine branch tips read back from the mirror and igneum-pow IDENTICAL to 017e7037 on every one: adv-mixer d2ba3134, adv-mixer-2 2a632579, adv-mixer-3 4ebe2455, adv-cache 555c3e42, adv-cache-2 9384ee09, adv-cache-3 9452c0bf, adv-accept a7c49399, adv-accept-2 92168536, adv-accept-3 0c150e3c). adv-accept-3 (exhaustion or steering of the draw), tip 0c150e3c, every sweep ended 23:05 BST, about 3.3 box-hours, 0 pod-hours: Q1 exhaustion BOUND (per attempt accept 0.323, reject 0.677 ((a') 0.568, (a) 0.079, (b) 0.022, dynamic parts about 0.009), geometric histogram, P(exhaust) 0.677^256 = 4.6e-44, 0 of 16,337 seeds at the cap); Q1b the last resort FINDING (correctness; the mirror fired at cap 256 byte-identically; of 3,000 last-resort programs the real rule rejects 271, 9.0 percent: 251 by (a), 14 by (b), 6 by (c) distinct sum; handed out unchecked; unreachable; closed in class v5 by 8ca66afa, AP-F8-3); Q2 steering BOUND (45 of 48 planted rows fired, the real rule rejects every effective plant by (a'); 975 seeds at the first part, min ratio 0.998, 18 of 18 chain re-draws equal); Q2b the price of a seed property at 1 in 10^6 tries is a shadow block with 38 multiplies of 256 against a mean 74, about 2 to 3 percent of the f = 1 chip's energy per hash, the load critical path worth nothing at the memory activate ceiling; Q2c the 256-unit ratio is noise as a selector; Q3 program id FINDING (documentation: the "sub/" || 3_le16 suffix omitted from program.json and spec 1.4.6; a text-derived implementation computes 30956569d8f3d8d7 for Devnet 3 against the pack's fce15bf61030be57; 0 collisions over 10^7 pairs; fixed as AP-F8-4 at da2fc101); Q4 determinism DONE (the (c'') f64 compare never disagrees with the integer rule on any of the 2^20 + 1 values, margins 0.32 to 0.44 counts; a second interpretation agrees on 5,748 of 5,748 verdicts of 1,792 seeds); Q5 the era lever BOUND (400 eras, no stride under NAF weight 7, all 31 rotations, 354 distinct interleaves; epoch 0's accepted attempt is 3 under every era, so the era moves the address map, not the program). Partial named: the steering sweep at 975 of a planned 10^5 seeds (about 8 box-hours more at 32 cores). adv-cache-2 (the hot-set attack), tip 9384ee09 at 23:52 BST, about 2.2 box-hours by wall times threads over 96 (the boxes at load 400 to 600 for the first two hours), 0 pod-hours; two shards still queued at 00:00 (lines-2e30-s2c, warps-devnet-2e25-v2), named partial: Q1 the line index PASS (pooled 16 days; segments max +4.84 sigma against a control's +4.24, lines +5.61 against +5.35, chi2/dof 0.99937, top 0.1 and 1 percent of lines 1.0003x and 1.0002x of control; the 2^35 + 3 x 2^33 census all PASS; 0 mirror mismatches); Q2a the real programs PASS on the hot-set test (devnet at 2^26 1.0002x; Devnet 3 at 2^26 items 1.0071x, lines 1.0000x) with the FINDING at Devnet 3 site 0; Q2b all 64 programs done, every one clear on the hot-set test (items 0.9993x to 1.0075x of the windowed control) but the site class as recorded above (13 of 27 drawn-era over 1.04x, 8 over 1.2x, worst 1.7451x; the v5 floor refuses 0 of 61; AP-F8-6); Q3(1) steering by t PASS (worst cell 3.95 sigma in 2 x 2,112 cells); Q3(2) the weak-day scan PASS over 16,384 days (2^30 derivations in 707 s; worst per-day max bucket +8.13 sigma against the control's +7.78; the plant fired at +1,090); Q3(3) the window layer: the exact distribution matches the 4,096-program census to four digits (top quarter mean 0.3382, top half 0.5811), with a FINDING against the chip model's table: the f = 0.25 and f = 0.5 partial-store rows overstate the recompute share by up to 1.8x at f = 0.5, the full-store (f = 1) verdict unchanged (a correction owed in chip-model-v3's partial-store rows; no served number rests on f under 1); Q4 the prices: the only measured excess over f is the window layer's and the line reference multiplicity (a hottest-lines half store hits 57.8 percent instead of 50 at a higher miss cost than the stride). adv-mixer-3 (the statistical distinguisher and round margin), tip 4ebe2455 at 00:41 BST, still RUNNING at 01:03 (Q3 and Q4 at k = 8 on day 20729, queue 07 in the pool, the SAT ladder at k = 3 timed out; the total box-hours the lane's to give): Q1 the exhaustive round-0 line-index census over all 2^32 t PASS to k = 8 on days 20729 and 20733 and at k = 2, 3, 4, 8 on 20730 (z within 1.5); Q2 single-bit avalanche FINDING at k = 1 (354 and 266 holes, 130,000 cells beyond 6 sigma, the known one-application diffusion), PASS from k = 2 at 2^24 (0 holes, worst z under 5.3 through k = 8); Q2b the t-bit avalanche the same shape; Q3 differential multiplicity over 576 low-weight differences FINDING at k = 1 (695 and 537 deterministic output bits), PASS k = 2 through 7, k = 8 running; Q4 and Q4b linear correlations PASS from k = 1 (worst c 0.00046 to 0.00062, z under 5.1); Q5 rotational-XOR PASS from k = 1; Q6 SAT: k = 1 SATISFIABLE in 137 s (t = 0x49880000 verified through the real code), k = 2 and 3 TIMEOUT at the one-hour cap. The round margin as it stands: no statistic survives 2 of the 8 applications between reads; a chip gets nothing from the k = 1 findings because every read sits behind 8. The lanes' own lines go into section 13.1 as they arrive. THE LANES' OWN 00:00 LINES (adv-accept-3 and adv-mixer-3, 01:0x BST, in section 13.1 of in-house-pass.md): adv-accept-3's P(exhaust) refined to 1.0e-43 per epoch seed from 62,240 full-rule candidates plus 3.0e6 static candidates; Q2 steering BOUND over 19,975 full-rule and 1e6 static seeds, no property buying over about 1.03x at 1 in 1e6 tries; a second documentary FINDING: an implementation written from the spec text (not the code) at 017e7037's spec differs on 264 of 400 epoch programs, the same text-against-code gap as the id suffix (the audit lane's rewrite 8b834634 with spec_readback.rs is the fix; the proof that it closes this is a re-run of the text-derived implementation against the rewritten text, asked); a plant note: the floor-0.97 known-failed variant did not fire because the (c'') ratios are bimodal (accepted 0.989 to 0.999, rejected 0.814 to 0.966), replaced by a single-pass (a) variant that did; 3.3 box-hours, nothing running. adv-mixer-3: about 3.0 wall-hours of sweep plus 4 single-core CaDiCaL hours; the round margin stated as 6 of 8 applications between reads and 70 of 72 per item on every measured statistic, the k = 1 effects one mechanism (the lowest-set-bit trail through one application, dead once both addends carry a difference), nothing saving one application against 9,360 ops per item; still running at 4 cores on build-1 (2^27 and 2^28 avalanche rows, finish about 03:00 BST) and the day-20733 SAT ladder on build-2 (about 03:45 BST); not attempted: multi-bit linear masks and a MILP trail bound. adv-cache-2's own line still owed. ADV-CACHE-2'S OWN LINE (01:05 BST, tip 3f50d6c4; section 13 of in-house-pass.md now carries every lane's reading in its own words plus the verified roll-up): the drawn-era prevalence read on the SAME 32 base programs is 2 of 32 under the devnet era against 16 of 32 under drawn eras (8 over 1.2x, worst 1.75x), the mechanism carried by rotl(x times M, R) into the item index unless R is 29 or 30 (2 of 31 rotations), with a sub-class of warp-uniform sources once in 16,000 warps; the window layer's price restated: a chip holding the hottest f of items serves 0.4219, 0.7188 and 0.8907 of reads at f = 0.25, 0.5 and 0.75, so the chip model's partial-store rows overstate the recompute share by up to 2.3x on these programs, the f = 1 verdict unchanged (the correction to chip-model-v3's partial-store rows is the coordinator's next commit); partial named (the drawn-era windows census of 4,096 and one line shard in the pool); the longer-pass line: the biased-site rate per era in closed form (the R in {29, 30} rate 2 in 31) and a 2^28 read of the worst site. Nothing of the pass stands between the pool and a higher-class job except two pre-emptable shards on box 2. THE SPEC-TEXT RE-DERIVATION ORDERED (01:06 BST): adv-accept-3 re-derives its 400 epoch programs from the rewritten spec text alone at master 8b834634 (1.4.3 to 1.4.6 grown from 79 to 198 lines with the constants and pinned-ids tables), lease pool 16 --min 8 class adv, row Q4c in its report; the expected reading 0 of 400, any non-zero naming the diverging sentence to the audit lane; the proof that AP-F8-5 closed the text-against-code gap. THE CHIP MODEL'S PARTIAL-STORE ROWS carry a second correction (section 5, 8 October 2026) from adv-cache-2's window-layer reading: a chip holding the hottest f of items serves 0.4219, 0.7188 and 0.8907 of reads at f = 0.25, 0.5 and 0.75, so the uniform-store rows overstate the recompute share by up to 2.3x; the f = 1 row, the SRAM column and the full-store verdict unchanged, no served number on f under 1. THE CLASS V5 PACKS TEST ON THE MERGED TREE (the v5 lane, 01:0x UK): the job ran on box 2 the minute two adv-accept holders ended (65 cores; no lease fault, plain starvation before); 19 passed, 1 FAILED: v5_pack_is_the_v4_program_over_the_state_leaves (tests/packs.rs:977), the byte-for-byte compare of every pinned pack file with the crate's export. The ids are EQUAL (v4-genesis exports a217c7f698880830 as pinned; the state tag rides in master's recipe form unchanged); what differs is the program_id_derivation TEXT in program.json, which master's export (the hash lane's AP-F8-4 read-back form) now writes as "... || attempt_le32 || 'sub/' || sub_version_le16" for generator 4 while the pinned packs carry the pre-suffix wording. Disposition: the three pinned packs re-exported from the merged crate (text only; the ids, kernel texts, leaves and the fingerprint 82b19cbde8557ea5 must come out byte-identical, proved by the same test); the CLI rebuilding on build-1 from 51aa5bc4, the export from the box's IGSD1 streams, the packs test and the full suite on box 2 at 16 cores, then the push; readiness about 01:35 UK. The 0.3.24 kit zip (packs-ca3-v5-20261007T221001Z.zip) carries the old derivation text in its program.json files: a text field only, no id, kernel or fingerprint change, so the kit stands for 0.3.24 and the shipper is told; the re-exported packs go in the next kit. THE ONE 0.3.24 KIT, NAMED for the shipper (01:1x BST): packs-ca3-v5-20261007T183921Z.zip, sha256 e6c088bb34fecdc3ff297dbb06438a14ade7d8c55273357726d28f7a1334a25e, byte-identical to the frozen 1c420786 the pin pairs with; the fleet keeps placing it. The 23:11 zip packs-ca3-v5-20261007T221001Z.zip (sha256 4aaf9b9e..., /srv/artefacts/packs/ on build-1, from class-v5 7f58af97) carries the same packs, ids, kernels, leaves, fingerprint and derivation text and differs only in the merged kit host code and scripts beside the packs; it is the bench lanes' kit for the fingerprint jobs. The coordinator's earlier line naming 4aaf9b9e as the 0.3.24 kit was wrong and is corrected here. THE SPEC-TEXT READ-BACK RUNNING (adv-accept-3's Q4c, 01:11 BST on build-2, lease pool 16 --min 8 class adv): the same 400 epoch seeds re-derived from the spec text at master 8b834634 alone (1.3, 1.4.2, 1.4.3, 1.4.6, 1.6, 1.7, 1.13.1; a fresh text interpretation), compared field for field with the chain draw; the count about 01:21. One sentence already named divergent before the count: 1.4.6 part (c) cites dataset_elem(idx, S[0], S[1]) "of verify.rs" without stating its six operations, so part (c) cannot be computed from the text alone and the derivation takes that one function from the crate; the audit lane is to state the closed form's six operations in the text or the constants table, else 1.4.6 stays code-dependent on that line. A NINTH LIVE HOT SET (adv-accept, 01:12 BST): seed 228763 (id 2c4be0f6dc44c423, stand-in 0.9820) at 2^24 (X at 0.1 percent +0.118, 1.82x the window model), its single hottest item 0xe2cc96 at 1,218,380 reads, 0.057 percent of ALL reads, the largest single item of the pass (40x 100767's), from a NON-saturated source r0 at site 9 (the sel register), saturated-source share 0.000: the third shape at scale, a value-level concentration neither (c') nor a saturation test can see by construction; its 2^20 ratio against the 0.995 floor lands in minutes and decides whether the floor's instrument reaches it (if missed, the exemplar for the next class's non-saturated case). 638990 reads 1.51x beyond the gate with one item at 0.027 percent (r0, no saturation), no hot set; 623492 clean. Tally: 9 hot sets in 37 tail seeds against 0 in 20 random, 269,250 programs drawn; the price unchanged at 1.002x (0.27 percent of reads on 1 MB; one item 64 bytes). The public sentence's "eight of eight" moves to "nine of nine" or gains the first miss when the ratio reads. THE FLOOR REACHES THE NON-SATURATED SHAPE (adv-accept gap-tail3, 01:13 BST): seed 228763 reads minimum site 9 at 0.9809 at the 2^20 sample, the lowest of the pass, REFUSED; 638990 site 2 at 0.9872, REFUSED; 623492 (clean live) site 0 at 0.9922, REFUSED, a seventh false refusal. Final tally over everything the lane read at 2^20: 9 of 9 live hot sets refused (0.9809 to 0.9919), both single-item programs refused, 7 clean-live programs refused and 1 passed among the 12 deepest 256-unit seeds, 3 mild residuals missed at about 1.0004x. The reading: the distinct-index ratio reads any few-item concentration whatever its source, saturated or not, and misses only the diffuse era-stride excess; the class v5 floor closes the hot-set class entire at the 2.4 percent clean-rejection cost; the next class's value-level test is for the diffuse class alone. The public sentence reads "nine of nine hot sets refused" from here (the v5 lane's follow-up cfce57ea rides its push; AP-F8-1 on master updates with the next record commit). THE FAST-TIME GATE ON dfbd1e10: SUMMARY PASS (cross-0324-dfbd1e10) at 00:12:57Z on 8 October (01:13 BST), the shipped re-cut's binaries (igneumd 4870ccf2..., igneum-miner aa8c2978..., igneum-pow 1c420786), build-1 under lease pool class v5, 23:58:56Z to 00:12:57Z, every check green: rung 1 by signal at epoch 6 (00:05:37Z), class v5 by signal at byte 6 from epoch 8 at rung 1 (00:07:46Z, 4 of 4, 9,985 bps), 12 of 12 ids equal to the CPU verifier's, the stale node 95 of 95 refused, the restart step across the boundary on a kept datadir resynced in 36.2 s with the catch-up done after 11 s (4 IsInIBD refusals of its own miner during it, 0 of its blocks accepted), four sinks equal at 661, 0 PoW rejections on the honest nodes; record on v5-fasttime 0a09eb78, docs/design/class-v5-harness/fasttime/cross-0324-dfbd1e10.json. Every gate on the pin is green; the move waits on the pairs on the dl host, the last FETCHED plus ten, and the F9/F1 interim read. THE RE-EXPORT READ (the v5 lane, box 1 with the merged crate ac285733): the three pinned packs' only difference was program.json's program_id_derivation text (generator 4 now "|| 'sub/' || sub_version_le16", generator 5 the class recipe "igneum-program-rw/ ..."); ids, kernel texts, leaves.bin, vectors and the fingerprint 82b19cbde8557ea5 byte-identical; the pinned packs carry the merged text; the full gate and the full igneum-pow suite with the packs test and spec_readback running on that tree, the push and commit string about 01:45 UK; main's sentence at nine of nine on AP-F8-6, section 14 and spec 1.4.7.2 at class-v5 b5d6368d (nothing with eight of eight reached the mirror). AP-F8-1's two eight-of-eight lines on master move to nine in this record commit. THE MOVE'S SOURCE (the shipper's ruling at 01:05 BST, corrected to this record at 01:1x): the 02:00 BST move does not wait on the build-server lane's pairs; that lane is dark (nothing published since 23:05 BST, nothing answered since 00:17), so the fleet moves EVERY Devnet 3 node from the node lane's dfbd1e10 pair at /srv/artefacts/0324-dfbd1e10/node-lane on build-1 (igneumd 4870ccf2, igneum-miner aa8c2978, the pair every gate ran on, native glibc 2.39 on every fleet box), the way dn3-g1 and g2 moved at 22:30; the fleet's puller fetches from build-1, not the dl host. The move waits on the fleet publishing the dfbd1e10 move file and naming the minute (asked 01:05) and the F9/F1 interim at 01:55. The hive and the Windows pairs are the dark lane's loss for tonight unless main gives the shipper the word to build them (asked 01:06); the Mac entry publishes at the minute regardless; if the fleet has not published the move file by 01:40 BST, main and the coordinator hear it with the clock. THE PC 1 LOCK VOID, THE V5 AMD BENCH PUBLISHED (the hash lane, 01:1x BST): the shipper's 0.3.24 host job was never published to the jobs file, so the slot was void (the shipper's "slot void" at 01:05 BST); the v5 kit fetch landed on both PCs at 00:12:06Z (919,273 bytes, sha256 ok); run-ca3-pc1-v5-amd-bench-20261007 published 00:14:19Z (the 9070 XT by name, about 3 minutes, lock-free), its start line printing app_version, so the 0.3.20 or 0.3.23 reading of PC 1's app comes with the fingerprint; PC 2's Arc job needs only the shipper's "PC 2 clear". PC 1's app had NOT taken the 0.3.23 kit as of the last reads (every job log through 21:46Z app_version 0.3.20; the install folder's exe igneum-app 0.3.20, mtime 12:24:42Z, sha256 0443ae17...). The update-return lane (a22d765a2e0355a9f) last spoke at 23:0x BST: the helper workaround for 0.3.20 scripts (truncate cmd.txt, restart the task, wait for helper.alive, then write; or four leading " dev " padding lines), the locked jobs held as they are, power-helper-24 b9a72b9b merged into release-0.3.24 (daa7427b: a silent change becomes a logged line, the helper writes its exit reason), install-close-23 4ad6c199 for 0.3.23's take 3, the re-probe job when PC 1's app has taken the 0.3.23 kit; nothing since. THE SPEC-TEXT READ-BACK PASS (adv-accept-3 Q4c, 01:11 to 01:15 BST on build-2 at 16 cores; report section 6.5 on build/adv-accept-3, log 983-textderive-8b834634.tsv, pushed): the spec text at master 8b834634, implemented fresh without the crate's generator or rule, reproduces the same 400 class v4 epoch programs as the code with 0 of 400 differences (every instruction, the chosen attempt, the id, the rejection sequence); the 264-of-400 divergence against the text at 017e7037 is closed, so AP-F8-5 reads fixed on a measurement. The one remaining gap: 1.4.6.4 names dataset_elem "of verify.rs" without its six operations, so parts (c), (c') and (c'') still take that function from the crate; the audit lane's one-sentence closed form (asked 01:1x) closes it, and the read-back re-runs on the new text. THE AMD CLASS V5 FINGERPRINT (PC 1's RX 9070 XT, gfx1201, beside the miners, lock-free): 82b19cbde8557ea5 at 01:16:14 BST, equal to the kit e6c088bb's on Metal, Apple OpenCL and CUDA, self-test PASS, the v4-genesis control 892b6d55a7ddcfcb PASS; the 0.3.24 kit stands on four platforms; Intel waits on PC 2 (held until main's word, since the 0.3.23 take 3 never ran there); PC 1's queue continues with the CA4 unlocked rows. The kits row reads: Metal, Apple OpenCL, CUDA, AMD equal; Intel not measured tonight. THE UPDATE-RETURN LANE'S THREE READINGS (01:17 BST, from the live manifest and the intake): (1) 0.3.23 take 3 (install-close-23 4ad6c199) never reported; the live manifest igneum-app-latest.json reads 0.3.23 published 20:37:44Z with platforms = {mac} only, NO Windows entry, so neither PC has anything to take through its update path; PC 2's app run is still take 1's relaunch from 21:08:43Z (997 uploads, last 00:16Z); (2) PC 1 will not take 0.3.23 unattended tonight for want of a Windows entry; its run win-ae432dc7-20261007-160110 (0.3.20) never restarted (2,376 uploads, last 00:16Z), mining 18.96 MH/s on the 9070 XT; when a Windows entry is published the 0.3.20 engine's OTA takes it with no hand; the 21:41:32Z helper.ps1 write was not the prompt path (0.3.20 writes that file unconditionally), so no screen is owed in the morning for it; (3) the re-probe job (relay/playbooks/pc1-helper-reprobe.ps1 on power-helper-24 69f3c733) waits only on PC 1's exe becoming 0.3.21 or later; the 0.3.20 workaround is cleared to run tonight as a lock-free job so the locked grids go ahead: per grid job, before the first command, empty sweep\cmd.txt, Stop-ScheduledTask and Start-ScheduledTask 'Igneum Power Helper', wait until helper.alive is within 4 s, then write the lines with climbing sequences (in 0.3.20 the skip is the line count at the helper's start, fixed for its life); the helper idle-exits 20 minutes after its last command and the next start must begin over an empty file again; never pad after a command. The coordinator's order to the hash lane on it: the locked grids proceed in the earlier order (the 5080 full grid, the third 5090 pass to the driver's floor, SM-sparse, the two Ember tunes, the hot-table ldcs rows), each with its restore step, under the no-prompt rule; a Start-ScheduledTask that reads the 0x800710E0 refusal again stops the job and reports, nothing escalates. THE LOCKED GRIDS UNDER THE WORKAROUND (the hash lane, 01:2x BST; commit 24f9858e on the mirror): the three lock scripts carry the cleared sequence (empty sweep\cmd.txt, Stop- then Start-ScheduledTask 'Igneum Power Helper', helper.alive within 4 s with a 60 s cap, then dev + command with climbing sequences; repeated before any write when helper.alive is older than 10 s; a refused start 0x800710E0 or no heartbeat stops the lock path with the text on RESULT lines, nothing escalates; no padding; each grid job ends with rgc through the same sequence and the applications clock read back). PC 1's app_version on the v5 bench's start line: 0.3.20 (no Windows 0.3.23 published, nothing to take). The CA4 SM-sparse job run-ca4-pc1-ca4sparse-5090-20261007 runs since 00:20:40Z on the earlier padded script (unlocked rows first, then its 1,300 knee attempt; about 25 to 50 minutes); then in order on the shipper's acks: the 5080 full grid as run-ca3-pc1-v4-eff-5080-20261007-d, the third 5090 pass (1,100 MHz down), the microbench and the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows; the 5080 grid's knee and best points to the site audit lane for row 17 as read. THE ATTEMPTS CENSUS COMPLETE (adv-accept row 90, 01:34 BST, 20,000 seeds, closing the partial named at 00:00): 42,711 rejected candidates; (a') 83.5 percent, (a) 11.6, (b) 3.0, (c'') 1.1 (459 candidates), constant bit 0.4, saturated 0.3, (c') 0.05, distinct 0.04, lane-constant and bias 0; per-candidate rejection 0.681, flat across attempts 0 to 3 (the halves agree to a tenth of a percent); accepted-attempt mean 2.136, max 28; 0 exhaustions; P(256 consecutive rejections) 2e-43 per seed. The number for spec 1.4.6: under sub-version 3 the per-candidate rejection is 68.1 percent and the expected attempt 2.1. adv-accept's shards run on in the pool's gaps under the mechanical yield; the box-hours cross 8 later tonight. CLASS-V5 LANDED ON BOTH MIRRORS (the v5 lane, 091a0758 at 01:40 UK): the full pre-push gate GREEN at 71 checks (stamp on 48d38493, the last code change); the igneum-pow suite on box 2 (74 unit, derivation 2, derive 7, mixer 4, packs 20 with the three pinned packs byte-identical to the merged crate's export, so e5a4ac5978462156, 7c54302b487340a1, a217c7f698880830 and 82b19cbde8557ea5 hold under master's recipe form, recheck 2, scratch 7, spec_readback 2); spec-constants 28 rows agreeing; identity grep 0 hits. Carried since 61588347: main's sentence at nine of nine on AP-F8-6, section 14 and spec 1.4.7.2; the 61-row era reading and the class v5 attempts census on the spec, the page and the ledger; AP-F8-3; spec 1.4.7 and 1.8.6 with the constants and id tables; the AMD fingerprint row; the kits branch and master merged; two corrections the proofs found: master's program_id_derivation text lacked the class v5 rung-0 arm (the v5 packs' text named the class recipe while the id was the plain form; the arm added to the TEXT, re-exported, ids unchanged; a post-freeze change on the class-v5 line, so 0.3.25's pairing, never 1c420786's), and the public-export scrub (the founder's name six times on the page, the zone name in three files; gone). Incoming to the page: the Arc fingerprint, F9 and F1. THE MOVE FILE NOT PUBLISHED (the shipper, 01:41 BST): build-1's /fleet/move.json still names commit 2720d8d2 with the 22:30 BST minute; no FETCHED count, no named minute; the fleet lane (ac055d60427caab99) has answered nothing since its 22:4x report (asks at 01:05, 01:16 and 01:41; its task output last written 22:21 BST, its last action a hand read of dn3-g1's proven share), the second dark lane beside the build-server lane (last written 22:36 BST). So 02:00 BST cannot hold; the 02:53 BST ceiling (DAA 32,400) stands only if a signed move file lands at once and the 34 pullers fetch inside forty minutes; main has the clock line with the two options (wake or replace the fleet lane; or a fourth re-cut from a morning minute, the Mac entry standing down with it). The publish record's shape stands: the Mac entry at the minute (staged, DMG 1aa301cc, both folders, armed); the hive and the Windows pairs on main's word; the pairing 1c420786, 091a0758 0.3.25's. Every other gate on dfbd1e10 green and recorded. THE RUNG-0 ARM CONFIRMED (the v5 lane, 01:4x UK): 987e90e8 touches only Program::program_id_derivation, the text in program.json; Program::program_id untouched (the v5 rung-0 plain-form branch since the freeze); the crate at 091a0758 and 1b5684ec (master 35602b30 merged, pushed 01:41 UK) derives every pinned id byte for byte (packs 20 on box 2 comparing all three pinned packs' files including program_id and leaves.bin; spec_readback 2); the shipper told 091a0758 and 1b5684ec are 0.3.25's pairing, 0.3.24 on 1c420786. THE SM-SPARSE JOB (run-ca4-pc1-ca4sparse-5090-20261007, exit 0 at 00:41:53Z, 1,171 s, the 5090 alone, every fingerprint matched, the Power Helper answering every command on the padded write, the card left unlocked at 2,855 MHz): the SM-sparse reading does NOT exist; the research lane's worker ran its base kernel on every variant row (its race line "race 0 ms variant base" on all 48 rows, no NVRTC compile text), so --bench never honoured --variant sp-w32; the sparse rows equal base in rate and drift in watts with the card's heat only; the rerun waits on the research lane's exe honouring the flag. What stands: a repeat of the efficiency pass at two states, 32 s rows, the card alone: v4 unlocked 137.07 MH/s at 465.5 W (0.294 MH/W), at 1,300 MHz 134.26 at 309.9 W (0.433; 155.6 W back for 2.05 percent of rate); v3 unlocked 136.71 at 331.6 W (0.412), at 1,300 134.03 at 219.4 W (0.611; 112.2 W back for 1.97 percent); the v4 premium 133.9 W unlocked, 90.5 W at the knee; the three power fields agree within 0.2 W on every row (power.draw = instant = average on driver 617.14), which settles the field question on PC 1's side and leaves the 5080's 110 W gap to the fleet's rented card's sampler. Next on the shipper's ack: the 5080 full grid (-d) through the cleared helper sequence, the third 5090 pass, the microbench, the seven packs, the two tunes, the hot-table ldcs rows (kit and job at 292fcc75). THE --variant FAULT FIXED (the research lane, counter-asic-4, UTC clocks on 8 October): 00:44 the fix (a --bench with --variant runs the pinned race and installs the named kernel; the RESULT line carries variant=, sparse_blocks=, block_warps=; a served kernel other than the requested one prints variant_not_installed); 00:46 the known-failed test on build-1 against the real class v4 pack, no card (base: race off, 524,288 blocks of 32, "variant base"; sp43-w32: race on, 43 sparse blocks of 32 warps, the rewritten kernel with the nonces argument and the unit function, 43 blocks of 1,024; PASS; before the fix both read the base shape); 00:46 the Windows exe igneum-worker-cuda-ca4sparse3.exe sha256 0ba97edcd5c46a302a7ff5ddd1bbb1e493ca15f64d0757820ed645972df3bb56, mingw exit 0; the commit after 2d0013d1; the hash lane has the sha, the test's lines and the rerun's job shape (the same 48 rows, the race line per row); the op-mix re-weight stays behind the SM-sparse reading, the served 3.4x standing; the clean efficiency repeat in the file's 20.3a (6.6 pJ per counted op). THE SPEC'S LAST CRATE-DEPENDENT SENTENCE CLOSED (the site audit lane, master 56eebc0d at 01:49 BST, gate GREEN on c2c92eab, 71 checks; spec_readback now 3 tests): 1.4.6.4 states dataset_elem in full (the eight operations, the three constants, 32-bit wrapping) with two pinned vectors (dataset_elem(0x00000fed, 0x9E3779B9, 0x7F4A7C15) = 0x5c7dabd2; dataset_elem(0x0fffffff, 0, 0) = 0x7662c1ec) that spec_readback.rs reads from the text and checks against the crate, so part (c) computes from the text alone (34845c47); 1.4.6.5 names the class v2 figures as class v2's and carries the shipped rule's own census sentence (20,000 seeds, 68.1 percent rejected per candidate, the per-part shares, mean attempt 2.1, max 28, 0 exhaustions, 2e-43). The text-derived re-run on this text is the proof it is sufficient end to end (asked of adv-accept-3). THE MOVE FILE STAGED (the shipper, 01:5x BST): id mdfbd-1, commit dfbd1e10, want_digest b1ba7822, both pair slots on build-1's served tarball dfbd1e10-node-lane.tgz (e59ed0e6), at_epoch 0, signed with the fleet key on the Mac and verified against the fleet's public key in the puller's namespace; the read-back on placing it: the served file's id by curl and the first FETCHED on the relay intake; the 34 pullers fetch inside their one-minute timers (27 MB from build-1), the last FETCHED about five minutes after the file, the earliest minute ten after that. THE REAL LATEST-PUBLISH CLOCK: the file alone halts every miner on the restart, because each box's pack gate PAIR_MINER_SHA16 lacks aa8c2978 and the puller does not carry the file's miner sha into the restart environment; so route (A) also needs one ssh line on each of the 34 boxes before the minute with the fleet's tooling (the fleet lane's, or the shipper's on main's word). Absent main's word by 02:15 BST the shipper stands the Mac entry down under the ceiling rule (no app alone on b1ba7822) and 0.3.24 becomes a morning minute with a fourth re-cut. ROUTE (A) STAGED TO ONE COMMAND (the shipper, 01:5x BST): the gate script r0324/move/pair-gate-aa8c2978.py in its scratch (dry run by default, apply on the literal argument, the fleet's own Box helper and label list, nothing restarted); the dry run read 33 of 35 boxes, every one carrying the old gate list with fb147dd1 last and aa8c2978 absent, no env-last override; unreachable dn3-relay and p2-4090-1b (dead Vast proxies; they fall off at the move and rejoin by the pull); the apply about 90 s for the 33 with each gate read back and counted. THE F9/F1 INTERIM (the attack-pass lane, read at 01:5x BST): 71,292 seeds, 0 exhausted, 0 panics, max attempt 30; F1 0 failures at 2 h 23 min; the move's gate reads clear. On main's (A): apply 02:00, the file placed 02:02, the last FETCHED about 02:05, the minute 02:15 BST; main has the clock. Nothing applies before the word. THE SPEC TEXT SUFFICIENT END TO END (adv-accept-3 Q4d, 01:52 to 01:57 BST on build-2 at 16 cores; report section 6.6 on build/adv-accept-3, log 984-textderive-56eebc0d.tsv, every row equal to its Q4c row): the spec text at master 56eebc0d, implemented with nothing from the crate (text.rs: 0 igneum_pow imports; dataset_elem from 1.4.6.4, its two pinned vectors checked at start), reproduces the same 400 class v4 epoch programs as the code with 0 of 400 differences on every field; no sentence of the generator or acceptance sections needs the crate; the documentary finding (AP-F8-4, AP-F8-5) closed in full on two measurements; the lane at its end, 3.35 box-hours in all. F9 AND F1 AT 00:59Z (class v5 at 1c420786, pairing e5a4ac5978462156, build-1): F9 73,691 of 100,000 chain-shaped seeds written, 0 exhausted, 0 panics, 0 past attempt 31, max attempt 30; the attempt histogram 23,119 / 15,981 / 10,805 / 7,547 / 5,181 / 3,415 / 2,439 / 1,653 / 1,119 / 744 / 529 / 389 / 258 / 152 / 113 / 72 / 54 / 40 / 31 / 14 / 15 / 5 / 2 / 6 / 2 / 4 / 1 at 26 / 1 at 30, r about 0.69; the 10^5 about 01:30Z (02:30 BST). F1: the 10^5 redundancy census at 2 h 28 min under its lease with no end marker (18 minutes on an idle box; under tonight's load no minute named); its panic path live and empty, 0 failures the honest reading. Both land as record lines, then the board's close per item on sub-version 3 and class v5. AP-F8-5 ON TWO MEASUREMENTS (the site audit lane, commit 116e6055, master 5c77a7ac at 02:05 BST, gate GREEN 71 checks): the row carries Q4c (8b834634, 0 of 400 with one crate function, section 6.5, log 983) and Q4d (56eebc0d, 0 of 400 with no crate import, section 6.6, log 984); the public ledger and the ledger page regenerated; nothing open in the spec or the ledger on the audit lane's side. THE 5080 FULL GRID (run-ca3-pc1-v4-eff-5080-20261007-d, exit 0 at 01:54:00Z, 4,118 s; PC 1's dock card alone, driver 617.14, app 0.3.20, mem 14,801 MHz throughout; every lock through the cleared helper sequence, every command answered first time, every fingerprint matched, clocks reset and read back): the knee as a reading: the rate holds within 0.3 percent of unlocked down to 1,000 MHz on both classes (v4 71.19 of 71.41 MH/s; v3 71.11 of 71.28) and falls 5.2 percent at 900 MHz on v4 (67.66), where the 75-minute budget ended the grid (v3's 900 and below not taken; the drift check skipped); so the 5080's knee sits between 1,000 and 900 MHz, a third of its 2,963 MHz boost, lower than the 5090's 1,300 (84 SMs at 2,960 MHz have more compute headroom per unit of its 960 GB/s than the 5090's 170 SMs per unit of 1,792 GB/s; the memory wait hides the shadow down to a lower clock). Best MH per watt within the 1 percent rate tolerance: v4 at 1,100 MHz, 71.20 MH/s at 146.6 W (0.486 MH/W; 106.5 W recovered for 0.29 percent of rate); v3 at 1,000 MHz, 71.11 at 103.7 W (0.686; 66.0 W for 0.25 percent). The v4 premium 83.4 W unlocked (253.1 against 169.7), 41 W at the best points (146.6 against 105.6 at 1,100). Per tier: a 5080 owner on class v4 locked near 1,100 MHz draws 147 W instead of 253 for 0.3 percent less rate (MH/W up 72 percent) and the shadow's residual cost is 41 W. Rows (lock: v4 MH/s / W / MH/W ; v3): unlocked 71.41/253.1/0.282 ; 71.28/169.7/0.420 (sm 2,963/2,977); 2850 71.41/229.5/0.311 ; 71.29/155.3/0.459; 2700 71.41/209.6/0.341 ; 71.29/149.2/0.478; 2550 71.41/193.0/0.370 ; 71.29/134.4/0.531; 2400 71.41/176.0/0.406 ; 71.29/128.7/0.554; 2250 71.41/165.6/0.431 ; 71.28/117.3/0.608; 2100 71.38/157.7/0.453 ; 71.28/112.3/0.635; 1950 71.37/154.0/0.463 ; 71.26/111.6/0.639; 1800 71.35/150.3/0.475 ; 71.24/113.4/0.628; 1650 71.33/151.4/0.471 ; 71.22/109.7/0.649; 1500 71.30/149.2/0.478 ; 71.19/110.6/0.644; 1400 71.27/149.6/0.476 ; 71.16/107.0/0.665; 1300 71.24/147.9/0.482 ; 71.14/107.7/0.661; 1200 71.20/149.4/0.477 ; 71.12/104.4/0.681; 1100 71.20/146.6/0.486 ; 71.11/105.6/0.673; 1000 71.19/149.0/0.478 ; 71.11/103.7/0.686; 900 67.66/137.8/0.491 ; not taken. Throttle reason 0x400 (the power governor) on every row, never the clock lock, so the draw floor of about 147 W (v4) and 104 W (v3) from 1,500 MHz down is the memory system plus idle, not the SMs: the clock lever is spent by 1,500 MHz on this card. The three power fields agree within 0.2 W on every row. The site audit lane has the knee and best points for row 17; the bench table's 5080 row takes "71.4 stock (71.2 tuned)", "146.6 tuned (253 stock)", class v4 cost "+83 W unlocked, +41 W at the best points", hive core 1100 (the mem clock unchanged) once the fleet's rented-5080 sampler question is closed. Next on the shipper's ack: the third 5090 pass, the SM-sparse rerun on the fixed exe, the microbench, the packs, the two tunes, the hot table. THE NIGHT'S MOVE OUTCOME (the shipper, 02:58 BST): main's word on (A), (A') or (B) did not come (asked 01:41, 01:50, 01:53, 01:56 by the shipper and 01:42, 01:52, 01:5x, 02:00 by the coordinator); the gate script not applied (the dry run's 33 of 35 the only read); the move file not placed (build-1's /fleet/move.json serves m2720-1, 2720d8d2, the 22:30 minute, by curl at 02:56); no move minute; the stand-down under the ceiling rule holds from 02:15 (the shipper's stand-down line at 02:15 was not sent, its miss, the state unchanged); the Mac entry standing, not published (staged on DMG 1aa301cc in both folders, the live manifest at 0.3.23). A FINDING: build-1's Devnet 3 seed (the process on 26631 with JSON RPC 27632, the node lane's DAA reader) is DOWN (no such process; node1-dn3 26671 and the observer 26651 run on 2720d8d2; the node lane's 0.3.24 reader on 28690 runs but answers no DAA by the envelope tried), so the node lane's DAA reads since 25,169 at 00:52:38 BST may have stopped with it; at 1.0 DAA/s the DAA passed 32,400 at about 02:53 BST, the 39,600 floor is lost, and the fourth re-cut is from a morning minute main names (before 12:50 BST, or the three heights move with the floor). Every Devnet 3 node is on the 0.3.23 pin 2720d8d2, digest ba75bf6f (the 22:30 move; dn3-j1 behind its proxy unverified since); nothing of 0.3.24 is on any box or in any manifest. The night's 0.3.24: every gate green on dfbd1e10, the kit on four platforms, the move unmade for want of one word and two dark lanes. THE ATTACK-PASS BOARD'S CLOSE (lane (d), 01:58Z on 8 October; record docs/analysis/attack-pass-2026-10.md on the mirror's attack-pass; box-hours approximate: build-2 about 7 h, build-1 about 9 h plus about 6 h of F6 batches and F2 solvers earlier in the day). F9 so far: 89,301 of 100,000 chain-shaped seeds, 0 exhausted, 0 panics, 0 past attempt 31, max 30 (the tail 20: 20, 21: 6, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1; r about 0.69), three chunks on their cores to about 02:20Z; F1 the 10^5 redundancy census at 3 h 22 min on 17 threads, healthy, no end marker, 0 failures on its live panic path. The board: F1 shadow redundancy PASS on sub-version 3 (max 5.078 percent at honest-compiler parity; AP-F1-1 on the v5 list at 3.0 percent), running on v5; F2 mixer round margin PASS effort-bounded (no trail under weight 20 to 24 at 2 applications, 29 to 35 at 3, 39 to 47 at 4), not re-run on v5 (the mixer unchanged); F3 chained cache j+1 PASS, not re-run; F4 weak-day census PASS on v4 on the DSP-bound metric with AP-F4-1 reconciled with adv-mixer-2 (median 226, 15 days a century, worst 2050-04-28 at 1.113x), on v5 PASS at 8ca66afa (0 of 2^24 days over 1.1x on both metrics, AP-F4-1 FIXED-AND-PASSED); F5 chip-model sweep FIXED-AND-PASSED (the F2 hour skipped by decision), not re-run; F6 verifier worst case PASS (worst of 10^5 at 8.708 ms half-core; O-1.14 closed, i7-9700K 6.334 ms), not re-run; F7 era draw PASS on all three (0 of 6 re-rolls), not re-run; F8 uniformity FIXED-AND-PASSED on sub-version 3 (60 of 64 under 1.2x; AP-F8-1, 2, 3 closed), PASS on v5 (61 of 64, worst 1.50x, the residue p4, p8, p10; p34 under); F9 edges, hot set, grinding PASS on sub-version 3 (34 of 105,064 edges bounded; grinding +0.004 percent), the exhaustion count running on v5; F10 ladder signal PASS, not re-run (node rule). Findings of the pass, all in-house: AP-F1-1, AP-F4-1, AP-F5-1 (the X9), AP-F8-1, AP-F8-2, AP-F8-3; two operating hazards fixed (AP-H1 the box clean, AP-H2 the shared binary path). The open tail (p4, p8, p10, and p34 on sub-version 3) is named in the public report; no outside party holds it (the attack-pass lane's close wrote "disclosed to the firms", stale wording from before the in-house ruling; its record file is to say "named in the public report"). THE SEED'S DEATH AND THE DAA NOW (the node lane, 03:0x BST): build-1's Devnet 3 seed log /home/build/dn3seed.log ends at 01:09:05Z at DAA 29,732 mid-stream with no stop, shutdown or panic line, so it was killed abruptly (it ran under nohup from a shell, not a unit; no journal names the killer; the OOM record needs sudo the lane lacks); its datadir /home/build/dn3seed/igneum-devnet-3/datadir is intact (13 GB) and it stays down until the shipper says; the lane's reads 25,169 at 23:52:38Z and 28,906 at 00:55:09Z came from it while it lived. The DAA now from node1-dn3 on 28670: 32,659 at 01:57:50Z (the observer 32,660), both on 2720d8d2; the chain passed 32,400 at about 01:53Z, 39,600 lost. The fourth cut in one line: the script on release-0.3.24-node reads the DAA from 28670, sets the floor to the morning minute's publish DAA plus 7,200 rounded up to the next 3,600, commits, pushes both mirrors and dispatches the gate set (about 20 minutes to the pin line, then the fast-time pair about 14); the latest minute before the three heights move with the floor is about 11:50Z (12:50 BST), where the floor reaches 79,200; nothing is cut until main names the minute. A morning item for the box owner: a process on build-1 was killed at 01:09:05Z without a log line while the box carried a load of 400 to 600; the killer (OOM or a sweep's cleanup) is to be read from the journal with sudo before anything long-lived runs there again under nohup. THE BENCH LOG ENTRY (the hash lane): docs/bench-log.md "7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080" (both cards' full tables, the knee per card, the best MH per watt points, the premiums at the lock, the lever's limits, the job ids and clocks, the rented-5080 watts note) on the mirror's master as merge 773b93a8 at 02:04:47Z (commit 11c698ad); the audit lane writes row 17's sentence from it. PC 1: the third 5090 pass run-ca3-pc1-v4-eff-5090-floor2-20261007 (1,100 MHz down to 300) since 01:57:03Z, about 28 minutes; then the SM-sparse rerun. ROW 17 AND THE 5080 BENCH ROW (the site audit lane, master 2c5c7f52 at 03:19 BST, gate GREEN on 6eb6fd9b, 71 checks): docs/evidence.md row 17 carries both cards' efficiency passes from the bench-log entry (the 5090's knee, best points and premium; the 5080's 71.41 MH/s at 253.1 W unlocked, 71.20 at 146.6 W at 1,100 MHz, v3 at 1,000 MHz 103.7 W, the premium 83.4 W to 41 W, the knee between 1,000 and 900 MHz, the per-tier reading, the Ember Tune lever), a what-moved table for 8 October, /evidence rebuilt (865a0a5e); site/miner-bench.json's RTX 5080 row states the team's pass as the card's figure ("71.4 stock (71.2 tuned)", "146.6 tuned (253 stock)", "+83 W unlocked, +41 W at the best points", hive core 1100 with the memory stock, driver 617.14, the bench-log entry as the source) and keeps the rented-fleet sampler reading with its 110 W gap as the open question; /miners rebuilt at 35 rows (6eb6fd9b); 0 identity hits; nothing deployed, the deploy the morning hand-off. The design pass on ca3-coord (015cc839) now sits behind this master and rebases onto it before its own landing on main's word. THE DESIGN PASS REBASED (the coordinator, 03:2x BST): ca3-coord rebased onto master 2c5c7f52 as the three site commits only (f5b7140c the design pass, 8cc4cbc6 the phone grid, 9ad3fdc9 the six-column row; the two commits already landed through the record branch skipped), site/miners.html rebuilt at each from the merged miner-bench.json so the page carries the 5080's new row ("71.4 stock (71.2 tuned)") under the design; the diff against master is build.mjs and miners.html only; pushed to the mirror (pre-push GREEN); it lands on main's word after the captures, one gate run. ADV-MIXER-3's LINE (read from its report at tip e02297ae, 03:18 BST): queue 17 finished on build-1 at 01:3x BST; Q2 single-bit avalanche at 2^27, k = 2 and 3 on day 20729: 0 holes, 0 cells beyond 6 sigma at band 0.00026, PASS (the k = 1 finding stands as the single-application diffusion); Q2b t-bit avalanche on day 20733 at 2^28: 0 cells beyond 6 sigma at band 0.00018, PASS (k = 2, 3, 4 on 20729 at 2^28 the same); Q3 at k = 8 NOT run (killed at 20:20 BST under the lease rule, not re-queued; k = 2 to 7 clean with 0 deterministic bits on both days), named partial; Q6 the day-20733 SAT ladder: k = 2 and 3 TIMEOUT at the one-hour cap, k = 4 on one build-2 core since 03:05 BST, its cap about 04:05; one pre-emption in its ledger (23:58 BST, 21 minutes of a 2^27 row lost, re-queued); box-hours about 3.0 wall-hours of sweep (build-1 1.9, build-2 1.1) plus about 4 single-core CaDiCaL hours, about 7 with the 20733 ladder. The pass's close with the per-lane table and totals at about 04:05 BST; section 13 on crypto-engage (docs only) merging the current master and going through the gate to the mirror's master so the record cites a master commit. Box 2 at 03:20: adv-accept 87 cores in four shards with three waiting, adv-mixer-3 one core; build-1 load 34, no adv lease. THE DESIGN PASS'S OVERLAP ON THE BOX (the CI steward, 03:33 BST): the 1440 and 390 dark captures of /miners from ca3-coord 9ad3fdc9 taken on build-2 under lease pool 4 (Playwright chromium 1194, the recorded feed; /srv/artefacts/captures/ca3-coord-9ad3fdc9/miners-1440-dark.png 1440 x 4280 and miners-390-dark.png 390 x 9779); the overlap sweep on the same checkout, 390 to 1600 px, light and dark: RED, 3 findings on the change itself: at 1280 px dark and 1600 px light and dark the date span in the lead cell's class v4 line is COVERED by the rate cell (4 of 5 sample points under td.big); 390 to 1024 pass. Cause: the branch's last gate ran on the Mac, which has no browser, so the sweep skipped and read GREEN; on the page the row rule's white-space:nowrap outranked the lead cell's normal by specificity, so the class v4 line ran under the rate cell from 1280 px up. FIXED at ca3-coord 2ca45001 (the lead cell's rule at the row rule's specificity, max-width 360 px, the class v4 line wrapping with overflow-wrap), rebuilt, pushed; the sweep and the captures re-run on the box before main's word. THE IN-HOUSE PASS'S PATH TO MASTER (the crypto lane, 03:2x BST): adv-accept's box-hours crossed 8 before 02:00 BST and sit near 10 (87 cores in four shards; it sweeps on under the mechanical yield, its reading unchanged); crypto-engage merged master 56eebc0d at 342b6730 (one conflict in funding.md, the pre-public scrub against the rewrite, resolved to the in-house pass with the scrub applied; the founder never named in in-house-pass.md or funding.md), the full gate running, merge-to-master on GREEN; section 13.3: master's igneum-pow moved after the freeze in four files (src/emit.rs and src/generator.rs, the derivation string and its recipe helpers, ids unchanged; tests/derivation.rs and tests/spec_readback.rs), none the hash, so the object the pass bounded is unchanged in every operation the hash performs. THE PASS IN ONE LINE (the crypto lane, 03:2x BST): eight of nine lanes closed, adv-mixer-3 on one SAT timeout (about 04:05 BST), adv-accept sweeping to its 16 box-hour line (9.2 now, the reading saturated at the 1.002x class), adv-cache-2 on one line shard; no break of class v4 sub-version 3; the acceptance's hot-set class closed by the class v5 floor (9 of 9) and its diffuse era-stride class routed to the next class; the weak-day FPGA tail reconciled and closed by a measured redraw rule; the attempts census complete; the spec text proven sufficient by two read-backs; one pod at USD 0.33 in the whole pass, none originated by the lane. THE THIRD 5090 PASS BELOW THE KNEE (run-ca3-pc1-v4-eff-5090-floor2-20261007, running at 02:34Z on its 500 MHz step; the steps lengthen as the rate falls since the batch count was sized from the unlocked rate, about 155 s at 500 against 60 at 1,100; the helper answering every command on the cleared sequence, every fingerprint matched, the 5090 alone). Rows (lock: v4 MH/s / W / MH/W ; v3): unlocked 137.09/456.7/0.300 ; 136.79/320.0/0.428 (sm 2,858/2,862); 1100 120.98/275.9/0.439 ; 117.32/198.6/0.591; 1000 110.03/254.9/0.432 ; 106.73/180.2/0.592; 900 97.43/232.7/0.419 ; 94.33/174.5/0.541; 800 86.00/216.3/0.398 ; 83.41/166.6/0.501; 700 75.98/202.7/0.375 ; 73.58/156.4/0.470; 600 65.30/178.2/0.366 ; 63.25/153.3/0.413; 500 53.03/166.5/0.319 ; v3 running. Reading: below the knee the rate falls about 10 percent per 100 MHz on both classes (compute-bound: the shadow and the base program no longer fit the memory wait) and MH per watt falls with it from 1,100 down, so the best point stays where the second pass put it (v4 at 1,200, v3 at 1,300); the driver took every lock down to 500 (the SM clock within 10 MHz), so the floor is below 500 MHz and is not where the optimum lives; the v4 premium below the knee 77 W at 1,100, 75 at 1,000, 58 at 900, 50 at 800, 46 at 700, 25 at 600 (the ALU work shrinking with the clock as the rate does). The exit line, the 400 and 300 rows, the drift check and the restore at its close; then the SM-sparse rerun on the fixed exe (each sparse row reading served= and sparse_blocks=, marked variant_row=FAILED if served as base). F9 AND F1 AT 02:34Z (class v5 at 1c420786, build-1): F9 98,945 of 100,000 seeds, 0 exhausted, 0 panics, 0 past attempt 31, max 30 (the tail 18: 39, 19: 19, 20: 24, 21: 8, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1); the last three chunks within minutes of their ends; F1 at 4 h 02 min under its lease, no end marker, 0 on its panic path. The pass record's wording fixed on the mirror's attack-pass at 9474cea8 ("named in the public report"; no "firm", "firms", "escrow", "prize", "paid review" or "Lot" line in the pass record or the ten row records; identity grep 0 hits); the section's merge to master after the two record lines, through the full gate in a detached worktree. THE SECOND SWEEP ON THE DESIGN PASS (the CI steward on 2ca45001, 03:38 BST): the desktop widths pass; RED at 390 px dark only, three findings on the lead cell (the card name and the class v4 line covered by the rate cell), the cause the new 360 px max-width on the phone grid; FIXED at ca3-coord 5158276c (the lead-cell width rule scoped to widths above 1,100 px, the phone grid's lead cell with no max-width), rebuilt, pushed; the sweep and captures re-run on it. F9 PASS ON CLASS V5 (the attack-pass lane, class v5 at 1c420786, pairing e5a4ac5978462156, build-1 under lease pool class release, the last chunk written 02:34:54Z): 100,000 of 100,000 seeds drawn through the chain path (era-composed class), 0 exhausted, 0 panics, 0 past attempt 31, max attempt 30; histogram 0: 31,454, 1: 21,460, 2: 14,660, 3: 10,263, 4: 7,047, 5: 4,701, 6: 3,297, 7: 2,256, 8: 1,532, 9: 1,027, 10: 702, 11: 509, 12: 365, 13: 216, 14: 153, 15: 103, 16: 80, 17: 56, 18: 39, 19: 20, 20: 24, 21: 9, 22: 6, 23: 9, 24: 3, 25: 4, 26: 2, 27: 1, 29: 1, 30: 1 (first-draw acceptance 0.3145; the mean attempt index 2.185, so 3.185 draws per seed on average; 4,862 seeds, 4.86 percent, at index 8 or above and 255, 0.255 percent, at 16 or above; the 256-attempt cap and the deterministic last resort never reached; the lane's first line read 1.993, a slip it corrected); the exhaustion gate holds for the 0.3.24 move; record docs/analysis/attack-pass/f9-grind.md and the lane (d) section on the mirror's attack-pass. F1 still running (4 h 05 min, 16 cores, 0 on its panic path, no end marker). F9's record on the mirror's attack-pass at 2bcb7e08 (the lane (d) row and f9-grind.md section (d); feature gate GREEN); F1 the one open item before the lane (d) merge to master. THE DESIGN PASS GREEN ON THE BOX (the CI steward on ca3-coord 5158276c, 03:4x BST; build-2 under lease pool 4): the overlap sweep 390 to 1600 px, light and dark, GREEN, 0 findings (the known-failed fixture fired first); the 390 px capture byte-identical to 9ad3fdc9's (the phone shape that passed before), the desktop widths carrying the wrap at 4,640 px tall; the four dark whole-page captures on build-1 under /srv/artefacts/captures/ca3-coord-5158276c/: miners-390-dark.png (sha256 9eec8f27..., 509,158 bytes), miners-1280-dark.png (1b6e636d..., 438,541), miners-1440-dark.png (87387e14..., 445,402), miners-1600-dark.png (d53973cd..., 448,545); the run log /srv/builds/bs-ci-steward/cap-out/run-5158276c.log on build-2. The branch's gate record: a full gate on the Mac skips the sweep (no browser), so the box line is the sweep's verdict for 5158276c; the branch waits on main's word on the look and lands in one gate run. THE IN-HOUSE PASS'S RECORD ON MASTER (the crypto lane): crypto-engage dab0c89f (gate GREEN, 71 checks) landed through merge-to-master.sh --remote build at 03:50 BST as master 00b8cd1b: docs/plans/cryptanalysis/in-house-pass.md section 13 (the roll-up, every lane's reading, the frozen-object note) and funding.md's in-house row and brief, scrubbed under founder-strings-check.sh. AN EXCEPTION OWNED (03:39 to 03:50 BST): the lane's first merge call used the tool's default path, which reads CI on GitHub with gh run list; GitHub is suspended and the rule says never poll it; the tool polled 21 times (each 403, nothing pushed, nothing read); the run's process outlived the task stop and the lane ended it by its pid at 03:50 BST, then used --remote build; the breach is the tool's default against the rule and the lane's for not passing the switch; no state moved on GitHub's side. The coordinator's order on it: merge-to-master.sh's default remote must refuse GitHub while the suspension stands (the CI steward, a gate-side fix with a known-failed self-test), so the rule does not rest on every lane remembering the switch. THE THIRD 5090 PASS CLOSED BY ITS CAP (run-ca3-pc1-v4-eff-5090-floor2-20261007, ended by the 45-minute cap at 02:42:05Z during the 300 MHz step, exit -1, its own finally block never ran; every row taken matched its fingerprint, the 5090 alone): the 500 row's v3 side 51.37 MH/s at 136.4 W (0.377); 400: v4 42.62/152.5/0.280, v3 41.32/131.3/0.315 (sm 390); 300 not taken; no unlocked-end drift check; the driver took every lock down to 400 (the SM clock within 10 MHz), so the floor is at or below 400 MHz. The reading: below 1,300 the rate falls about 10 percent per 100 MHz on both classes and MH per watt falls from 1,100 down (v4 0.439 at 1,100 to 0.280 at 400; v3 0.592 at 1,000 to 0.315), so the optimum stays at the second pass's points (v4 1,200 MHz, v3 1,300) and nothing below 1,100 is worth the knob's time; the v4 premium below the knee shrinks with the clock (77 W at 1,100, 46 at 700, 21 at 400). AN EXCEPTION OWNED: the 5090 sat at the 400 lock (390 MHz, 127 W mining) for four minutes until run-ca3-pc1-clocks-restore-20261008 (02:45:20 to 02:46:30Z, exit 0) started the helper over an empty cmd.txt and sent rgc ("All done"), the card reading 2,880 MHz after; the cause the batch count per step sized from the unlocked rate, so the low steps ran 2.5x longer than planned; the fix in the scripts: the budget check ends the grid with the restore inside the cap, and a probe dev line answered in helper.log counts as the helper up when its heartbeat file stays stale (the restore answered at once with helper.alive stale past 60 s). THE SM-SPARSE RERUN: fetch-ca4-sparse3-exe-20261008 landed 02:49:57Z (sha256 0ba97edc...), run-ca4-pc1-ca4sparse-5090-20261008 published 02:51:15Z on the hash lane's own order (the shipper's acks were for the void host slot); each sparse row reads served= and sparse_blocks= and is marked variant_row=FAILED if served as base; the close about 03:15Z (04:15 BST). THE STEP-BUDGET FIX ON MASTER (the hash lane, merge 9fd8b1d8 at 03:02:03Z on 8 October, commit 0b00c42e, the full gate GREEN): the efficiency pass keeps four minutes of its cap for the restore (every step and lock guarded by the deadline minus four minutes) and sizes each step's batch count from the last rate read for the pack, so a 60 s step stays 60 s as the rate falls; a probe dev line answered in helper.log counts as the helper up when the heartbeat file stays stale (all four lock scripts); the gate check tools/ci/pc1-step-budget-check.sh with the known-failed case first (under the old rule a lengthening grid ends on the cap with no restore; under the new it ends with the restore at 1,500 s of 2,700), wired into pre-push.sh and checks.txt (74 checks). The 5080 Ember tune, the 9070 XT tune pass and the hot-table ldcs rows publish behind the SM-sparse rerun, the microbench and the packs. THE SM-SPARSE RERUN FAILS THE SAME WAY, NOW NAMED (run-ca4-pc1-ca4sparse-5090-20261008, the fixed exe ca4sparse3, started 02:52:48Z): every sparse row served=base sparse_blocks=0 variant_row=FAILED, the worker's own line "RESULT variant_not_installed requested=sp43-w32 served=base race=... variants 1 base only, no race (no other variant named)", no "compile:" text, so NVRTC never saw a rewritten kernel: the variant name is parsed into the request but never added to the race's variant table in this exe; the research lane's emulation test checked resolve and rewrite, not the race list the bench builds (a test of the wrong layer; the known-failed case must be the bench's own race line reading "variants 2"). The rows are base runs; no reading. The queue goes on: the microbench at the rerun's exit (about 03:15Z), the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows; the SM-sparse question's fourth row stays with the research lane, an exe whose card-free check shows "variants 2" in its race line getting the slot within the minute. CLASS-V5'S F9 ROW PUSHED (the v5 lane, class-v5 1d5e5d23 on both mirrors at 04:04 UK): the page's F9 row (100,000 seeds, 0 exhausted, max index 30, first-draw acceptance 0.3145, mean index 2.185, F9 PASS, the record file named), F1 stated as running with 0 failures (its own commit to follow), the Intel row not measured tonight; master merged twice (2c5c7f52 gated at 5f5e0a5c, full gate GREEN 71 checks at 03:45 UK; 9fd8b1d8 auto-merged and pushed on the hook's light gate, the full gate running on 1d5e5d23); the generated ledger files and the spec-constants check clean on the tree. THE THIRD --variant FIX (the research lane, 03:04Z on build-1 under lease, with the hash lane): the cause of the 02:52Z rows: the race's push looked the pinned name up in the empty order list through the variant lookup, whose on-demand sp path answers for any list, so the sparse variant was "found" and never pushed; the order is now a pure function with membership by name; --list-race prints, with no device, the race order the worker's own option handling builds and whether the rewrite applies: with the job's exact flags "variants=2 names=base,sp43-w32" and "sparse_blocks=43 block_warps=32 rewrite=applied bytes=22261 nonces_arg=1 unit_fn=1" (before the fix variants=1); exe igneum-worker-cuda-ca4sparse4.exe sha256 84846396559004a8df61881c15ecb42fa3fc1010ad99074e0c0b53e81bb1ca3b, the commit on the mirror after 7e9d52a6; the third rerun on the hash lane's queue at the next slot; the two failed runs stay the night's SM-sparse state, the op-mix re-weight held, the served 3.4x standing. THE GITHUB GUARD ON MASTER (the CI steward, tip 2f702735 at 04:05 UK; merges 53773860 and 2f702735, full gate GREEN 71 checks each): fa7e98fe adds the tracked marker tools/ci/github-suspended (suspended-since 2026-10-07T17:02:00Z, removed by main at the cut-over) and two refusals: merge-to-master.sh refuses a GitHub remote (origin by default, or any remote whose URL carries github.com) with one line naming the switch and exit 2 before any gh or git call; the pre-push hook refuses any push to a GitHub remote the same way (the hook reads the remote URL, so a bare git push origin is refused too); known-failed first in both self-tests; the live read on the Mac: merge-to-master.sh --remote origin exits 2, nothing contacted; two follow-ups (9484b988, a08423d4) fix the tool's own --self-test under the real marker. The rule no longer rests on any lane remembering the switch. F1 READ AT 03:05:58Z (the attack-pass lane; the census process itself, not the lease wrapper): state S with 17 threads, 15 cores busy over 45 s, 2 d 19 h of CPU banked over 4 h 30 min of wall, RSS 0.8 to 1.0 GB; computing, not hung. No rows can exist before the end: the harness collects every Report in memory under thread::scope and writes census.csv in one go at the end (no progress print), named as a harness gap in the record. Why fifteenfold against the v4 reference: under class v5 every candidate draw runs the (c''') distinct-index floor over 2^20 (about 1.8 core-s per candidate under the night's load, times 3.2 draws per program, about 5.8 core-s per program before the analysis), so 10^5 programs at 15 busy cores is about 10.7 h of wall, the end about 09:00Z (10:00 BST), nearer the early side as the load fell to 21. Ruling: not killed (a kill loses 4 h 30 min with nothing on disk); the lane (d) section merges to the mirror's master now with F9 and the F1 row reading "running, 03:06Z reading, projected end about 09:00Z", F1's record line in a second merge when it writes; the harness gains a progress line before its next 10^5 run. THE IN-HOUSE ADVERSARIAL PASS CLOSED (04:08 BST on 8 October; an internal adversarial pass, not an independent review; section 14 of in-house-pass.md at crypto-engage c099e818 landing on master through --remote build; every tip read from the mirror at 04:07 with igneum-pow identical to 017e7037 on all nine). Per lane (tip; box-hours; verdict; partial): adv-mixer d2ba3134, about 0.6 plus 1.8 single-core SAT hours, the algebraic structure BOUND, none; adv-mixer-2 2a632579, 0.31, BOUND for every chip, GPU and the verifier with the FPGA LUT-area FINDING (2^-10.8 of days, 15 a century, worst 2050-04-28 at 1.113x) closed by the measured redraw rule, none; adv-mixer-3 981bfff2, about 5.0 wall-hours plus 8 single-core SAT hours, Q1 BOUND (2^32 t uniform at k = 1 to 8, both days and 8 random days), Q2 and Q2b FINDING at k = 1 only and BOUND from 2 to 8 at 2^24 to 2^28, Q3 FINDING at k = 1 and BOUND 2 to 7, Q4 and Q5 BOUND from k = 1, Q6 SAT BOUND (k = 1 in 137 s, k = 2 to 4 timeout), the round margin 70 of 72 per item, partial Q3 at k = 8 not run, multi-bit masks and a MILP bound not attempted, GPU blocked; adv-cache 555c3e42, 0.55, the recompute shortcut BOUND on every row, none; adv-cache-2 91ca5ce1, about 2.25, the line census PASS at 2^35 + 3 x 2^33, the real programs PASS with the Devnet 3 site-0 FINDING, the diffuse era-stride class named (16 of 32 base programs biased under drawn eras against 2 of 32 under R = 29, 8 over 1.2x, worst 1.75x, under 0.1 percent of reads per site, 0 of 61 refused by the v5 floor, AP-F8-6), steering and the 16,384-day scan PASS, the window layer exact and the chip model's partial-store rows overstated up to 2.3x with the verdict unchanged, partial the line shard s2c waiting on build-1 since 23:09 BST; adv-cache-3 9452c0bf, 0.23, the chain-break or skip BOUND on every row with the pebbling optimum under the hold-every-k curve, none; adv-accept c8a98e46, about 9.2 at 03:25 BST running to its 16-hour line, the bypass FINDING confirmed and bounded (9 few-item hot sets in the tail of 408,067 accepted programs, 0 in 20 random, 1.002x at the largest; all 9 refused by the class v5 floor, 7 clean programs falsely refused among the 12 deepest, 3 mild residuals missed), the stand-in gap BOUND, distinguishers BOUND, the attempts census complete, partial the sweep at 408,067 of 10^6; adv-accept-2 92168536, about 9.0 core-hours and 0.3 pod-hours (the one pod), header grinding BOUND by card measurement (+0.09 percent on an A6000) and by tail (3e-7), one 0.1 percent repeat class for the rule's owners, none; adv-accept-3 7826d2b2, 3.3, exhaustion BOUND (P 1.0e-43), the last-resort path FINDING (correctness, unreachable; closed in class v5), steering BOUND (no property over 1.03x at 1 in 1e6 tries), the program id BOUND with the derivation-string FINDING (fixed on master and in the packs), determinism BOUND, the spec text proven sufficient by two read-backs, the era lever BOUND, partial the steering sweep at 975 of 10^5 full-rule seeds. Totals: about 30.4 box-hours of run across the nine lanes (lease waits excluded) plus about 9.8 single-core SAT hours; pod-hours 0.3 on one RunPod A6000, USD 0.33 in all, rented and destroyed by the fleet lane. The verdict: no lane broke the frozen object; the acceptance rule admits two residual classes of address concentration, both under 1.002x to a chip: the few-item hot sets, closed entire by the class v5 floor (9 of 9) at a 2.4 percent clean-rejection cost, and the diffuse era-stride excess the floor does not reach, routed to the next class with its lever; the weak-day FPGA tail reconciled and closed. Already changed by the pass: the derivation string in the shipped packs, spec 1.4.3 to 1.4.6 rewritten and proven text-sufficient, the chip model's partial-store and pebbling baselines corrected, the last-resort path flagged and closed in class v5. Still to come: adv-cache-2's s2c row and adv-accept's final count, appended when they land. CLASS-V5 GATED (the v5 lane): the full gate on 1d5e5d23 GREEN, 72 checks in 347 s (04:1x UK); class-v5 4a162aba on both mirrors at 04:12 UK with the page's F1 line stating the 04:06 reading (computing, not hung; census.csv only at its end; projected end about 10:00 UK); nothing of the lane's pending on a box or a watch. THE LANE (d) MERGE ON MASTER (the attack-pass lane, 399f8c4d at 03:16:35Z, 04:17 BST; attack-pass 4150f66d, full gate GREEN 45 checks on the branch): F9 PASS on 1c420786 (row and f9-grind.md section (d)), the F1 row as ruled (running, the 03:06Z reading, projected end about 09:00Z, 0 on its live panic path, the harness gap named), the in-house wording kept through a conflict with master's older copy, one founder-strings scrub the gate caught on the pass record (the attribution now "The founder's word"). The harness item: the progress line every 1,000 programs and the flushed partial census.csv (temp file and rename) committed on attack-v5-frozen at 18a9c04a, built on box 2, its known-failed test (a 4,000-program census killed by pid at the 2,000 line, 2,000 rows expected) running under lease pool class adv; the verdict and the push follow. THE SM-SPARSE QUESTION, THE THIRD RUN (run-ca4-pc1-ca4sparse-5090-20261008-b on ca4sparse4, 03:23:45 to 03:48:45Z, exit 0): the card-free check on the card's own exe listed the sparse variant (variants=2 names=base,sp43-w32, rewrite=applied), the race ran it, and NVRTC refused the rewritten kernel on every sparse row: "kernel_bound.cu(370): error: identifier "d" is undefined | igneum_hash_bound_unit(d, ou, baseNonc, mas, i, gid);" (the same for sp170, sp85, sp21, sp11), so the race installed base and every sparse row reads served=base variant_row=FAILED. The hash lane's reading to the research lane: the wrapper's call carries the kernel's parameter names cut by one character (d, ou, baseNonc, mas for ds, out, baseNonce, mask), which points at the rewrite's name capture against the PC's CRLF pack text (the Linux check reported a different byte count for the rewritten kernel): the first card test of the rewrite, the finding kept. The base rows a third repeat of the knee pass (v4 137.06 MH/s at 449.7 W unlocked, 134.23 at 301.4 W at 1,300; v3 136.79 at 329.8, 134.05 at 218.0), the card restored each time. The slot returns to the research lane on an exe whose card-free check compiles the rewritten text through nvrtc for sm_120 (on CRLF input). The queue: the microbench run-ca4-pc1-microbench-5090-20261007 since 03:52:14Z (20 probes of 60 s unlocked, then at the 1,300 lock; about 50 minutes), then the seven packs, the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows. THE CLOSE'S MASTER COMMIT (the crypto lane, sent 04:55 BST for a 04:14 landing, the forty-minute gap its own): crypto-engage c099e818 (full gate GREEN, 71 checks) landed as the mirror's master 2882352c at 04:14:50 BST; the record cites the roll-up and every lane's reading at 00b8cd1b and the close (section 14) at 2882352c; further landings only for adv-accept's final count and adv-cache-2's s2c row. THE FOURTH --variant FIX (the research lane, 03:55Z on build-1 under lease): the cause was not the line endings: the rewrite's parameter capture wrote the substring length as end minus start where the last index needs plus one, so every argument lost its last character on any input; CRLF would have missed the anchors entirely; the rewrite now strips \r first (the same rewritten bytes from LF and CRLF, 22,266 on both) and the capture is right; the card-free check through NVRTC on LF and a CRLF copy, identical lines: variants=2 names=base,sp43-w32; rewrite=applied; call="igneum_hash_bound_unit(ds, out, baseNonce, mask, iw, gid)" params=6 args=6 names_match=1; nvrtc=libnvrtc.so.12 arch=sm_120 compiled=1 image_bytes=36256; the failed case the 03:23Z card line. Exe igneum-worker-cuda-ca4sparse5.exe sha256 a4550202b301faf22f5329c2ab4fa1c0aa6695dbdaf31c974f316dca2524d7d6, with the hash lane; the commit on the mirror after 3ac5d20a; the slot after the microbench and the packs. The three failures gave three repeats of the knee pass (the v4 premium 133.9 to 145.3 W unlocked, 90.5 W at 1,300 MHz) in the file's 20.3a. ADV-ACCEPT OFF BUILD-1 (04:5x BST, the coordinator's placement rule): adv-accept runs on to its 16-hour line (about 10:15 BST, 10.6 box-hours at 04:54, the reading saturated) in box 2's gaps under the mechanical yield, its build-1 shard ended at the frontier and its waiter withdrawn, so F1's census keeps build-1 (its 10:00 BST projection assumed load 21) until census.csv writes; adv-cache-2's four-minute s2c shard the one exception. Confirmed by lease status at 04:57 BST: build-1 holds F1 (release, 16 cores) and adv-cache-2's s2c (32 cores, its last shard) and nothing of adv-accept's; adv-accept's four holders and waiters on box 2, where the attack-pass lane's flush test waits at 1 free behind them (the same class, no yield case); the coordinator's placement rule: one adv-accept holder ends at its frontier for the flush test (a 4,000-program census, minutes), since adv-accept's reading is saturated and the harness fix gates the morning's F1 rerun class. Done at 04:59 BST: adv-accept's sweep-s05b ended at its frontier at 04:58:50 (46,460 rows kept) and the flush known-failed test took the 16 cores at 04:58:55; the shard re-queued behind it. ADV-CACHE-2 CLOSED (05:0x BST): its last shard s2c ran 04:56 to 04:59 on build-1 (PASS at 2^33 reads, control-level), so the line census totals 2^36 reads over 464 chain days with every statistic at the control's values; final box-hours 2.35 of run (0.08 a duplicate windows run by its build-1 drain, recorded), pod-hours 0; tip bfc3746c on build/adv-cache-2, igneum-pow identical to 017e7037; the biased-site class (AP-F8-6) and the window-layer pricing stand; section 14's row updated on crypto-engage, landing with adv-accept's final count. Eight of nine lanes at their end; adv-accept alone runs to its 16-hour line about 10:15 BST. THE CENSUS HARNESS'S PROGRESS LINE (the attack-pass lane, attack-v5-frozen 18a9c04a on the mirror): the attack-f1 census prints a progress line every 1,000 programs (count, elapsed, running failure count) and flushes a partial census.csv at the same cadence through a temp file and rename; the known-failed test on box 2 under lease pool class adv (binary 14180ef4...): a 4,000-program census killed by pid at the 2,000 line at 04:08:27Z (05:08 BST), census.csv holding exactly 2,000 rows, no tmp file, lease exit 143; PASS (the old harness's known fail zero rows); record f1-shadow.md section 12 on the mirror's attack-pass at c99f147f (riding the F1 record merge); a side reading: 1,000 programs per 286 s on 16 cores, about 4.6 core-s per program, confirming F1's build-1 projection of about 09:00Z (10:00 BST); the running 10^5 census stays on the old binary, every census after it on the new. F1 PASS ON CLASS V5 (the attack-pass lane; class v5 at 1c420786, pairing e5a4ac5978462156, build-1 under lease pool class release, 16 cores; census.csv written 04:20Z, 05:20 BST, after 20,774 s of census, 5 h 46 min, earlier than the 09:00Z projection as build-1 emptied): 100,000 of 100,000 programs through the string-seed draw with the (c''') floor; instructions saved min 0.000 percent, mean 0.623, max 4.688 (the worst seed attack-f1/95060: 6,912 to 6,588); chip-view ops saved mean 0.520, max 4.783; programs over 5 percent 0, over 10 percent 0; soundness: differential mismatches 0 of 100,000 (8 random states each), verifier mismatches 0 of 100,000; 0 panics; the histogram of saved in 0.5 percent bins from 0: 55,241, 20,597, 11,762, 9,851, 1,484, 656, 259, 133, 13, 4, 0, 0. Against the v4 10^5 (max 5.078, the AP-F1-1 letter miss): the v5 tip's worst program sits 0.39 points under the 5 percent letter and the top two bins are empty. F1 PASS on 1c420786 by the letter and at honest-compiler parity; the redundancy gate holds for the 0.3.24 move; AP-F1-1's v5 half FIXED-AND-PASSED at this count; record f1-shadow.md section 13 and the lane (d) row, merged to master next. The attack board on class v5 is complete: F4 PASS (8ca66afa), F8 PASS, F9 PASS, F1 PASS; the rest not re-run by rule. CLASS-V5'S F1 ROW (the v5 lane, class-v5 1095eaa8 on both mirrors at 05:24 UK): the page's attack row reads F8 PASS with the known residue, F4 PASS, F9 PASS, F1 PASS on the full 10^5, the rest not re-run by rule; the full gate running on 1095eaa8; nothing else of the lane's open tonight. THE CA4 PACKS ON THE 5090 (run-ca4-pc1-packs-5090-20261008-b, exit 0 at 04:22:54Z, 579 s; the 5090 alone through the installed worker, the lock and reset through the helper, every self-test PASS at both states): the int8 mma tile prototypes' inline PTX compiles under NVRTC 12.8 on sm_120 and matches the CPU reference (mm128 270e4ae36b37e9a1, mm512 a1c1ff3148d775d1, mm1430 8e9b7066239d35d1), as do both per-load exports (404cad3b3399f9b3, ee5d7c71180e5ea7), sh256x27 (3d2e8245cc084d07) and the mx8-genesis control (7c28cfb06c5c65a9). Rows (MH/s / W / MH/W), unlocked then at the 1,300 lock: mx8-genesis 137.54/311.0/0.442 then 127.32/213.0/0.598; sh256x27 137.51/462.2/0.298 then 126.93/295.8/0.429; shl256x27 (unsound, an energy reading only) 158.62/472.8 then 145.65/299.4; shl256x27_v2 (unsound) 135.90/448.3 then 126.04/282.9; mm128 137.45/332.9/0.413 then 127.01/217.8/0.583; mm512 137.50/369.4/0.372 then 127.07/235.4/0.540; mm1430 137.45/457.7/0.300 then 126.87/284.5/0.446. Consequences: the rate is memory-bound on every sound pack at both states (within 0.5 percent of the control); the tile premium over mx8 is 21.9 / 58.4 / 146.7 W unlocked for 128 / 512 / 1,430 tiles (0.103 W per tile, linear) and 4.8 / 22.4 / 71.5 W at the lock (0.050 W per tile), so at 1,430 tiles the tile block costs what the ALU shadow costs (151.2 W unlocked, 82.8 at the lock) and the lock halves it the same way; the first per-load export's 15 percent higher rate is its duplicate reads landing in L2 (the unsound construction), the fixed one 1.2 percent under the control. The research lane has the rows for 20.3 and 20.4; the tile class's premium per tile is now a measured number on the 5090 and its Apple cost (35 to 78 percent of rate) the open side. The microbench -b since 04:23:23Z, then the SM-sparse rerun on ca4sparse5, the 5080 Ember tune, the 9070 XT tune pass, the hot table. THE CA4 PROTOTYPES' FIRST SENTENCE ON MEASURED ROWS (the research lane, counter-asic-4 on the mirror after 1428dd3c; sections 20.3 and 20.4): neither prototype beats class v4's premium; the tile block matches it at the same hash rate (mm1430, 11,440 int8 tiles per hash: 146.7 W over class v3 against the ALU shadow's 151.2 W unlocked, 71.5 against 82.8 W at the 1,300 lock, the rate memory-bound within 0.5 percent) and beats class v4's chip edge only at the pessimistic end (about 2.2x against 3.5x), not at k = 1 (2.2x either way), because the 5090's measured cost per int8 MAC (0.091 pJ unlocked, 0.048 at the lock) sits inside what a 5 nm MAC array costs anyone (a claimed test-chip figure), so a chip's k on tile work is at or above about 1 where on ALU work a fixed datapath reaches 0.3 to 0.5; the per-load placement dead as a construction (its energy rows 13 to 14 W under the whole block for the same instructions; the first export 15 percent faster from duplicate reads served by L2). Against the tile block as a class: the verifier (AVX2 0.047 us per tile per unit; mm1430 10.14 ms with the sibling loaded on the box's core, a 0.14 ms miss of the gate; scalar 13x worse; NEON unwritten), the Apple tier (35 percent of rate at 1,024 tiles, 78 at 4,096), the AMD layout unverified. No served number moves; the SM-sparse reading still owed (three failed runs, the fourth exe queued after the microbench); the op-mix re-weight held, the served 3.4x standing. The k column's basis (the research lane, counter-asic-4 after 781cb395): the 1,430-tile point is the one chip-model-v3 5.11's tensor-tile k column was priced at (15.2 set R about 1,430 from the 4090's 0.056 pJ per MAC to carry the ALU shadow's 0.654 microjoules; 11,440 tiles per hash), and the 5090 reads 0.091 pJ per MAC unlocked and 0.048 at the 1,300 lock there, so the column (2.1x at k = 1, 1.6x at k = 1.5) has its GPU-side cost measured at the premium it was priced for (1.067 microjoules unlocked, 0.564 at the lock, against the ALU shadow's 1.10 and 0.652); the Apple cost the open side; nothing served moves. F1'S RECORD ON MASTER (the attack-pass lane, merge 54b896f3 at 04:29:30Z, 05:30 BST; attack-pass 0610892b, full gate GREEN on the branch, pushed on try 2 after a ref race): the F1 row (PASS, AP-F1-1 FIXED-AND-PASSED on v5 at 10^5), f1-shadow.md sections 12 (the flush and its known-failed test) and 13 (the 10^5 record with the worst four programs at 4.688, the attempt histogram, the v4 comparison). Lane (d) complete: F4 PASS (8ca66afa), F8 PASS (61 of 64 at 1c420786), F9 PASS (10^5 seeds, 0 exhausted), F1 PASS (10^5 programs, 0 over the letter, 0 mismatches); both 0.3.24 gate lines PASS on the full 10^5. Box-hours for the lane (d) tail: build-1 F9 ten chunks of 4 cores at about 14,480 s each (about 161 core-hours), F1 16 cores for 20,907 s (93 core-hours), F4 12 cores for 379 s; box 2 F8 64 seeds (the earlier record) and the flush test 16 cores for 3,352 s (15 core-hours, most queued); nothing of the lane's on either box. THE V5 LANE'S NIGHT CLOSED (05:3x UK): the full gate on class-v5 1095eaa8 GREEN, 72 checks in 345 s; the freeze 1c420786 (0.3.24's pairing), the post-freeze line through 1095eaa8 (0.3.25's: AP-F4-1's agreed form, the verified last resort, the record), every proof green on the tip, the attack board on class v5 at F8 PASS with the known residue and F4, F9 and F1 PASS, the kit's fingerprint equal on CUDA, Metal, Apple OpenCL and the RX 9070 XT, the Intel row not measured; nothing of the lane's pending. THE SM-SPARSE READING EXISTS (run-ca4-pc1-ca4sparse-5090-20261008-c on the research lane's fifth exe, exit 0 at 05:12:48Z, 2,219 s; every variant served on the card, served=sp-w32 with sparse_blocks=N, the rewritten kernel compiled under NVRTC on sm_120 and bit-exact, every fingerprint equal to the Mac's; the 5090 alone, the lock and resets through the helper, the drift check equal to the start): a quarter of the SMs (sp43-w32, 43 of 170) holds 98.2 percent of the class v4 rate at the SAME draw (134.58 MH/s at 460.1 W against base 137.07 at 450.8) and 99.8 percent of the class v3 rate at 4 W less (136.55 at 309.8 against 136.77 at 313.9); the draw falls only when the rate falls (sp21-w32: v4 70.75 MH/s at 327.4 W, v3 132.82 at 303.4; sp11-w32: v4 37.34 at 250.9, v3 100.14 at 274.5), and watts minus idle per MH/s never drops below base (v4 2.75 W per MH/s base, 2.87 at sp43, 3.58 at sp21, 4.74 at sp11; v3 1.75, 1.73, 1.73, 2.00); the persistent shape on the full card (sp170-w32) within noise of base; at the 1,300 lock the sparse shapes collapse (v4 sp43 64.3 MH/s at 208 W, compute-bound). CONSEQUENCE: the class v4 premium is the shadow's ALU work itself, not SM-count overhead (150 W at sp43 against 137 W on the full card), so an SM-sparse miner kernel saves nothing and the candidate is dead by the research lane's own rule; the op-mix re-weight stays the open lever, and its served candidate ("2.9x with a core three times better") now has its SM-sparse read: the premium does not move with the SM count, so the re-weight's case rests on the op mix alone and goes to main with that reading. The microbench -c since 05:13:41Z with the pack argument; then the 5080 Ember tune, the 9070 XT tune pass, the hot-table ldcs rows. RANK 2 CLOSED IN THE CA4 FILE (the research lane, 20.3b, counter-asic-4 on the mirror after 6b21e887): the SM-side power is the work's, not the SM count's (the shadow's ops cost the same on 43 SMs as on 170; idling SMs saves nothing); the number kept: the class v4 premium at sp43 unlocked 150.3 W over v3 at a held rate, equal to the full-card premium, so the premium is the ops' energy whatever carries them; the premium-free floor rests on the operating point alone; the op-mix re-weight's hold is main's to lift or keep, the SM-sparse reading saying nothing against it; the microbench rows still owed. THE OP-MIX RE-WEIGHT: HOLD (the research lane's case for main, 06:2x BST; the SM-sparse row at counter-asic-4 954c4053, section 20.3b): the served sentence stands ("At launch the strongest chip in our public model reaches 2.1x per joule against an RTX 5090 with a core as good as a GPU lane, 3.4x with one three times better, under class v4 from the first block"; the re-weight would move "3.4x" to about "2.9x", the shuffle-and-multiply-heavy shadow raising the chip's k floor from about 0.32 to 0.46). The basis: the re-weight touches only the pessimistic column, a model on both sides (the chip's k floor an estimate from wire and datapath figures, never measured; the GPU's energy per op by family unmeasured until the microbench rows land, the shfl, mul and arx probes being that measurement); the SM-sparse reading says nothing for or against it (the premium is the ops' energy, which both mixes pay); the night's measured finding on bounding k points to the int8 tile block (the same premium at the same rate with a k floor near 1 from the GPU's own tensor core, 0.048 to 0.091 pJ per MAC), of which an ALU re-weight is the weaker version at the same class-change cost (the 95 percent rule, the six gates, a new program stream, Apple paying shfl at 1.91x per op); a reader gains 0.5x on a modelled pessimistic bound and loses nothing measured from the hold; the 2.1x at k = 1 rests on four repeats of the knee pass (82.8 to 90.5 W at 1,300 MHz). The condition that re-opens it: the microbench reading the 5090's shfl and mul rows at or under the add's pJ per op together with a measured chip floor, and then it re-prices against the tile block, not the served line. Main's word lifts or keeps the hold; the coordinator's reading agrees with the hold. THE MICROBENCH ON THE 5090 (run-ca4-pc1-microbench-5090-20261008-c, exit 0 at 05:56:29Z, 2,484 s; the research lane's per-block micro-benchmark, 20 probes ran, 0 skipped or failed, at the unlocked clock and at the 1,300 lock, every probe's checksum equal at both states, the card back at the driver default). Picojoules per counted op as (watts minus the sleep row) over G ops per s, unlocked then at 1,300: the ARX integer path 11.3 then 6.2; int_mul 13.9 then 8.3; mulhi 39.6 then 21.0; prmt 22.3 then 11.5; lop3 24.1 then 13.0; shfl 55.8 then 29.4; fp32 fma 9.2 then 5.2; fp16x2 fma 5.1 then 2.6; int8 mma m8n8k16 4.1 then 2.2; int8 mma m16n8k32 1.36 then 0.83; fp16 mma 3.2 then 1.7; bf16 mma 2.9 then 1.5; fp8 e4m3 mma 1.5 then 0.8; the memory rows per read: L2 chase 2.4 nJ unlocked and 1.4 nJ locked, DRAM chase 10.9 nJ and 8.7 nJ, texture point 2.3 nJ, texture linear 0.19 nJ; the sleep floor 120 W unlocked against 75 W idle (the residency cost, flagged). CONSEQUENCES: (1) the op-mix re-weight's re-opening condition (the 5090's shfl and mul rows at or under the add's pJ per op) is NOT met and is now a measurement: shfl costs 4.9x the ARX op and mul 1.2x, mulhi 3.5x, so the GPU pays more for the heavier mix and the hold on the served 3.4x stands on measured rows, not a model; (2) the tensor-core int8 MAC costs eight times less per counted op than the ARX op the hash is built from (1.36 against 11.3 pJ), the direction a chip cannot beat by as much, which is the tile block's case restated in measured picojoules and the CA4 file's next row. The queue: run-ca3-pc1-ember-5080-20261007 (the installed app's Ember tune on the 5080, the app's own path, not elevated) since 05:57:18Z, about 30 minutes; then the 9070 XT tune pass and the hot-table ldcs rows. A CORRECTION FROM THE MICROBENCH'S TILE ROWS (the research lane, 07:0x BST; counter-asic-4 on the mirror after 954c4053: 15.1a, the corrected 20.3 and 20.4, the first sentence, the ranking): a mma.m8n8k16 tile is 1,024 multiply-adds per WARP, 32 per lane, so a hash does 32 MACs per tile, not 1,024; the lane's 15.2 and 20.3 and the 6 October 4090 figure chip-model-v3 5.11's tensor column was priced on were wrong by that factor. Corrected: the 5090's int8 MAC at the ALU shadow's premium costs 2.9 pJ unlocked and 1.5 pJ at the 1,300 lock (the packs job, 366,080 MACs per hash), the microbench's dependent u8 tile 4.1 and 2.2, the wide s8 m16n8k32 tile at 80 percent of peak 1.36 and 0.83; the 4090's "0.056 pJ per MAC" of new-pow 5.1 is 1.8 pJ. Against a 5 nm MAC array (0.04 to 0.4 pJ per INT8-class MAC, claimed) the chip's k on tile work is 0.03 to 0.3, BELOW the ALU shadow's 0.3 to 0.8: at the same premium the tile block leaves the chip 3.5x to 6.7x where the ALU shadow leaves it 2.1x to 3.5x. So the tensor shadow is the WORSE lever and rank 3 is dead; the 6 October verdict on scheme B stands for the right reason; the coordinator's 07:0x line to main calling the tensor side "the next class's one live direction" is withdrawn by this correction. Chip-model-v3 5.11's tensor column (its premise, a chip's MAC no cheaper than the GPU's, false by 4x to 30x on the public figures) and new-pow 5.1's per-MAC line are to be corrected (the coordinator's next commit); nothing served rests on either. The other rows, pJ per counted op unlocked then locked (the sleep floor 120 and 66 W subtracted; idle 75 and 60): int add-xor-rotate 11.3 / 6.2 (the shadow's 10.8 / 6.4 on the packs job: the two instruments agree); mul 13.9 / 8.3; mulhi 39.6 / 21; prmt 22.3 / 11.5; lop3 24.1 / 13.0; shuffle 55.8 / 29.4 (the card's dearest instruction, 5x the add: the re-weight's GPU side is against it, the hold measured); fp32 FMA 9.2 / 5.2; L2 hit 2.4 / 1.4 nJ per read against a chip's SRAM 0.2 to 0.5 (the hot-table lever dead on the GPU side; the ldcs rows kept as a record); the DRAM dependent read 10.9 / 8.7 nJ per read, the whole card's marginal against the chip memory's 2.0, section 2's floor seen per read. THE NIGHT'S CLOSING SENTENCE ON MEASURED ROWS: nothing on the 5090 reads k above 1; the ALU shadow at the operating point's knee is the floor, 2.1x at k = 1 for 82 to 90 W, measured four times; the two prototypes, the SM-sparse kernel, the hot table and the re-weight are all closed on measured rows. The CA4 file's commits (the research lane): 15.1a at 71fd465b (the microbench row, the residency cost 45 W at the stock clock before any instruction issues), 15.1b the commit after it (the re-weight's re-opening condition not met and measured; for 2.9x to be the honest pessimistic column a chip would have to pay 0.42 to 0.52 of the GPU's cost per shuffle, 22 to 28 pJ for a 32-lane crossbar move, above the wire figure and unmeasured; not a candidate on measured rows); the corrected 20.3, 20.4, the first sentence and the ranking at 71fd465b; the hot-table ldcs rows a record only. The lane closed for the night. THE TWO INTERNAL CORRECTIONS LANDED (the coordinator): chip-model-v3.md 5.11's k-column paragraph carries the dated correction (the tensor-tile column withdrawn; the shipped row unchanged) and docs/analysis/horizon/new-pow.md 5.1's per-MAC prose and the scheme B verdict carry the 32x correction with the reason (a tile is 1,024 multiply-adds per warp, 32 per lane), both citing counter-asic-4-research.md 15.1a at 71fd465b; new-pow's 5.1 table column and its 5.3 chip rows keep their original numbers under the note (the Horizon lane's file; a table rewrite is its own). THE 5080 EMBER TUNE (PC 1, app 0.3.20, 06:05Z, 07:05 UK; run-ca3-pc1-ember-5080-20261007): Tuned 60.3 MH/s at 123 W, 0.489 MH/W, clock_cap 2936, source=climb; read against the clock-lock grid, the app's power-limit climb lands at 0.489 MH/W where the 1,000 MHz lock gave 71.1 MH/s at 103.7 W (0.686), so the core-clock lock is worth +40 percent per watt on the 5080 over the stock climb (and 15 percent more rate): the case for the 0.3.24 core-clock knob shipping. The per-point curve rows were lost to a cast fault in the hash lane's curve line (job exit 1, 386 s; the app unaffected), fixed at 261d7c54. Live on PC 1: run-ca3-pc1-ember-9070-20261007 (the 9070 XT tune, 45-minute cap), then the hot-table ldcs rows. THE KNOB ON release-0.3.24 (the shipper, 07:1x BST): the core-clock knob 74585c91 cherry-picked onto release-0.3.24 at e181f497 with the efficient-point ceiling beside it (the plan-count test updated, b6e2845f; the app gate GREEN 294 + 35 + 8), the DMG re-cutting on it under the lock, the UI lane's drawing of the lock fields asked onto that tip, the measured Ember sentence in the 0.3.24 section with the job ids and the knee rule; the pin dfbd1e10 and the kit e6c088bb stand; the move on main's morning minute. THE 9070 XT EMBER TUNE (PC 1, app 0.3.20, 06:11Z, 07:11 UK): one row only, baseline 18.9 MH/s at 202 W, 0.093 MH/W, the chosen point "80%": the app has no knob on AMD in 0.3.20 (power_pct 0, clock_cap 0, limit 0.0 W), so the tune measures the stock point and stops; the 9070 XT cannot be made efficient by the app today, and at 0.093 MH/W it sits at a sixth of the 5090's locked 0.58 MH/W (the app's stored 5090 curve: 1,390 MHz, 118.6 MH/s at 204 W, 0.580) and a seventh of the 5080's locked 0.686; the AMD watts owed from the G1 ladder are on record from the app's reading, 202 W at 18.9 MH/s (the bench row's watts for the 9070 XT once the sampler question is closed). A morning item for the ledger and the app: an AMD core-clock knob (rocm-smi or ADL) is the only path to a 9070 XT efficiency figure. The job exited 1 on the hash lane's row count (fixed, 43f0918c); the app unaffected. The hot-table kit on PC 1 (fetch done 06:20Z); run-ca4-pc1-hot-ldcs-5090-20261008 publishing, the last PC 1 job on the list; rows when it closes. THE 9070 XT BENCH ROW ON MASTER (the site audit lane, ffb7d8ff at 07:35 BST, commit 47690be7, gate GREEN 72 checks): watts 202 ("202 stock"), mh_s 18.92 ("18.9 (18.8 to 19.2 on the G1 ladder)"), 0.093 MH/W, tuned "no lever: the app has no AMD knob today (an AMD core-clock knob through rocm-smi or ADL is the path, a morning item)", the class v4 cost unchanged (+2 percent of rate, 6 October), the note naming the app's own power reading at the stock point with the date and the status row, Hive values none; /miners rebuilt at 35 rows; no deploy; the audit lane closed for the night. The bench table's AMD watts are no longer owed. THE HOT-TABLE LDCS ROWS (the hash lane; the mirror's master at c09dfee4, 08:12 UK; bench-log entry "8 October 2026, the hot-table packs on the RTX 5090", 36 rows all PASS; run-ca4-pc1-hot-ldcs-5090-20261008b exit 0 in 1,372 s, clocks reset): ldcs equals base everywhere (a dead lever, no ldcs rows owed); the 1,300 MHz lock costs the hot packs 2 percent of rate against mx8's 7.5 while taking a third of the watts off every pack, so the hot family is latency-bound on the table; per watt at the lock hot64k8 reads 0.734 MH/W against the mx8 control's 0.602 (the control matches the v4 grid's 0.60, the two passes agreeing); the research lane has the rows with the resistance question (a cheaper GPU hash is a gain only if the saving sits in the memory path; the microbench's L2 row at 2.4 nJ against a chip's SRAM 0.2 to 0.5 answers it on the chip side). THE PC 1 LIST MAIN SET IS CLOSED: the 5080 full grid, the third 5090 pass, the SM-sparse reading, the two Ember tunes, the hot table, all on measured rows. Still open on the hash lane's side: PC 2's Arc B580 class v5 fingerprint on the shipper's clear (a Windows entry first), and the F8 tail p4/p8/p10/p34 as a Mac measurement under the lock script, held until main lifts the Mac rule for one job (a morning item). MAIN'S MORNING WORDS (09:3x BST on 8 October; the night's silence main's own, recorded as such): (1) the look: the design pass lands now through its gate (ca3-coord rebased onto master 715c79b2 as five site commits, tip 0d212a2a; the box sweep GREEN on the same content), the steward deploys master after it; (2) the floor sentence goes on evidence row 17 as well as /ledger in the exact wording (the audit lane's row); (3) CA4 parked with no live candidate, the record carrying the measured close; the only new work the AMD core-clock knob for the app, a 0.3.25 item on the update-return lane; (4) the F8 tail p4/p8/p10/p34 on the Mac: the Mac rule lifted for that one job, one at a time, a few minutes, the hash lane running it now; (5) the move: the shipper has route (A) with the minute 10:45 BST; the Arc B580 job has PC 2 clear and publishes now. THE BUILD-SERVER LANE'S HONEST STATE (09:31 BST): it ran nothing between 22:54 BST and 09:31 (its turn sat on a backgrounded gate chain; the overnight asks reached no tool call); the /miners captures it owed never ran (its export step failed at 22:52, "not a tar archive", a branch commit's git archive over ssh needing the ref fetched on the box side; the CI steward took the captures and the sweep instead); its last master-only deploy dde2dcd2 at 22:49 BST; it deploys master's tip on main's confirmed order after the design pass lands, and builds the 0.3.24 Windows pair and hive on the shipper's word. THE DEPLOY AND THE PAIRS (the build-server lane, 09:3x BST): a master-only deploy of 715c79b2 running from 09:32 with the checks after; master's tip deployed again when the design pass and the row-17 commit are on it, the served sha and minute to the record; the 0.3.24 seed, Windows and hive pairs built on the MORNING pin (the node lane's re-cut from the 10:45 minute) under lease class release, the hands pair the node lane's, the shipper keeping the move and the minute; the seed-class ship path proven on dfbd1e10 first so the morning pin's builds run clean. THE FOURTH CUT (the node lane, 08:33:18Z, both mirrors): 5b673577 on release-0.3.24-node = dfbd1e10 with program_class_v5_activation_daa 68,400 (epoch 19), nothing else, the three heights staying; the read from build-1's restarted seed on 27632 at DAA 56,329 at 08:33:18Z (1.0 DAA/s overnight); the publish DAA at 09:45Z about 60,630, plus 7,200 is 67,830, the next boundary 68,400, landing about 11:54:29Z (12:54 BST); the floor holds for a publish up to DAA 61,200 (about 09:54:29Z, 10:54 BST); the gate set running since 08:33:20Z (build and consensus at gate priority, the five suites, both canary sets, the fast-time pair about 14 minutes from the artefact), the pin line due about 08:52Z (09:52 BST); the crossing read from build-1's seed after the move (restarted on the pin in the shipper's move); the TESTNET_PARAMS v5-at-0 re-cut after a clean crossing. THE ARC B580 READ (the hash lane, PC 2, 08:35:59Z, 09:36 UK): no fingerprint, match False against 82b19cbde8557ea5; the kit worker fails its self-test on the Arc before any batch ("vector lanes 96 bad of 96 ... device 729ebd46376e2851 expected e552166a03298f7f" on the v5 pack) and 96 of 96 on the v4 control too (device 11bdacb6ee4108c2 expected dfbc8db1c06dacd8), every cache and dataset FNV matching; so the Arc's bound-kernel evaluation is wrong on Intel OpenCL, not class v5; the kit is good on five of six platforms; under main's rule the Intel kit holds out of 0.3.24 with the crossing time 09:36 UK for its page row. The open question, put to the shipper (PC 2 its now): whether the installed 0.3.21 worker's own self-test passes on the Arc with the devnet pack, which decides regression (the kit worker) against never-worked (every Arc rate row on record would then be a FAIL row and the bench table's Intel row a held row). The F8 tail job on the Mac started under the lock script, one seed at a time. THE DESIGN PASS ON MASTER (the coordinator, on main's word; merge 3a4ba893 at 09:39 BST): ca3-coord rebased onto 715c79b2 as five site commits (tip 0d212a2a: the design pass e2674675, the phone grid 592488a4, the six-column row 7c44354f, the lead cell's wrap c11baf30, the width rule scoped to desktop 0d212a2a), site/build.mjs and site/miners.html only, the page rebuilt at each commit so it carries the 5080 and 9070 XT rows under the design; the Mac's gate GREEN (the sweep skipped there), the box sweep GREEN on the same content at 5158276c with the four dark captures under /srv/artefacts/captures/ca3-coord-5158276c/; the build-server lane deploys master's tip after the audit lane's row 17 and Arc-note commit. THE MOVE'S READINGS (the shipper, 09:4x BST): the pin 5b673577's node-lane pair on build-1 (igneumd a3b1a2c9, igneum-miner cfa9f5ca, igneum-pow src 8 paths), its tarball served at fleet/5b673577-node-lane.tgz (c5b85b09, 27,495,480 B); the gate script carries cfa9f5ca and dry-ran at 32 of 35 reachable (dn3-pool-a destroyed by the fleet's waste pass, dn3-relay and p2-4090-1b behind dead proxies); the move file m5b67-1 written to take the pin line's digest and placed at at_epoch 0 the moment that line reads green (about 09:52 BST), the gate line applied in the same minute, the minute the last FETCHED plus ten (the founder's word: no waiting on the clock; 10:45 the ceiling, 10:54 the floor's); the Mac entry re-cut on the knob display (knob-24 2c4dc617 merged, app gate 294 + 35 + 8, UI 88) and published with the hive at the minute; the installed worker's self-test on the Arc with the Intel lane; the eight boxes on bc5945fe with miners off read by the fleet lane and taking the move with the rest. (The fleet lane is answering again this morning.) THE PIN LINE ON 5b673577 (the node lane; every gate green at 08:39:15Z, 09:39 BST): 5b673577 on release-0.3.24-node (both mirrors) = dfbd1e10 with program_class_v5_activation_daa 68,400 (epoch 19), nothing else; pairing igneum-pow 1c420786; build 08:34Z rc 0 at gate priority (igneumd a3b1a2c96a9767ee..., igneum-miner cfa9f5ca..., /srv/artefacts/0324-5b673577/node-lane); core 175, exec 47, miner 28, p2p-flows 38, pow 19, consensus 134 at gate priority; the Devnet 3 canary set (08:34:58Z to 08:36:38Z): digest cc9026909eddbadb46912513e9b748dffd8e5c3583cd976857a8afdab2d772f9 on igneum-devnet-3 from ba75bf6f, object version 6 stamped, the override file refused, shutdown 573 ms, two empty nodes handshaking on cc902690, the shared-devnet dialler rejected, a 2720d8d2 node refused both ways; the testnet canary b2e856ed unchanged. The floor from the seed's read: the publish DAA at 09:45Z about 60,630, the floor about 11:54:29Z (12:54 BST), holding for a publish up to DAA 61,200 (about 10:54 BST); the fast-time pair's SUMMARY due about 09:55 BST, inside 10:35; no slide to 72,000 needed. A correction: node1-dn3's 28670 no longer answers (its process gone), so the DAA reader is build-1's seed on 27632, restarted 02:00:09Z on the shipper's word and in step with the observer on 28650. dfbd1e10 void as a pin. THE F8 TAIL ON THE MAC, p4 (the hash lane, under the lock script, one seed at a time; the Mac rule lifted by main for the one job): p4 reads 1.2169x over the window model (the gate's 1.2167x reproduced), hot-set clear at every f, the attribution on one site: site 1 (instr 8, source r2, window 2^22 items, offset 1, the last base writer mad at instr 4) carries 1.448 percent of the hot reads against 0.107 flat, index entropy 13.74 of 14 bits, the largest 256-item bucket 4.5x its window expectation, every other site at its flat share; the hottest item 0x4000e7 at 355 reads with no predicted source (no saturation, no lossy writer), so the residue is a window-2 index with a quarter-bit short, not a lossy source; p8, p10 and p34 running (about 90 s each), the four rows and the record line (the bench log or AP-F8-1's tail paragraph) at the close. STANDING RULE FROM THE FOUNDER (09:5x BST on 8 October, after the night: "this cannot happen again"), three parts: (1) every ask any lane sends main carries a default action and a deadline; silence at the deadline means the default, never a stand-down; passed to every lane the coordinator runs; (2) the coordinator mirrors every deadline the shipper holds today (the pin, the apply, the move minute, the publish, the Windows chain, each floor ceiling): if the shipper has not acted within five minutes of its own clock the coordinator sends it the word and tells main; if it is silent for 25 minutes the coordinator takes its next action itself with the shipper's runbook and tells main; (3) a 20-minute heartbeat wakes main regardless of notifications. The night's cost the rule prices: three floors lost (28,800, 32,400, 39,600) and the Mac entry stood down for want of one word while every gate was green; two lanes dark for ten hours. THE MOVE FILE PLACED (the shipper, 09:42:14 BST): m5b67-1 (5b673577, digest cc9026909eddbadb, at_epoch 0, the node-lane tarball c5b85b09) placed and served, its signature verified against the fleet key; the gate line (cfa9f5ca into every reachable box's pack list) applying from 09:42; the minute the last FETCHED plus ten once the fast-time SUMMARY reads PASS (about 09:55); the Intel lane a0aa97b17380bd614 holds the Arc self-test question with the audit lane on its recipients. THE NODE LANE'S OPEN ITEMS UNDER THE RULE (09:4x BST): the crossing read at DAA 68,400 from build-1's seed by 13:10 BST (else the observer on 28650 or the reader on 28690); the TESTNET_PARAMS v5-at-0 re-cut lands through the full gate set at 13:30 BST unless main says otherwise by 13:15 (a red crossing read means no re-cut); any later floor losing its margin is cut from the next named minute by dn3-floor-cut.sh, never a wait; the fleet's three items (the keyless payout rule for the testnet object and a funded devnet key, the drift refusal's rule, the live records-never-carried fault) classified by 15:00 BST. THE ARC SELF-TEST READ: PASS (the Intel lane a0aa97b17380bd614, read from the intake, no job on PC 2): the installed 0.3.21 igneum-worker-opencl.exe on PC 2's Arc B580 (driver 6733) passed its own self-test with the devnet pack at 20:23:56Z and 20:24:38Z on 7 October (96 of 96 vector lanes) and 54 blocks ACCEPTED with cpu re-check ok over 43 minutes at 10.58 MH/s wall (accepted 54, rejected 0 at 21:06:33Z); the shipped 0.3.20 worker read 96 of 96 on every pack on both PCs earlier that day. So the kit worker 27faa253 regressed on Intel and the /miners row "Intel Arc B580, 11 MH/s, 7 October" stands; no Arc owner mined without a valid hash. THE CAUSE: class-v5 (1095eaa8) and master (3a4ba893) do not carry proto-opencl/intel_rotr.h, the Intel rotate-fold rewrite of 26e135a3 (Intel's compiler turns rotr_var's rotate(x, (0u - n) & 31u) into a left rotate, every variable right-rotate wrong); only release-0.3.23 (710e1fea) and release-0.3.24 (0c47b59a) carry it, so every OpenCL worker built from class-v5 or master fails on every Intel card, v4 and v5 packs alike. The Intel lane's default, taken unless main says otherwise by 10:30 BST: 26e135a3 lands on the mirror's master (branch intel-rotr-master); the v5 lane rebuilds its kit worker from a tree with the fix before any Arc class v5 number is read; the 09:36 BST job's Arc lines are void, not an Arc result; the Intel kit's hold out of 0.3.24 stands until the rebuilt kit's fingerprint reads on the Arc. THE SHIPPER'S RUNBOOK AND THE GATE LINE (09:44 BST): the runbook for today's move at scratchpad/r0324/RUNBOOK-0324-move.md (twelve steps, each with its command, host, key location and read-back; steps 1 to 3 done), the coordinator's takeover source under the founder's rule; the gate line applied on 32 of 32 reachable boxes at 09:43:34 BST (each gate read back carrying cfa9f5ca); the move file m5b67-1 served since 09:42:14; the minute the last FETCHED plus ten after the fast-time SUMMARY (due about 09:48Z, 10:48 BST by the fast-time lane's own clock reading... the SUMMARY due about 09:5x BST), inside 10:54. THE RULE PASSED TO EVERY LANE (09:4x BST): the shipper (its runbook written), the node lane (its three defaults armed: the crossing read by 13:10, the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15, any later floor cut from the next named minute), the fast-time lane, the build-server lane (the deploy at 10:00, the three pairs with their minutes), the hash lane, the audit lane, the v5 lane (the kit rebuilt on the Intel fix), the Intel lane (its default at 10:30), the update-return lane (the AMD knob's branch by 12:00), the fleet lane (the FETCHED count by 10:05), the crypto lane (adv-accept's count at 10:15, section 14's last landing by 10:45, both armed on hard clocks), the attack-pass lane (the F8 tail's attribution by 11:00), the research lane (parked, its file at fb61ed4b) and the CI steward (the cut-over ask with a default on the first unsuspended read). THE AMD KNOB OPENED (the update-return lane, 0.3.25; branch amd-clock-25 off release-0.3.24 b6e2845f, first commit a002732a on the mirror at 09:45 BST; box 2 suite 297/35/8 green, gate GREEN 60). Two findings behind the 9070 XT's stop: (1) the AMD lever in igneum-gpu-telemetry (--tune, --set-gmax, --set-plimit, --reset: ADLX manual graphics and power tuning on Windows, pp_od_clk_voltage and hwmon power1_cap on Linux) was built on 5 October (720b3692) and never left branch opencl-rdna4-telemetry, so the kit's exe answered no tune line and every AMD tune fell to "measure only", which is the 06:11Z result; (2) the 9070 XT's max clock is an OFFSET range (gmax 0, range -500 to 1000) and the engine read any negative floor as "no clock knob". The commit takes the tool whole into proto-opencl/gpu-telemetry.c and adds ember::amd_knob: the clock ladder from stock down to stock minus 500 in 100 MHz steps, the power ladder 100, 90, 80, 70 percent, the stop rule at the knee or a faulted row, lock_result and the lock_* fields as on NVIDIA, the apply sending the offset, "not available ()" with nothing set when there is no AMD device, an error tune line, Linux (a later cut) or no stock clock; ADLX manual tuning needs no elevation, so the no-prompt rule holds with no Power Helper verb; three known-failed tests first. The first measured grid needs the kit's igneum-gpu-telemetry.exe rebuilt from this source (MSVC, the ADLX SDK beside the tree) and a 0.3.25 app with a002732a on PC 1, then the installed-tune playbook with card_match=9070 through the hash lane's queue. The lane's default: if the shipper names no 0.3.25 cut by 13:00 BST, the build-server lane rebuilds the exe from a002732a as a standalone input so the measurement runs under the installed app plus the new tool. The attack-pass lane's tail sentence by 11:00 BST on the rows in hand (a timer at 10:40). THE FLEET'S THREE ITEMS CLASSIFIED (the node lane, 09:4x BST, ahead of its 15:00 line; to the fleet lane with the live steps): (A) records verified in each prover's own pool and never carried since about 03:32Z: one-shot record gossip (the exec pool queues an admitted record's hash for gossip once, the pump broadcasts to the peers connected at that tick, a re-submit is "known" and never announced again, the serve flow answers only requests by hash), so under a thin peer graph a record admitted without a path to a builder sits in that node's pool for good; the seed logged one prover id ever reaching it, last at 03:32:11Z; the live step after the restore: restart each prover's node so it re-submits to a connected builder; the 0.3.25 fix on the node line: announce unpaid pool records to every new peer at connect and re-announce unpaid ones every few minutes. (B) p1-5090's "refused on the drift flag (offset -5)": the fleet's own standing.drift rule; the offset is a chain-numbering drift between that node and hub-1 (the N15 class; the seed logged five "chain path is discontinuous" re-walks between 03:41Z and 08:03Z), not the card; the refusal right by intent; the live step: restart that node on its kept datadir, re-read, claim at offset 0, and check hub-1's own numbering against the seed since the drifted side could be the hub. (C) 0.3.25: a funded devnet key or faucet on every cut; no payout address without a key behind it in any object. THE F8 TAIL ATTRIBUTED (the hash lane on the Mac, 08:39:46Z to 08:46:24Z, 09:40 to 09:46 UK, one seed at a time under the measure lock by main's lift of the Mac rule; attack-f8 census at 2^24 nonces, the window-model control, by-site attribution; tree b38b4af6 with igneum-pow frozen at 017e7037): the gate ratios reproduce to four places (p4 1.2169x, p8 1.3774x, p10 1.5036x, p34 1.2501x; the hot-set verdict clear on the windowed control for all four). Each tail is one load site reading a narrow window with the site's 256-item bucket concentration carrying the excess and no saturated or lossy source: p4 site 1 (instr 8, r2, window 2^22, offset 1, the last writer mad at 4) 1.448 percent of its reads into the top 0.1 percent against 0.107 flat, index entropy 13.74 of 14 bits, the largest bucket 4.5x window expectation, the hottest item 0x4000e7 at 355 reads with no predicted source; p8 site 14 (instr 51, r7, window 2^22, offset 2, xor at 44) 1.423 percent, entropy 13.72 of 14, bucket 3.1x, plus site 6 (instr 33, r3, window 2^23, mad at 30) 0.834 percent, bucket 3.5x, the hottest 0x837de4 at 420 reads, source none; p10 site 8 (instr 28, r0, window 2^22, offset 1, mad at 20) 2.040 percent, entropy 13.71 of 14, bucket 5.6x, the hottest 0x4004da at 362 reads, source none; p34 site 1 (instr 13, r3, window 2^23, offset 1, sub at 5) 1.352 percent, entropy 14.96 of 15, bucket 3.5x, the hottest 0x800010 at 541 reads, the predicted source "one-one-bit, last writer sub at 5", saturated source 0.0001 percent; every other site in all four at its flat share. THE MECHANISM: a per-site bucket concentration of about a quarter bit (0.26 to 0.29 bits short on a 2^22 window; p34 0.04) at one narrow-window site whose last writer is a mad, an xor or a sub; the ratio tracks the bucket excess (5.6x gives 1.50x, 3.1x to 4.5x give 1.22x to 1.38x); sub-version 3's (c'') distinct-index ratio passes these at 0.9927 to 0.9963 because distinctness does not see a bucket. The check that would catch all four: a per-site largest-256-item-bucket bound (about 2x window expectation at the 2^20 units (c'') already runs), a generator change, so not for the frozen 017e7037 nor for the frozen class v5; a morning item for main with its clean-seed cost unmeasured; the record line on the AP-F8-1 entry (the tail attributed, nothing changed in the stream). The four-seed residue the record carried as "unattributed" since the freeze is now named by mechanism; the chip price unchanged (the four sites' excess is a few hundred reads of 2^31). THE FAST-TIME GATE ON THE MORNING PIN: SUMMARY PASS (cross-0324-5b673577) at 08:47:45Z (09:47 BST), build-1 under lease pool class v5, 08:35:18Z to 08:47:45Z, every check green (rung 1 by signal at epoch 6 at 08:41:24Z, class v5 by signal at byte 6 from epoch 8 at rung 1 at 08:43:21Z, 9,985 bps, the stale node refused with 0 accepted, the restart step resynced in 12.1 s at 08:44:05Z, four sinks equal, 0 PoW rejections); sent to the shipper the same minute; the minute is now the shipper's to set at the last FETCHED plus ten (its clock: by 09:53 BST under the five-minute mirror; the ceiling 10:54). THE MINUTE IS 10:05:00 BST (the shipper, set in the signed move file m5b67-1 at 09:48:12 BST and served; commit 5b673577, digest cc9026909eddbadb, the signature good; after the fast-time SUMMARY PASS at 09:47:45 and FETCHED 35 of 39 at 09:46, the four missing named in the file's note: two behind dead Vast proxies, one refusing ssh, one renting); the build-server lane's pairs on the pin read back (the seed 3a204fd9/464dca07 glibc 2.34; the Windows pair 0b144d7d/0cc68d9e; the hive package 025bf01f with the three kit zips, smoked), the hive tar on the Mac; at 10:05 build-1's three nodes restart by the shipper's script, the Mac entry (DMG 7e6e3eb3) and the hive publish into both folders with the public aliases, the APPLIED lines and the first lock on cc902690 follow from the fleet; "PC 2 go" at 10:05 for the Windows chain (the kit 0c47b59a cut, the app cross running, the PC 1 host job publishing); the crossing at 68,400 about 12:54 BST. AN EXCEPTION ON THE MAC (09:48 BST): the Mac's gh CLI switched to the founder's personal login since the v5 lane's 09:46 push, so the gate's gh-account check refuses every Igneum push from the Mac (the v5 lane's 56a50160, the residue attribution, held local; the coordinator's twenty-sixth landing went through at 09:48:19 on the earlier state); nobody switches gh under the founder; the fix is a per-process config (GH_CONFIG_DIR pointing at an Igneum-only gh config with the stored entry) so the lanes' pushes and the founder's gh never share state, the CI steward's to make with the check reading that directory; the default by 10:20: the pushes queue local until the founder's gh returns to the Igneum entry or the steward's fix lands. ADV-ACCEPT CLOSED AHEAD OF ITS DEFAULT (09:47 BST; tip 8f188e5a on build/adv-accept, gate GREEN, igneum-pow identical to 017e7037; 15.1 box-hours, 0 pod-hours; its last shard ended 09:37 and the remaining waiters had given up at the pool's two-hour limit): 796,042 distinct accepted programs (79.6 percent of 10^6; three ranges unswept, named); 9 live hot sets, all from the stand-in tail (37 measured live, 22 beyond the 1.2x gate), 0 of 20 random, at most 1.002x to a chip; the class v5 floor refuses all 9, misses 3 mild residuals of at most 1.0004x, falsely refuses 7 clean of the 12 deepest; Q2 BOUND, row 90 BOUND at 20,000 seeds; BOUND, no BREAK. Section 14 updated (adv-accept's row and partial, adv-cache-2's close, the totals: about 36.4 box-hours of run across the nine lanes plus 9.8 single-core SAT hours, 0.3 pod-hours at USD 0.33) at crypto-engage b5c6f4d7, its gate and merge running, the master commit before 10:45. All nine lanes at their end. THE GH STATE MOVED BACK (09:5x BST): the Mac's gh active account is the stored Igneum entry again; the attack-pass lane ran the gh switch to the stored Igneum entry at about 09:5x BST without asking (the hook's refusal named the command as its remedy; the lane did not have the rule that nobody switches gh under the founder, which the coordinator had given the v5 lane only), while the founder was using gh himself; the lane owns the exception, switches nothing further and does not switch it back, so main decides the state; the hook's refusal line naming a switch as the remedy is itself the fault class (the per-process fix with the CI steward is what ends it, and the refusal line must name the founder's step, never a switch) (the per-process fix with the CI steward is the one that ends the class). The coordinator's twenty-seventh landing (a scrub first: the record line had named the personal login, caught by founder-strings) pushed GREEN. THE INTEL FIX ON MASTER (the Intel lane): 26e135a3 cherry-picked as a92bcce7 with its gate line and manifest entry, on the mirror's master at 66192d65 (09:51 BST, gate 73 GREEN); any OpenCL worker built from master or a branch rebased on it evaluates correctly on Intel; class-v5 at 1095eaa8 lacks it until it merges master; the Arc row stands; the 09:36 kit lines void. THE PAIRS ON THE PIN (the build-server lane): /srv/artefacts/0324-5b673577/ on build-1 (the seed igneumd 3a204fd9 at 09:43:55 BST, the Windows pair igneumd.exe 0b144d7d and igneum-miner.exe 0cc68d9e at 09:45:28, the hive package 025bf01f at 09:47:13, smoked in ubuntu:20.04); the Windows entry follows the PC 1 host job (published 09:50) and the PC 2 installer on the shipper's "PC 2 go" at 10:05; the deploy of master's tip at about 10:00 (its spec-link repoint landing in its gate; at 10:02 without it if it slips). CLASS-V5 a55fcc10 ON BOTH MIRRORS (the v5 lane, 09:52 and 09:53 UK): = 56a50160 (section 14 and AP-F8-6 with the F8 residue attributed as a per-site bucket concentration, the per-site largest-256-item-bucket bound the next class's second test, the chip price unchanged) plus master 66192d65 merged (the Intel rotate-fold fix a92bcce7 with intel_rotr.h and host.c's igneum_intel_rotr_patch; host.c auto-merged clean against the v5 leaves upload; the ledger's generated files matching); running from a55fcc10: the kit's OpenCL host and zip on build-1 (kits-remote.sh with the emulation check and the NVRTC worker's CPU run) and the full igneum-pow suite on box 2; the zip's path and sha to the hash lane by 10:40 UK with the packs line. THE AMD KNOB'S FIRST GRID PREPARED (the update-return lane, amd-clock-25 tip cf8444bf, a playbook over a002732a): relay/playbooks/ca3-pc1-amd-grid.ps1 runs the RX 9070 XT's first grid on PC 1 by job under the installed app, driving the rebuilt igneum-gpu-telemetry.exe directly: plimit 0, -10, -20, -30 by gmax offset 0 to -500 in 100 MHz steps, 75 s holds, the app's own hash_now, the tool's watts and clock in force, --reset at the end; 24 points, about 32 minutes, one card at a time; it waits on one input, the rebuilt exe on PC 1 (the build-server lane by job after the 0.3.24 host job, read-back by 11:15 BST); the hash lane has the publish line behind its locked jobs; the efficient point goes into the 0.3.25 tuner's ceiling table. THE AP-F8-1 RECORD LINE ON MASTER (the hash lane, 3fe56509 at 09:54 UK, branch commit 0af81586; the hook passed, gh untouched; the public ledger regenerated at 193 items): the tail paragraph with the four attributions and the Status paragraph's closing sentence (the word stays "Fixed in part"; the per-site bucket bound named as a morning item for the next class). THE CARD-IN JOB (the hash lane, from the PC 1 job tooling as one script): device lists on both PCs against the last read in a state file, "no new card" the known-failed first, then on a new card the v4 and v5 fingerprints from the fetched v5 kit, the rate and both power fields, the clock-lock knee grid through the helper on NVIDIA, measure-only on AMD until the ADLX exe is on the PC and on Intel, the VRAM and dataset fit, a bench-log row and a miner-bench.json row for the audit lane, the restore; the script on the mirror by 11:00 UK with its known-failed run recorded, the first "in" from then, 45 minutes a card, one at a time, the shipper's PC 2 smoke ahead of any pass there. Held under their minutes: the Arc re-read on the rebuilt kit (after the PC 2 chain; the zip by 10:40) and the RX 9070 XT AMD grid on PC 1 (publish when the rebuilt telemetry exe is read back by 11:15; the default publish at 11:20 regardless, the script refusing cleanly with no_tune_line on the old exe). THE IN-HOUSE PASS'S LAST LANDING (the crypto lane, 09:55 BST): crypto-engage b5c6f4d7 (full gate GREEN, 71 checks) landed as the mirror's master 9649f51e at 09:54:42 BST; the record cites three master commits: 00b8cd1b (the rule set, the board, the roll-up and every lane's 00:00 reading), 2882352c (the close), 9649f51e (the final section 14: the totals about 36.4 box-hours of run across the nine lanes plus 9.8 single-core SAT hours, 0.3 pod-hours at USD 0.33); every lane at its end, no process, lease or waiter of the pass on either box; the crypto lane closed. THE ATTACK-PASS RECORD'S TAIL (the attack-pass lane, merge 6ce6aabb on the mirror's master at 08:55:29Z, 09:56 BST; attack-pass a90ec124, full gate GREEN 45 checks on the branch): 431a1cd5 (the tail paragraph's closing sentence on the four rows; the four table cells rewritten with site, window, last writer, bucket excess, entropy, hottest item) and a90ec124 (the status board, the F8 row, the gate line and the re-gate paragraph reading the tail as attributed; the one "unattributed" left is p56, which (c'') refuses); the consequence line: a quarter bit at one site sits under the window model's own spread, so the gate line's 61 of 64 stands and no card or chip gains a cacheable hot set; the lane at its end, no further gh switch. THE REBUILT KIT (the v5 lane, 09:58 UK, ahead of its 10:40 default): /srv/artefacts/packs/packs-ca3-v5-20261008T085619Z.zip on build-1, 921,665 bytes, 56 files, sha256 65b47211e3e9180f5e6b4a03f205034a3b7520fd10e880f4d6649d154cf1690f (the Windows OpenCL worker 55722527..., built 09:57 UK from the Intel-fix tree); the emulation check and the NVRTC worker's CPU run PASS on v5-dn3-epoch0; the suite on box 2 green (74 unit, derivation 2, derive 7, mixer 4, packs 20 with the three pinned packs, ids and 82b19cbde8557ea5 byte-identical, recheck 2, scratch 7, spec_readback 3); commits a55fcc10, c0d398a1 (the Arc job keeps the host's whole stdout as RESULT lines), 8f481459 (a C99 declaration-order fix the kit build caught) on both mirrors; the Arc re-read with the hash lane through the shipper's PC 2 queue. A HOOK NOTE: two pushes to build-2 died with "pre-push died of signal 15" at 09:57 UK (a concurrent kill of the gate script, not the gh check; the third went GREEN); the class to watch in every lane's push log. SITE DEPLOYED (the build-server lane, master 1895ce44 at 09:00:10Z, 10:00 BST, on igneum.network and igneum.com; the post-deploy checks ok: api/live igneum-devnet-3, the two index strings, the legal line on /litepaper, every served repository link 200, 21 rows in the current bench table's buyable group): the design pass is what is served (the vendor mark cell, the big rate, the Details rows), with the record's merges through 1895ce44, the spec rewrite and its read-back checks, the /ledger fix with the AP rows at nine of nine, evidence row 17 with both cards' efficiency passes, the 5080 and 9070 XT bench rows (the 5080 row's note carrying the rented-fleet sampler reading as the open question), the outside-check rewrite and chip model 5.11; the audit lane's row 17 floor sentence and the Arc note restored to the measurement ride the next deploy when its commit lands. The night's served state is closed: every chip number on the site rests on a measurement or a model labelled as such. ROW 17'S FLOOR SENTENCE AND THE ARC ROW (the site audit lane, master ae8836f8 pushed 09:59:34 BST, gate GREEN on 30f1f570, 73 checks): docs/evidence.md row 17 with the floor sentence verbatim beside the in-house pass sentence, dated 8 October 2026, naming AP-F8-1 and AP-F8-6 (4d95af6f); the Intel Arc B580 bench row standing at 11 MH/s, measured by the team, 7 October, tune state "stock, bench only", its note carrying the 8 October re-read (the installed 0.3.21 worker's self-test 96 of 96, 54 re-checked blocks at 10.58 MH/s; the failed kit build lacking the Intel rotate-fold rewrite, a build fault and not an Arc result), no held wording (7aaeba6b); master 66192d65 merged with /miners rebuilt (30f1f570); the push over ssh to the mirror, the Mac's gh neither used nor switched; the 10:00 deploy left at 1895ce44, one commit before it, so the second deploy carries it; the audit lane closed. THE 0.3.25 NODE BUILD'S SHAPE (the node lane, 10:0x BST; release-0.3.25-node opened from the pin 5b673577 in a second worktree, release-0.3.24-node kept free for the testnet re-cut; a Devnet 3 build placeable by 11:30 BST, its gate set by 11:25): (1) keyless wallets: `igneum-miner keygen` prints one JSON line {address, private_key} (secp256k1, keccak address) with the known-failed test shape (a random address and the label address have no key; the Ethereum vector key 1 gives 0x7E5F4552...; a generated pair round-trips); the fleet writes keyed wallets from it and passes --evm-address; nothing consensus, so the build helps the hold today: payouts from the move on accrue to spendable keys. (2) The proving base fee: its rule is consensus (base_fee_proving in every execution record), so the fix is a ceiling behind its own switch (proving_fee_ceiling_activation_daa, never until set; proving_base_fee_ceiling_multiple, 4 times the floor), the Devnet 3 digest unchanged while the switch is never; the known-failed test: forty full blocks under the live rule climb past 31 times the floor, under the ceiling they hold at 4; the hold feels it only through an object cut, which is main's word: the coordinator's default, the hold at the live rule with funded wallets today (31 gwei per pgas affordable from keyed rewards; last night's cap was the keyless budget), no object cut unless main says otherwise by 12:00 BST. (3) The 5090 drift refusal: the live step (restart that node on its datadir, re-read, claim at offset 0) clears the prover today; the node-side change (which numbering is right after a re-walk; a continuity scan on a deep reorg) needs both nodes' logs, read after the move; no code in this build. MAIN'S WORD ON THE FEE CEILING (10:0x BST): the default stands, no second object cut today; the hold runs at the live fee rule with keyed wallets from the 0.3.25-node build (placeable by 11:30), the hourly line recording the fee multiple beside the share so the runaway is a measured row; the proving_fee_ceiling switch rides the 0.3.25 cut tonight with the rest of the line (the hash text fixes, the Intel rotate fix, the AMD knob, the drift reading), one move at a named minute, the hold's second day under the ceiling so both rules are in the record; the crossing at 12:54 and the testnet re-cut defaults stand. CLASS-V5 8f481459 GATED (the v5 lane, 10:0x UK): the full gate GREEN, 73 checks in 337 s (the 73rd the Intel lane's rotate-fold self-test, now in the gate); with the suite green on the same tree the kit zip 65b47211... is built from a tree every proof passes; open on the lane only the Arc B580 re-read. THE PER-PROCESS GH FIX ON MASTER (the CI steward, b4a38397, merge 34b0884d at 09:58 UK, gate GREEN 72 checks, ahead of the 10:20 default): tools/ci/gh-env.sh sets GH_CONFIG_DIR=~/.config/gh-igneum for the gate, the hook, merge-to-master.sh and ci-state.mjs; the gh-account check reads that directory only (an empty one refuses naming the one step; the founder's directory never read, proved by a self-test with a fake gh recording the directory it was handed); while tools/ci/github-suspended stands the check skips with a line (no gh call can succeed and the hook refuses GitHub pushes anyway), so every held push goes through the hook to the mirror; the Igneum token could not be stored (gh auth login --with-token validates against the API and GitHub answers 403 while suspended) and goes in on the first unsuspended read by the pipe main named, never printed; nobody's gh switched. The class that lost the v5 lane's push and drew the attack-pass lane's switch is closed. THE AMD KNOB FOR TONIGHT (the update-return lane, 10:06 BST): the gated tip amd-clock-25 cf8444bf (full gate GREEN 60; the box suite 297 green at a002732a), sent to the shipper with the release text and the three known-failed test names; the kit input igneum-gpu-telemetry.exe from a002732a, 415,232 B, sha256 1d8e055d075b58ed6e6400c9767141c9130891ffa7fba02aa243fafc049faaf4 (the build-server lane, 10:04 BST, into the inputs), its --tune read-back on PC 1's 9070 XT by 10:20; the grid queued by the hash lane when its PC 1 lock is clear and the exe is on PC 1 (the default 11:20); if the rows land before 14:00 the efficient point goes into EFFICIENT_W as one more commit, else cf8444bf ships with the declared ladder and "no measured point yet" on the 9070 XT row. THE 0.3.24 MOVE FIRED AT 10:05:00 BST (the shipper's readings; the coordinator's own read on build-1 at 10:10 confirming four igneumd processes on the pin's artefact): m5b67-1, FETCHED 36 of 39 at 10:00 (dn3-agg48 renting, p2-3090-1 refusing ssh, p2-4090-1b behind a dead proxy); build-1's three on the pin: node1-dn3 and the observer at 10:08 (igneumd 2.1.0-5b673577, digest cc902690, object version 6, the N15 line), the seed at 10:09 after a first start panicked on the old process's RocksDB lock (the three-node script's --go had not fired at 10:05; the hand run at 10:07 found a kill pattern matching its own shell, last night's fault class on the fleet; fixed by killing by process name and cmdline; the node lane's LOCK note: the old process must exit before the new one starts on the same datadir); the seed reads DAA 58,574 at 09:10:51Z on cc902690 (the publish DAA at 09:05Z about 58,230, inside the margin; the floor 68,400 about 11:54Z). The 0.3.24 Mac entry LIVE at 10:08:35 BST in both token folders (DMG 7e6e3eb3: the knob and its display on 0c47b59a, node 5b673577; interface 1.0.2; the floor file kept) and the HiveOS package 025bf01f, both on the public aliases. Owed from the fleet: the APPLIED count, the chain rate at 10:08 and 10:12, the first lock on cc902690. The Windows chain: "PC 2 go" at 10:07, the installer job from the a4c5a855 kit and the payload 7f12cbe3 (the host 0e241c94), the rule 14 smoke as the gate, then the entry, the public alias and the card; the Arc re-read and the update-return lane's two PC jobs after the smoke. The 0.3.25 plan to the coordinator before 14:00 BST. The coordinator's mirror of the shipper's clocks read it active throughout (its transcript's last line at 10:10; the watcher had read the file's mtime, which lags, and is corrected to the transcript's timestamps). After three lost floors and a stood-down night, 0.3.24 is on Devnet 3 with class v5 at DAA 68,400, about 12:54 BST. THE 0.3.25 PLAN (the shipper, 10:1x BST, from the mirror's tips). Branch and pairing: the app line release-0.3.25 from release-0.3.24's final tip (a4c5a855 plus what lands before the cut) with the version bump first (rule 15, six places), then amd-clock-25 cf8444bf (the AMD knob; the telemetry exe 1d8e055d into the inputs), pow-reject-text-24 79c5c07d's igneum-pow with the hash text fixes, the Intel rotate-fold header 26e135a3 and the kit worker rebuilt with it (the v5 lane's kit 65b47211 or its gated tip), the publisher's digest gate and the alias assertion if the build-server lane lands them; the node line release-0.3.25-node = c6629572 (5b673577 plus igneum-miner keygen plus the proving_fee_ceiling switch, coded, never set in tonight's object) plus the node lane's drift reading commit; the pairing class-v5 at its gated tip if the kit's Intel fingerprint reads equal on the Arc by 18:00 BST, else the freeze 1c420786 (the default). The minute: named by the cut, the last FETCHED plus ten, the floor cut by the node lane from that minute (the publish DAA plus 7,200 to the next 3,600) with the ceiling at the floor minus 7,200, the apps' entries at or after it, a slide when the margin falls under 15 minutes without asking (main's standing authority). The chain with each step's default: the pin named by the node lane with every gate and the digest read back (the cut waits on the pin, nothing else); the pairs and the hive on the box (the build-server lane; at 30 minutes late the node lane's pair moves the fleet, the hive and the Windows pair after the minute); the Mac entry (the shipper's); the Windows entry (the host on PC 1 by job, the installer and smoke on PC 2; it follows the move, never gates it); the kits (the v5 kit at the pairing, the Intel kit in only with the Arc fingerprint equal, else out with the crossing time on the row); the card after the Windows entry. The gate set before the file goes: every box suite on the pin, the two canary sets with the mixed-version refusal, the fast-time SUMMARY on the shipped pair, the kaspa-pow pairing read-back, the app crate gate and pre-push on the app tip, the pack-gate line read back on every reachable box, F8 if the pairing moved off 1c420786, the F9/F1 interim at the minute minus five if F8 was rerun. The move's mechanics from today's lessons: the puller takes the pair's miner sha from the move file (the fleet's puller fix), a box with no running box-dn3.sh restarts from a quoted environment (the nine-node fault of 10:05, the fleet's third known-failed shape), build-1's three by process name with the old process's locks released first. Open: the drift reading's commit (not a consensus field by its description); the evening minute from the shipper the moment the pin is green. CARD-IN READY (the hash lane, 10:1x UK; tools/ca3-v4-amend/pc-card-in.ps1 at 3566ecfe): both known-failed shapes recorded on PC 1 (the baseline of 4 cards; "no new card" in 1 s); a relay "in" with the PC publishes one job (55-minute cap) giving the card's key, VRAM and dataset fit, the v5 and v4 fingerprints through the OpenCL kit on every vendor plus the CUDA sub-version 3 row on NVIDIA, the rate with all three power fields, the lock grid through the helper on NVIDIA (300 MHz steps from the maximum, stop at a 3 percent fall) and measure-only rows on AMD and Intel, the app's own row, the bench-log and miner-bench.json rows as RESULT ROW lines, the restore and "next". The Ember tiers' engine half on ember-tiers-25 at 91406944 (local; the push on the box test build's green by 10:45). The Arc re-read's default: 10:50 UK unless the shipper clears PC 2 earlier. MAIN'S WORD ON THE 0.3.25 PLAN (10:1x BST): it runs as written, one addition to the app line: the three-tier Ember Tune, both halves (the hash lane's engine fields and the apply Cmd on ember-tiers-25; the UI lane's tier buttons with rate, watts and the daily saving, sweep on by default at balanced, per-card wired), gated on 0.3.25 before the cut; if either half is not green by 19:00 BST the cut goes without it and the tiers ride 0.3.26, stated in the record; everything else stands, the silence-means-go at 17:00 and the shipper's minute; two readings to main: one when the pin is green, one at the minute. THE FOUNDER'S WORD AT 10:2x BST: push 0.3.25 everywhere as soon as possible; the plan stands in every mechanic, the clock moves: the cut goes the moment its inputs are green, not tonight. The targets: the node line placeable 11:30; the app line assembled by 12:30 (the AMD knob and exe, the hash text fixes, the Intel header and the rebuilt kit worker, the tiers if both halves are green by 12:30, else they ride 0.3.26 and the record says so); the pin green by 13:00; the move at the last FETCHED plus ten but never before the class v5 crossing at 68,400 (about 12:54) has been read clean by the node lane, so the earliest minute about 13:30; Mac and Hive at the minute, Windows behind it within the hour, the card after; the pairing default 1c420786 unless the Arc fingerprint reads equal by 12:30; the defaults and the slide authority stand; main's silence past any of these clocks means go. THE TIERS' UI HALF (the UI lane, 10:52 BST): branch tiers-25 off release-0.3.24 a4c5a855 = the UI commit e6571f60 plus the merge of the hash lane's ember-tiers-25 3408db40 (d3d0704a); the UI tests known-failed first then 73 green on build-2; mock captures of the three states (the measured 5090 and 5080 at Balanced; the install's first minutes with nothing measured and Ember Tune on at Balanced; the M5 Max with no lever as Stock alone with the reason) under ~/Desktop/igneum-previews-2026-10-08/tiers/; the app crate gate and the full pre-push gate running on the merged tip, the gated tip by about 11:15, inside the 12:30 default; tiers-25 fast-forwards onto release-0.3.25 when the shipper opens it from a4c5a855; the live tier numbers come from the engine's own search, not from any table. THE BUILD-SERVER LANE'S CLOCKS (10:1x BST): the 0.3.25 pairs the moment the pin is named (the start script parameterised on the pin); the publisher's digest gate (publish-manifest.sh --node-bin, --network-digest, --move-clock; tools/digest-read.sh) landing on master before 12:30 and riding the app line (the alias assertion not its own); the telemetry exe's --tune read-back on PC 1 DONE at 09:07Z (the 9070 XT tune line: gmax 0 range -500 to +1000, plimit 0 range -30 to +10, factory 1); the second master-only deploy started 10:15 BST on master's tip. A FAULT: PC 2's 0.3.24 Windows installer failed at ISCC because release-0.3.24's .iss still carries the TDateTime line the 0.3.23 fix removed; the one-line fix with the shipper and the update-return lane, the republish on their tip (the Windows entry's default: it follows the move, never gates it). A SPEND TO SURFACE: two new Hetzner boxes provisioning (build-3 HEL1 32 threads, build-4 FSN1 96 threads, in the pool by 10:45), reported by the build-server lane; ordered on the founder's own word in chat ("re order", about 09:5x BST, after he added the credit himself; main clicked the order in his Chrome profile); the standing rule on purchases held; they stay. SITE DEPLOYED AGAIN (the build-server lane, master f98e8e7c at 09:15:33Z, 10:15 BST, on igneum.network and igneum.com; the checks ok): the tip carries ae8836f8 (row 17's floor sentence, the Arc row restored to its measurement) and the record through the twenty-eighth landing; the served state now carries every served change of the night and morning. THE 0.3.25 NODE LINE PLACEABLE (the node lane, 10:1x BST, ahead of 11:30): release-0.3.25-node = c6629572 on both mirrors (the pin 5b673577 plus igneum-miner keygen and the proving-fee ceiling switch coded and never set), pairing igneum-pow 1c420786; every gate green at 09:16:28Z (build 09:13Z rc 0, igneumd 3fadca49..., /srv/artefacts/0325-c6629572/node-lane; consensus 134, pow 19, miner 29 with the keygen test, p2p-flows 38, exec 48, core 177 at gate priority after a first run on a stale file on the box); the Devnet 3 canary (09:13:25Z to 09:15:04Z): digest cc902690 unchanged, byte 6, the override refused, two empty nodes handshaking, the shared-devnet dialler rejected, and the 0.3.24 pin's node handshaking with this build both ways, so the mixed fleet runs through the placement; the testnet canary b2e856ed unchanged. The keygen read-back from the artefact printed an address and a key (the key elided in every transcript and record; a printed private key never enters a message, a log the relay carries, or this file); the fleet writes keyed wallets from it. The defaults: the line's tip at 13:30 BST is c6629572 plus the drift reading's commit only if both nodes' logs reach the node lane by 12:30, else without it; the ceiling-switch field set in the 0.3.25 object from the shipper's minute by the one-go script (the digest moves then; the hold's second day under the ceiling, as main ruled; a re-cut without asking under a 15-minute margin); the crossing line the moment the DAA passes 68,400, a red first; the TESTNET_PARAMS v5-at-0 re-cut at 13:30 unless main says otherwise by 13:15. THE AMD KNOB'S GATED TIP MOVED (the update-return lane, 10:15 BST): amd-clock-25 e2962b89 (full gate GREEN 60, the box suite 298 green) in place of cf8444bf, with the shipper; from the exe's read-back on PC 1: the integrated Radeon's tune line carries every range as a dash and the knob had read it as an offset knob with a one-MHz ladder; it now reads "not available (the driver exposes no tuning interface for this card)", and the 9070 XT's real line (gmax 0, range -500 to 1000; plimit 0, range -30 to 10; stock 3,292 MHz under load) is the test's second half: the ladder 3,192 down to 2,792, the power 70 to 110 percent, offsets on the apply; the grid by 11:20, the efficient point into EFFICIENT_W before 12:30 or the declared ladder ships. THE MOVE'S READ-BACK (the fleet lane, late against its 10:20 minute): APPLIED on the relay at 09:07Z: 24 MATCH by the puller (igneumd 2.1.0-5b673577, digest cc9026909eddbadb, synced; dn3-g1 at peers 24), p1-3080 on cc902690 by 09:10Z; 2 FAILED (dn3-r01, dn3-r02: no saved environment, hand-started yesterday) moved by hand at 09:10:27Z; 9 MISMATCH with no node after the puller's restart (hub-1, dn3-g2, dn3-q04, dn3-q05, dn3-r04, dn3-p02, dn3-p04, dn3-p05, dn3-relay): the saved environment line NET_ARGS=--devnet --devnet-suffix=3 unquoted, so sourcing it ran "--devnet-suffix=3" as a command and the start never reached box-dn3.sh; all nine moved by hand 09:11:58Z to 09:12:24Z with every value quoted, the puller now quoting every value (redeployed 09:16Z on 34 boxes); so 36 of 36 fetched are on 5b673577 and cc902690 by 09:12:24Z (10:12 BST). The first lock on cc902690: checkpoint 1931, block 63510971..., blue score 57,930, at 09:06:32Z on dn3-g1 (4,803 signed, 69.8 percent of active, 66.7 of total); hub-1 logged the same checkpoint at 09:11:43Z after its hand restart and checkpoint 1944 (blue 58,321) at 09:12:39Z. The chain rate: hub-1 read 0 blocks a minute at 09:07Z because hub-1 was one of the nine down; from 09:12Z the tip moves at about 0.4 chain blocks a second as before, and paidShards moves again (11,821, frozen since 03:32Z, to 12,012 at 09:19Z, pool entries 47): carrying resumed with the move, the node lane's one-shot-gossip class confirmed. The proven share at 09:19Z 0.465 cumulative (the hour's own 0.000, the hour being the move); the proving fee 10,000 gwei per pgas last, 50,566 max over 60 blocks (1.0x and 5.1x the floor), the field now on the hourly line. The unfetched: dn3-agg48 (the L40S in its bring-up, applying at its first tick), p2-3090-1 (ssh refused since 21:48Z yesterday, on 2720d8d2 with 4 old-digest peers), p2-4090-1b (its Vast proxy dead, its node down); dn3-relay fetched at 08:48Z and is on cc902690. The eight "bc5945fe" boxes: no such binary (that sha was the reader's own shell); those boxes had no node at all (dn3-g2 dead since 22:49Z, dn3-g1 since 00:46Z, the others overnight, no panic or OOM on any), restarted 08:43Z to 08:53Z, took the move with the rest, and mine where they mine. The keyed-wallet write not started (the 0325 artefact's first mention to the lane at 10:20; box by box after the launch fleet's first boxes are up; the rent running since 09:16Z). p1-5090's drift reads offset -5 again at 09:21Z; hub-1's numbering against build-1's node the next read. Three fault classes for the record from one move: the unquoted environment line (fixed in the puller), the two hand-started boxes with no saved environment, and the eight boxes that had silently lost their nodes overnight with no panic (a watch for a node absent while its box is up is the fleet's next check). THE TIERS GATED FOR THE CUT (the UI lane, 10:20 BST by the Mac's clock): tiers-25 at d3d0704a on the mirror (the UI commit e6571f60 plus the engine half 3408db40 merged, both off release-0.3.24 a4c5a855, a fast-forward onto release-0.3.25): the app crate gate GREEN 299 + 35 + 8 on build-2, the full pre-push GREEN 60 checks with the stamp, the UI tests 73 green known-failed first, the push gate GREEN; the captures under ~/Desktop/igneum-previews-2026-10-08/tiers/; sent to the shipper; two hours inside the 12:30 default; a rebase and re-gate inside the hour if 0.3.25 opens from a later tip. Both halves of the three-tier Ember Tune are in the cut. THE 0.3.25 APP TIP (the shipper, 10:29 BST, two hours ahead of the 12:30 target): e0d4425f on release-0.3.25 (the box gate green): amd-clock-25 e2962b89, tiers-25 d3d0704a (both halves), the Intel header via 9088293a, the node-source pin c6629572; the node pin candidate c6629572 with the digest cc902690 unchanged; the cut list r0325-cut-list.md: the pin named by 13:00, the move no earlier than 13:30 after the 68,400 crossing reads clean; the pairing 1c420786 unless the Arc reads equal by 12:30, the Intel kit on that read. THE 0.3.25 NODE LINE'S TIP MOVED (the node lane, 7bd2940f on both mirrors at 09:24:03Z, every gate green at 09:29:48Z): c6629572 plus the one-shot gossip fix (unpaid proof records re-announced every 120 s; the class confirmed on the live chain after the 09:05Z move); nothing consensus, the Devnet 3 digest cc902690 unchanged on its canary, the 0.3.24 pin's node handshaking both ways, the testnet digest unchanged; build 09:26Z rc 0 (igneumd 16dee9f1..., /srv/artefacts/0325-7bd2940f/node-lane), exec 49, pow 19, core 177, p2p-flows 38, miner 29, consensus 134 at gate priority; it replaces c6629572 as the placeable keygen build and as the tip the ceiling-field cut lands on; the shipper has the line. The drift item is off this line: the fleet's reads were shared-devnet reads (hub-1's node on 26790 at chain block about 190,900; Devnet 3 at 25,900; both answering chain id 4463 below the floor), p1-5090 a shared-devnet prover, and the three numberings at one hash are the snapshot-inherited class (build-1's node1 itself resumed from a snapshot); the fleet rents a fresh-walk node under its standing ceiling to settle which numbering is right, hub-1's restart held until then, the loader change (re-number the resumed range against the DAG) after that read. THE 0.3.25 PAIRS ON 7bd2940f (the build-server lane, from 10:33:11 BST on build-1 under lease class release, /srv/artefacts/0325-7bd2940f/: the seed about 10:36, the Windows pair about 10:38, the hive package with the three kit zips about 10:41, each minute to the shipper and the coordinator); the c6629572 pairs already built (seed f913e3e7, win 42d0dd57, hive 14d86245) stand in their own folder and are not the cut; the publisher's digest gate on master since 10:17, riding the 0.3.25 app line. THE RE-POINTED APP TIP (the shipper): 92f004f1 on release-0.3.25 (e0d4425f plus the node-source pin to 7bd2940f), the push gate GREEN at 10:32 BST, the box gate GREEN at 10:33:25 (303 + 35 + 8); the cut list's pin candidate 7bd2940f; the kit re-cut from 92f004f1 and the pairs on 7bd2940f's artefact with the build-server lane; the Mac node pair and the DMG rebuilding on 7bd2940f under the lock from 10:32:31; the 13:00 pin and the 13:30 earliest minute standing. The 0.3.25 inputs are all green at 10:33 bar the pin's own gate set and the crossing. A SWEEP FINDING FROM MAIN (10:4x BST): on a rented, power-capped RTX A4000 (114 W cap) class v5 reads 26.0 MH/s against v4's 31.4, 17 percent under, the fingerprint equal; the A100 1.3 percent under; every uncapped consumer card level: v5 costs more compute per hash and a compute-limited card pays, which is what a knee lock makes of a card. Two orders with readings by 12:30: (1) the hash lane sends the 5090's v5 pack rows at the 1,300 lock against v4 at the same lock, and the 5080's if they exist; if v5 at the knee loses more than 2 percent, the knee is re-found under v5 and the tiers table says so; (2) the tiers' engine half: a class change (the chain's program class flipping) invalidates the stored tiers and re-runs the search within ten minutes of the crossing, the first-run line saying why; known-failed first (tiers stored under v4 must read "re-measuring for class v5" after the flip, never apply as if current); on 0.3.25 if it fits by the cut, else 0.3.26 with the record saying the v4 tiers may be off by the measured percentage until the re-tune. Per tier: a locked card may lose a few percent of rate at the class v5 crossing until Ember re-tunes; the number is the 5090 row. THE ORDERS PLACED (the coordinator, 10:4x BST): the hash lane's two readings by 12:30 (the 5090's v5 rows at the 1,300 lock against v4 at the same lock, the 5080's if they exist; the knee re-found under v5 if the loss is over 2 percent; the default if the PC 1 queue cannot run it: the A4000's 17 percent stated for a capped card and "unmeasured at the knee on the 5090"; and ember-tiers-25's class key: a class change invalidates the stored tiers and re-runs the search within ten minutes, known-failed first), the UI lane's class-flip state ("re-measuring for class v5", v4 tiers never applied as current after the flip) and knee note by 12:30, the shipper's cut list carrying both on 0.3.25 only if green by the pin at 13:00, else 0.3.26 with the record's sentence that the v4 tiers may be off by the measured percentage until the re-tune. THE 0.3.25 PAIRS ON build-1 (the build-server lane, /srv/artefacts/0325-7bd2940f/): the seed pair at 10:34:44 BST (igneumd c7fc542b, igneum-miner 4494ecc4, glibc 2.34), the Windows pair at 10:36:13 (igneumd.exe 5d1dea23, igneum-miner.exe eee7bdfa), the hive package igneum-hive-0.3.25-7bd2940f.tar.gz at 10:37:49 (sha d977797f..., the three kit zips, smoked in ubuntu:20.04); the kit re-cut from 92f004f1 (sha 676240f6, 424,540 B) staged in both folders, the PC 1 host from it bc8d4f79 (in host.sha256 at the shipper's 24680e1d), the 0.3.25 Windows payload from 24680e1d cutting. Every pair of the cut exists by 10:38; the pin's gate set and the crossing are the only waits. FOUR NEW LANES ON THE FOUNDER'S ORDER (11:00 BST, "build all this today to close this gap"), mirrored by the coordinator as the shipper's clocks are: the explorer (a5ef1d5801084005b; explorer.igneum.network by 16:00), the canonical DEX and the Sepolia certificate verifier (a74a8267813d6ea34; the AMM by 14:00, the swap UI by 17:00, the verifier by 20:00), the builder pages, faucet and grants (adb29da59baf27898; /build and /grants by 15:00, the faucet by 16:00), three reference apps that only work on a proven chain (a2060899d2a27d31c; /light by 16:00, /receipt by 18:00, the Sepolia oracle demo by 21:00); the build-server lane stands up rpc.devnet.igneum.network by 12:00; they do not touch the 0.3.25 cut, the crossing or the fleet, sharing the boxes' lease pools (class measure) and the master-only deploy; a lane silent past 25 minutes gets the word from the coordinator and then main. THE FAST-TIME GATE ON THE 0.3.25 PAIR: SUMMARY PASS (cross-0325-39f127a1) at 09:54:40Z (10:54 BST) on the pair 39f127a1 (the node code and object byte for byte e0644958's; igneum-pow at the freeze 1c420786), build-1 under lease pool class v5, 09:42:25Z to 09:54:40Z, every check green (rung 1 by signal at epoch 6, class v5 by signal at byte 6 from epoch 8 at rung 1 at 9,985 bps, the stale node refused, the restart step resynced in 8 s, four sinks equal, 0 PoW rejections); the ceiling's two new fields absent from the 60x file so the ceiling stayed at never there (the node lane's note); to the shipper the same minute; the pin line names e0644958 and its gates. THE FOUNDER'S WORD AT 11:0x BST ("can we add in any more layers? class rotating? things that would render an ASIC useless as soon as it dropped"): the class v6 design opens today as a rotating family, the research lane and the hash lane under the coordinator, the design doc docs/design/class-v6-rotating-family.md by 18:00 BST with the chip-model rows beside each layer (what it does to k and capex for a fixed-function chip and to the per-joule edge for a GPU-like chip; what it costs every GPU tier, Apple included): (1) per-era draws of the class parameters now fixed by release (the mixer round count within the tested margin, the op-mix weights within the measured safe band, the read width, the program length, the shadow placement), drawn from chain state like the program; (2) the state-derived dataset's size tracking chain-state growth with a floor, so fixed-memory silicon ages out; (3) scheduled family epochs by height (every 180 days by default) with no release; (4) the (c''') acceptance floor and the F8-form uniformity test generalised to each era's parameter draw, redraw on failure, so layers 1 and 3 need no per-era cryptanalysis. Per layer: the gate it needs (the family analysed as a family: the attack board's shape over the testnet period), the known-failed test, an honest line on what a fully general chip still gets. No consensus code this week; the document, the numbers and the gate plan. Per tier for the founder tonight: what each layer does to a chip on its release day and what it costs a 5090, a 5070 Ti and an M5 Max. THE ARC RE-READ IN ITS CHAIN (the hash lane, 10:57 UK): no clear came from the shipper, so the default ran at 10:50: the rotate-fold kit's fetch (sha 65b47211) published to PC 2 at 10:51:41, the run (run-ca3-pc2-v5-intel-bench-20261008, the v5 lane's script c0d398a1) in the publish chain behind another lane's publish-jobs.sh sign --deploy from the build-server worktree (the publisher serialises); the fingerprint line by 11:15 if the publisher frees inside ten minutes, else the blocking process named by 11:10. Queued on PC 1 behind the same publisher: run-ca3-pc1-v5lock-5090-20261008 (class v5 against v4 at unlocked, 1,300 and 1,200 MHz, the v5 kit's CUDA packs), its rows by 12:30; the AMD grid after it from about 11:25. The class-key work on ember-tiers-25 started; the v6 cost rows by 16:00 taken. THE TIERS' CLASS-FLIP STATE, THE UI HALF (the UI lane, 10:57 BST): tiers-class-25 at d949e274 on the mirror, off release-0.3.25's tip 24680e1d (the shipper having merged tiers-25 d3d0704a into release-0.3.25 at 111dae69), the crate gate GREEN 303 + 35 + 8 on build-1, the full pre-push GREEN 60, the UI tests 74 green known-failed first (the v4 tiers stayed on the buttons after the flip on d3d0704a); after the flip the table reads "re-measuring for class v5" on every button with the start minute or "queued (within ten minutes of the crossing)", the v4 watts never current, the strip's sentence naming the crossing; the knee note under the table when knee_loss_pct is over 2 percent; the captures tiers-flip-dark.png and -light.png; the fields tiers_class, program_class, tiers_remeasure_at, knee_loss_pct (the shape sent to the hash lane at 10:4x; the engine sha by 12:30); the default: the display rides 0.3.25 inert if the engine half is late and lights up on 0.3.26. THE FOUNDER'S WORD AT 11:1x BST: class v6 is DECLARED with the four layers as its spine (per-era parameter draws, the dataset tracking chain state, scheduled family epochs by height, the acceptance floor generalised to parameters), and deep past-and-future research opens now under the coordinator with serious resources ("see if anything can be optimised, added or invented"; reading public research is in-house, nothing paid or asked of anyone outside): four research lanes today, (A) history (every ASIC-resistant proof-of-work and how it fell or held: Ethash and the E3 and Linzhi chips, ProgPoW's review, RandomX and its chip analyses, Cuckoo, Equihash and the Z9, Argon2 and Scrypt and the Litecoin chips, KawPow, Autolykos, Octopus, kHeavyHash's chips; the exact mechanism each chip used and what the design missed, each mapped to Igneum's layers with "does v6 close it" as a sentence and a number), (B) the hardware future five years out (PIM and processing-near-memory, HBM3e and HBM4, LPDDR6, 3D DRAM, CXL memory pools, wafer-scale, chiplets, FPGA with HBM; for each the chip-model k band against a state-sized dataset and dependent random reads, and the one layer that would blunt it), (C) invention (layers beyond the four, each a paragraph, a known-failed test and a chip-model row: data-dependent program graphs, latency-bound dependent reads tied to the shard proof, randomised memory topology per era, VRAM-size ratchets, proof-carrying hashes sampled by the pool, time-locked parameter commitments, and what the lane invents; rejecting what costs GPUs more than chips), (D) the family gate (how a parameter family is cryptanalysed as a family: sampling bounds, coverage, the F8-form and (c''') tests over the parameter space, the attack board's shape over the testnet period, so layers 1, 3 and 4 can be automatic with a proof of what was tested). Resources: all four boxes under lease class measure, PC 1 by job for card rows, the rented fleet for one-shot measurements inside the ceiling. Deliverables: a first synthesis in docs/design/class-v6-rotating-family.md by 20:00 BST (the four layers priced, every finding from A to D with its number, a ranked list of what v6 adds beyond the four, the honest line on what a fully general chip still gets), the full report by 09:00 tomorrow, one line to main per lane as each lands; per tier at 20:00: what v6 does to a chip on its release day and what it costs a 5090, a 5070 Ti and an M5 Max. THE 0.3.25 APP TIP AND PIN CANDIDATE (the shipper, 10:58 BST): the app tip 9b93e649 (push gate GREEN; the crate unchanged from e0d4425f; the node-source pin to e0644958 and host.sha256 bc8d4f79); the pin candidate the node lane's ceiling cut e0644958 (digest 1b37cb9d, every gate green 10:53, the fast-time SUMMARY PASS 10:54, the floor at DAA 82,800 about 16:53 BST, a publish up to 14:53 without a second cut); the tiers' class-key halves: the UI lane's tiers-class-25 d949e274 green and inert alone, merged with the hash lane's engine sha the moment it lands (12:30), gated as a pair on the release tip, riding only if green by the 13:00 pin; the 0.3.24 Windows take 2 failed at a new place (Inno stopped the app and copied nothing); the update-return lane owns the fix on release-0.3.25 by 12:30, the default the 0.3.25 Windows entry waiting for a clean take 3 while Mac and HiveOS move at the minute. THE FOUR CLASS V6 RESEARCH LANES SPAWNED (the coordinator, 11:0x BST, each with its worktree, its box resources under lease class measure, its clocks and the rules): lane A history (a603a938582c43ab5; the first cut docs/analysis/class-v6/history.md by 15:00), lane B the hardware future (a4f73e2a6f2d1b757; hardware-future.md by 16:00), lane C invention (a5dfe95ee8c47cd0f; invention.md by 17:00), lane D the family gate (a07a99a3788566af2; family-gate.md by 17:00); each feeds the research lane's synthesis docs/design/class-v6-rotating-family.md by 20:00 (its outline by 13:00; the hash lane's per-tier rows by 16:00); the full reports by 09:00 tomorrow; the coordinator's lane mirror carries their clocks. A HELD PUSH AND ITS CAUSE (11:00 BST): the hash lane's push of ca3-v4-amend was refused at 10:58 by the gh-account hook reading the founder's gh (his personal login active again; nothing switched by any lane); the cause is the branch's own hook, which predates the per-process fix (34b0884d): the hook runs the branch's tools/ci, so every branch older than 09:58 must merge the mirror's master before its next push, under which the check reads Igneum's own gh directory and skips under the suspension marker; the rule to every lane. Live: the Arc re-read on PC 2 (published 10:59:47) and the v5lock job on PC 1 (published 10:53, about 12 minutes). THE CLASS V6 OUTLINE ON THE MIRROR (the research lane, docs/design/class-v6-rotating-family.md on counter-asic-4, the commit after fb61ed4b, pushed 10:5x UTC, two hours ahead of 13:00): section 0 the founder's table (per layer, what it does to a fixed-function chip and to a GPU-like chip on its release day, and the 5090, 5070 Ti and M5 Max columns, measured where the night's rows exist, the 5070 Ti scaled until the hash lane's row); the honest frame on top: the four layers render a FIXED-FUNCTION chip useless on the first era its wired value leaves (one tape-out lives one era) and move nothing for the stored-dataset chip with a programmable core except the core's size and the N5 project it forces; that chip keeps 3.6x at zero premium and 2.1x at k = 1 on a 5090 at its knee. The layer table (sections 1 and 2) names the bands each draw takes and the measured rows that set them: the mixer in {4, 8, 16} (x16 open), the op-mix weights within B = 4 with shuffle and mulhi capped (shfl 55.8 pJ per op), the read width in {1, 4} words (w64 excluded by the 5 October rows), the block shape 64 to 256 (never 1,024), N left to the ladder's signal (an unconditional draw retires the Apple tier at 200,000). Open numbers asked of the hash lane with defaults at 16:00: the 5070 Ti row (the rented 5070 scaled), the x16 mixer's verifier and build (the chip model's estimate), two re-weighted shadow packs for the op-mix band (the microbench arithmetic). Layers 2 to 4 and the gate plan are skeletons with their sources named, filling by 18:00 with the four research lanes' cuts, the synthesis by 20:00. THE FOUNDER'S WORD AT 11:2x BST ("all builders are idle, load them up"): build-1 to build-4 filled now and kept above 80 percent all day under the lease pool, class measure behind the release gates, in this order of value: (1) the class v6 family gate's sampling runs for lane D (the F8-form census and the (c''') floor over the parameter bands: the mixer {4, 8, 16}, the op-mix weights within B = 4 with shuffle and mulhi capped, the read width {1, 4}, the block 64 to 256; thousands of drawn eras, the uniformity and bucket tests on each, so the family document carries measured coverage tonight); (2) the attack families at scale on the 0.3.25 pin candidate's igneum-pow (F8 to 256 seeds, F9 and F1 to 10^6 on the frozen 1c420786, the day-key scan to 2^28) as the record's strengthening lines; (3) the invention lane's candidate layers measured as packs as fast as it writes them; (4) the full suite matrix of the 0.3.25 pin on every box as the pre-pin check; (5) the Windows and hive cross builds and the sweep's reruns; the lease tool's pre-emption giving release-class work the cores when the pin's gates need them; one line to main at 12:00 with the load on each box and what runs there, then hourly only if a box drops idle. THE DRIFT CLASS SETTLED (the node lane, from the fleet's fresh-walk node, a shared-devnet node synced from an empty datadir to 191,441 chain blocks at 10:03:45Z): hub-1 and five standing boxes number the fresh chain exactly; seven boxes carry numbering inherited from an exec snapshot taken on a chain that later re-walked (+2: p1-4090, p1-a5000, pool-1, build-1's node1; +3: p2-3090-2; +4: p2-3090-4; +5: p1-5090 and p2-3090-3), and a restart on the kept datadir does not re-walk (p1-5090 at 09:22Z stayed +5); the cost: a prover on drifted numbering signs statements the hub vetoes, so the seven earn nothing from proving until they re-walk, the drift refusal stopping the waste. The node lane's word to the fleet: p1-5090 first, both snapshot files moved aside so the executor re-walks from the DAG, the re-walk timed and read against the fresh node, then the other six in series, hub-1 untouched, build-1's node1 after the 12:40Z move; if the re-walk reads over two hours the six wait for the node-side fix on the next node line (the loader re-numbering a resumed range against the DAG before serving). THE 0.3.25 PIN CANDIDATE CONFIRMED (the node lane): e0644958 on both mirrors (keygen, the re-announce, the ceiling switch at 82,800 in the Devnet 3 object, digest 1b37cb9d, the 0.3.24 pin refused both ways), every gate green at 09:53:01Z, the fast-time SUMMARY PASS at 09:54:40Z on the same object; the publish ceiling DAA 75,600 (14:53 BST); waiting only on the 68,400 crossing reading clean (about 12:54; the node lane's line the moment the DAA passes it); the shipper names the pin at 13:00; the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15. LANE C'S FIRST PACK (the invention lane, 11:0x BST by the Mac's clock; its own line read "12:1x", a clock to correct): build-1 takes the igneum-pow build from counter-asic-4 at 5984ffab, then the per-load shadow in its sound form (mx8+shl6912x1: 16 sub-blocks of 432, one pass, the form 20.2a named and never drew) as the first candidate: the acceptance census over 64 seeds and 16 drawn eras against the 16x27 form and the class v4 shape, the pack export, the F8 read at 2^24 and the verifier bench on a leased core, the first read by 13:30; build-2 next for the second candidate (warp-uniform data-dependent block selection); the candidates with no pack form (the VDF commitment, the VRAM ratchet, the pool-sampled witness, the state-tied reads) stay modelled and the 17:00 cut says so; the worktree igneum-wt-v6-invention on class-v6-invention. THE WINDOWS INSTALLER CLASS AND THE 0.3.25 TIP (the shipper, 11:08 BST): the app tip 139c147a (9b93e649 plus install-detach-25 52a34111, packaging/windows and tools/ci only, the crate unchanged; push gate GREEN); the 0.3.24 take 2 class: an installer started under the app's job runner is a child of the engine, and the engine's kill_tree on quit ended it between PrepareToInstall and the copy; the fix re-launches the installer as a one-shot scheduled task outside the job's tree; the 0.3.24 Windows entry skipped; the rule-14 take on PC 2 is the 0.3.25 installer over the running 0.3.21 app, queued ahead of the Arc re-read; the pin candidate e0644958, the DMG 501ba293 staged, the 13:00 pin and the 13:40 provisional minute standing. THE ATTACK FAMILIES AT SCALE (the attack-pass lane, cores held at 11:08 BST, every run under lease pool class measure): box 2 (88 cores): F8 seeds p66 to p257 (192 new, 256 with the gate's p2 to p65) at 2^24 on class v5 at the freeze 1c420786 (the gated binary 0f5c98dc, pairing e5a4ac5978462156; the leaves re-run on 8f481459 if the kit pairing flips), the window-model control, by-site, as three thirds of 64 seeds; box 4 (80 cores held, 16 asked): F9 to 10^6 on 1c420786 (seeds 100,000 to 999,999 in six chunks of 150,000 at 8 threads, four running), F1 to 10^6 class v5 programs on 1c420786 (one census at 40 threads with the progress line and flushed partials, re-drawing the record's first 10^5 on the way as a reproduction check), the F4 day-key scan to 2^28 on 8ca66afa's redraw rule at 8 threads; nothing on build-1 or build-3 (lane D's); the projections: F4 about 2 to 3 hours, F8's 192 seeds about 9 hours, F9's 900,000 and F1's 10^6 about 30 hours each, so the 17:00 default is partials for those two with the lane (d) rows carrying counts so far; any pre-emption by release-class work reported. THE RPC AND THE 0.3.25 PAIRS ON THE PIN CANDIDATE (the build-server lane, 11:0x BST): rpc.devnet.igneum.network up since 11:08 BST (the first of the founder's builder clocks, 52 minutes ahead); the 0.3.25 pairs on e0644958 running on build-1 since 11:06 (the app tip 139c147a), the Windows and hive crosses on build-2, build-3 and build-4 as reproducibility rows at class release by about 12:40; the sweep reruns' list not held by the lane, the default at 12:30: last night's sweep logs on build-1 read for rows that ended without a result line and those rerun at class measure. THE SWEEP RERUNS' LIST (the fleet lane to the build-server lane, 11:1x BST): the fleet ran nothing under the build boxes' lease pool last night (every fleet bench a rented GPU one-shot), so the rows the lease kills cut short are the hash and class lanes' and the build-server lane's default read on build-1 is the right one; the fleet's own rows without a result (A10, A40, A100 40 GB, H100 NVL, H100 PCIe, MI250, RTX 3050, RX 7800 XT, 7900 XT, 7900 XTX, 6900 XT) are provider gaps needing a GPU host, rerun the moment a provider lists one. THE CLASS-FLIP TIERS, BOTH HALVES (the UI lane, 11:13 BST by the Mac's clock, 1 h 47 min inside the 13:00 pin): tiers-class-25 at 081b3ba7 (the display d949e274 plus the hash lane's ember-tiers-25 0a838072, on release-0.3.25's 9b93e649; the field names matched exactly): the crate gate GREEN 305 + 35 + 8 on build-1, the pre-push GREEN 60, the UI tests 78 green known-failed first, the push gate GREEN; with the shipper. A RED ON THE RELEASE TIP, for the shipper and the update-return lane: release-0.3.25's 139c147a is red on one crate test (ota::return_tests::no_relaunch_while_an_installer_runs_and_a_relaunch_when_it_clears, 304 of 305): install-detach's 0c588b09 reshaped the installer's clear step into a multi-line block while the test asserts the one-line literal at app/igneum-app/src/ota.rs:1348; 9b93e649 passes; the fix is the test's literal on the install-detach line; the UI lane built on 9b93e649 so its tip is green alone. A RED FROM THE PIN MATRIX (the CI steward, 11:13 UK): the core suite fails on the pair (the node e0644958 with the app tree 9b93e649): config::params::tests::fast_time_60x_file_is_the_devnet_at_60x panics "override-60x.json lacks the field base_unit_decimals"; the field was added by 0e4ec18a on ca3-v4-node yesterday at 21:45 UK and reached neither master, release-0.3.25 nor the app tip while the node line's test demands it; so every box reads red on core, and the fix is one line on release-0.3.25 (the cherry-pick of 0e4ec18a, or "base_unit_decimals": 8 in infra/fast-time/override-60x.json); sent to the shipper; green so far pow and app on build-1 and build-3; the two new boxes' toolchains read the same as build-1 (Ubuntu 24.04.5, glibc 2.39, the pinned rustc, sccache and lease, no nvcc). The founder's fourth load item paid in its first ten minutes: a red no single-box gate had read. MAIN'S WORD ON THE TWO REDS (11:1x BST): the install-detach fix belongs in 0.3.25 if it can make it, since a Windows install by any path that lets the engine's job runner kill the installer mid-copy is the plug-tune-play fault class (an update a user repairs by hand); the default order: the update-return lane fixes the ota.rs literal by 12:00; if 139c147a plus the fix is green on the crate gate by 12:15 the cut goes from it, else from 9b93e649 with the detach on 0.3.26 and the record saying Windows installs by job stay unreliable until then; the missing 60x field: the CI steward lands the one-line field on master and the release line by 11:45; the pin slides under the shipper's authority inside 14:53. THE DAY-KEY SCAN TO 2^28 (the attack-pass lane; class-v5 8ca66afa's redraw rule, build-4 under lease pool 8 class measure, 379.2 s, census-2p28.md at 10:15Z, 11:15 BST): days with any gain over 1.1x: 0 of 268,435,456 on M1 (median 226), 0 against the mean, 0 on M2, 0 on ROT and RC; the M1 cost mean 225.791, sd 6.073, min 206 (day 27,016 at 1.0971x, the redraw rule's floor: no day under 206 in 2^28), max 258; every weak class on its analytic expectation (ROT any pair summing to 32: 160,354,008 against 161,256,979; RC any zero: 1 against 1.0, at cost 234, no gain; RC with rk = 0: 87 against 72, 1.8 sigma; the two cells under expectation the rule's own refusals). PASS: no chip buys a weak day in the first 735,000 years of days; at most 1.097x on the best day. The row and f4-weakday.md section 10 committed on attack-pass at eabb4b0e, the push held by the branch's old hook (the fix: merge master, under which the check reads Igneum's own gh directory and skips under the suspension marker). THE SWEEP RERUNS' READ (the build-server lane, 11:18 BST): build-1's records hold no hash-lane or v5-lane run the pool cut short (preempt.log: three TERMs all night, every one to an adv-class holder pre-empted by a release gate, not reruns by rule; no reaped.log; builds.jsonl for 18:00Z to 09:00Z 150 rows with no signal end, the non-zero rows the fast-time gate's designed failed cases and build errors; the census and fingerprint suites leaving no builds.jsonl row and no output directory ending without its result); live at 11:17Z the family gate's v5_attempts_census holding 24 cores on build-1 at class measure; the default at 12:30 if neither lane names a run: no reruns, the boxes carrying the e0644958 reproducibility crosses (build-3's Windows pair already read: igneumd.exe 4b0c3aeb, igneum-miner.exe b3da4088) and the gates. The founder's fifth load item is therefore the crosses, not reruns. The attack-pass branch merged master and pushed (460fd9fa, the F4 2^28 row and f4-weakday.md section 10 on the mirror; the hook skipping the gh read with its suspended line; nothing switched). THE FAMILY GATE'S FIRST COVERAGE (lane D, 11:2x BST by the Mac's clock; its own line read "11:3x"): the harness live on build-1 under lease pool class measure (scripts and pinned binaries under /srv/builds/_adv-family-gate/): (1) the base control v5_attempts_census on the shipped class v5 draw over f8-label seeds 1,000 to 11,000, 24 cores since 11:16; (2) the family harness family_gate_era_census (branch family-gate-v5 = class-v5 8f481459 plus the harness, never a chain path; the acceptance keyed on the family's shapes behind IGNEUM_FAMILY_GATE): one drawn era per seed, every layer-1 parameter from the era's own stream (the shadow block {64, 128, 256} x {108, 54, 27}, the mixer {4, 8, 16} recorded, the read width over {1, 4} words, the ten weights within B = 4 with shfl and mulhi never raised), the chain draw through the real rule with every candidate's first failing part, then on the accepted program at the rule's own 2^20 sample the (c'')/(c''') ratio, the largest 256-item bucket per site (ratio and sigma), the index-bit bias per site in sigma; the 16-era smoke run PASSED at 11:21 (about 10 core-seconds per era; 10,000 eras about 28 core-hours). THE WORST READINGS IN THE 16: (a) the index-bit bias read fires HARD on 7 of 16 eras, |z| 130 to 511 at one site, every one at address bit R (the era's stride rotation) or R+1 (era 15 with R = 25 bit 25 z -511 at P(bit) 0.25, a product's bit 0; era 7 R = 17 z -468; era 5 R = 26 z -440; era 13 R = 1 bit 2 z -255, a product's bit 1 at 3/8; era 1 R = 6 z -224; era 12 R = 5 bit 6 z -130; era 6 R = 18 z +256, an or-shaped source at 5/8), the other 9 under |z| 3.8: adv-cache-2's era-stride class measured at the acceptance's own sample on class v5 accepted programs: not diffuse at the bit level, a 25 percent bias on one address bit of one site in about 40 percent of drawn eras, which (c''') does not see (min ratios 0.9954 to 1.0000); a chip holding the favoured half of that site's window serves 75 percent of its reads instead of 50, about 1.6 percent of a hash's reads at f = 1/2 for one site, which does not move the f = 1 verdict but is an auditor's flag on "uniform random reads"; the lever is load_index's form (fold the product's low bits before the rotation), not a floor (a 6-sigma refusal would redraw about 40 percent of epochs): a class v6 design row. (b) The (c'') ratio min 0.9954 (era 7), the rest 0.9965 to 1.0000. (c) Attempts: 14 of 16 accepted at attempt 0 or 1; era 9 (shape 64, width 4, mul 11 and or 8 of 75) took 24 candidates: the lossy corner raises r, the exhaustion number to read per stratum. (d) The largest 256-item bucket: ratios 2.2 to 2.4 at full-window sites are the CLEAN maximum (65,536 Poisson(16) buckets, +4.4 sigma), so the F8-tail bound must be stated in sigma, not ratio (the sigma column in the rebuild). Next: the random stratum (10,000 eras) and the corner strata (the lossy cap, width 4, shape 64, 3,000 each) on build-1's free 64 cores, then build-3 and build-4; the first cut of family-gate.md drafted, the measured coverage table in at 16:xx for the 17:00 cut. THE OTA TEST LITERAL FIXED (the update-return lane, 11:23 BST, ahead of both clocks): ota-test-25 off release-0.3.25 139c147a, tip 53cb2f73 on the mirror, one test-only commit (the test reading the installer's clear step as the begin/end block the detach made it; the detach's behaviour kept), the box 2 crate suite 303 + 35 + 8 passed, 0 failed, the full gate GREEN 60; the shipper's cut tip 139c147a plus this commit, so the install-detach rides 0.3.25 and the PC 2 rule-14 take runs on it. THE 60x FILE, THE WHOLE FILE NOT ONE FIELD (the CI steward, 11:25 UK): the test names the first missing key in key order; with base_unit_decimals in it named emission; the file on master and release-0.3.25 lacks six keys the 0.3.25 node line's OverrideParams has (base_unit_decimals, pool_split_activation_daa, program_class_v5_activation_daa, proving_base_fee_ceiling_multiple, proving_fee_ceiling_activation_daa, subsidy_per_block_activation_daa); ca3-v4-node's copy (81 keys, master's 75 plus those six, no shared value differing) passes on build-3 by hand; release-0.3.25 got the one-field commit 907fdaf4 at 11:23 and the whole-file commit follows through the hook's gate, master the whole file behind the one-field landing; the known-failed on record on all four boxes; the green from the core re-runs in the 12:30 matrix; the risk named to the shipper: an older daemon reading the file with deny_unknown_fields. THE INDEX FOLD AS A CLASS V6 DESIGN ROW (the research lane, docs/design/class-v6-rotating-family.md on the mirror, the commit after 206e81e1): load_index folds a product's low bits before the stride rotation so no era's R lands a biased bit on an address bit (a design row, not a draw and not a floor); the evidence lane D's 7 of 16 drawn eras at |z| 130 to 511 on address bit R or R+1 with the (c''') ratio blind to it; the chip row 1.6 percent of a hash's reads at f = 1/2 for one site and zero at f = 1; the cost 0 on every card (one xor-rotate on the address path); the known-failed test lane D's 7 of 16 reading 0 of 16 with the fold; the value-level bias test in layer 4 ordered after the fold as its guard; the F8 tail's largest-bucket bound restated in sigma against its own window's Poisson expectation. The 60x commits: the one-field commit on both lines (master 7be52d76 at 11:24, release-0.3.25 907fdaf4 at 11:23), the whole-file commits in their gates behind it (release cbbaa8c4 pushing, master's queued). CLASS V5 AT THE KNEE ON THE 5090 (the hash lane, run-ca3-pc1-v5lock-5090-20261008-b, 11:09 to 11:21 UK, the 5090 alone, the v5 kit's CUDA worker on the rotate-fold build 8f481459, 60 s rows, the cleared helper sequence; an hour ahead of main's 12:30 clock): the same genesis seed, class v4 against class v5: unlocked v4 135.82 MH/s at 458.3 W (0.296 MH/W), v5 135.90 at 474.3 W (0.287); at 1,300 MHz v4 125.92 at 294.0 W (0.428), v5 125.93 at 299.8 W (0.420); at 1,200 MHz v4 115.69 at 273.3 W (0.423), v5 115.87 at 278.6 W (0.416); the Devnet 3 epoch-0 v5 pack (another seed, the fingerprint 82b19cbde8557ea5 matched on every row): unlocked 136.94 at 494.4 W, 1,300 134.10 at 315.6 W (0.425), 1,200 128.51 at 302.2 W (0.425). THE READING: at the knee class v5 loses 0.0 percent of rate against class v4 and costs 2.0 percent in watts (1.9 percent per hash), under main's 2 percent line, so the v4 knee stands, the tiers table says the class v5 rows are within it, and the UI lane's knee note stays off (knee_loss_pct 0 on the 5090); the A4000's 17 percent is a capped card's number: the 5090 at 1,200 MHz holds v5 level with v4 too, so the loss appears only where the power cap, not the clock, is the limit. Per tier for the founder: a 5090 or 5080 owner on a knee lock loses nothing at the class v5 crossing; a power-capped card (a datacentre card at its cap) loses up to 17 percent until its cap is raised or its class re-tuned. The 5080's rows after the v6 packs job if wanted; the AMD grid live on PC 1 since 11:25 (24 points, about 32 minutes). LANE B'S FIRST READING, RELAYED BY MAIN (11:2x BST), WHICH CHANGES THE CHIP MODEL AND LEADS THE 20:00 SYNTHESIS: a 2 GiB SRAM full store on one N2 die (about USD 500 of silicon, an N2 project of USD 100 M to 500 M) reads 13x to 17x the 5090 per joule at zero shadow and 2.7x to 4.8x with the shadow at the measured k band; layer 2 (the dataset tracking chain state) moves its capex, not its joules; the custom HBM4E base die (2027 to 2028) 6.5x to 14x, untouched by the four layers; PIM structurally blind to dependent random reads; and the M5 Max at 3.1x the 5090 per joule is the honest denominator. MAIN'S ORDERS: (1) chip-model-v3 gains the SRAM-store row and the HBM4E base-die row with lane B's figures and their claimed or measured marks; (2) the synthesis states the per-joule edge against the SRAM store honestly (3x to 5x with the shadow) and against the M5 Max, and prices the one layer that answers it: a dataset floor that grows on a schedule faster than SRAM cost falls, with the cost to a 12 GB and a 16 GB GPU and to 16 GB unified Apple memory stated; (3) the served chip line ("2.1x per joule at the knee") is reviewed at 20:00 with the measured basis for each clause; no served text changes before the synthesis, and if the SRAM-store reading stands the line becomes the honest range with the project cost and the clock beside it. THE SHIPPER'S THREE READINGS (11:2x BST): (1) override-60x.json: every reader in the tree is the fast-time harness, the sims and CI; no daemon on the fleet loads it; the app manifest's consensus.override is a separate 16-key object carried from the live manifest and untouched by the cut; the live chain's object is the digest's (1b37cb9d on e0644958); the harness's file only, the cut stands. (2) The cut tip cbbaa8c4 on release-0.3.25 (907fdaf4 plus the steward's whole-file commit; the crate and packaging trees byte-identical to 907fdaf4's, whose crate gate read 305 + 35 + 8 at 11:24; override-json-check passing): amd-clock-25 e2962b89, tiers-25 d3d0704a, the Intel header, the tiers class-flip pair 081b3ba7, install-detach-25 52a34111 with its test fix, the node-source pin e0644958, the host bc8d4f79, the fast-time file; the Mac DMG on it afa7f527 (45,766,741 B, the node pair 556926b1/d2dfe966), staging. (3) The knee note off on the 5090 rows. The pin at 13:00 on e0644958 and the 13:40 provisional minute standing; the matrix on cbbaa8c4 and e0644958 the steward's by 12:30. LANE B'S FIRST CUT ON MASTER (34f63b3c at 11:25 UK, four hours and thirty-five minutes ahead of its 16:00 clock): docs/analysis/class-v6/hardware-future.md with the three findings and the k bands (with the research lane, into the synthesis's section 7a on counter-asic-4 at ad37a50c); lane B's four decisions in its section 7 with defaults (the draw bounds by 20:00 via the synthesis; the dataset schedule unchanged; the M5 Max as the reference joule; the clock unchanged); nothing built or benchmarked, gh untouched; the full report by 09:00 adds detail only, no k band moving. LANE A'S FIRST CUT ON MASTER (docs/analysis/class-v6/history.md, 300 lines, merge 4c58ad65 at 11:26 UK, three and a half hours ahead of its 15:00 clock; the full gate GREEN 73 checks; primary documents read from the PDFs: the Least Authority and Bob Rao audits, Kik, EIP-1057, the RandomX design and v2, Tromp's README, the Fudan Equihash solver, Percival's lookup-gap note): 21 chip rows by mechanism (what each chip specialised, the miss, the timeline, the v6 layer, closed or not, the per-joule number), the in-depth sections (Ethash, ProgPoW, RandomX, Cuckoo, Equihash, Scrypt and Argon2, the no-chip hashes, kHeavyHash, CryptoNight, X16R, Lyra2REv2, the compute rows), the four layers against the history layer by layer, the tier consequences. THE HONEST VERDICT WITH THE NUMBER: the chip that stores the dataset (class C: every Ethash chip, the E3 at 1.0x, the Linzhi at 2.1x, the Jasminer X4 at 5.1x via DRAM hybrid-bonded onto a 40 nm logic die, the E9 Pro at 4.1x) is NOT closed by any of the four layers, every per-era draw and family epoch being firmware to it; v6 inherits 5.1x per joule on GDDR7 at zero premium (3.6x at the 5090's knee, 2.1x with the class v4 shadow at k = 1), USD 2.8 against 14.7 per MH/s; classes A, B, D's governance half and E are closed, mostly since v2 and v3. THE THREE LESSONS THAT BIND: (1) the stored-dataset chip is firmware-immune to every draw; only joules and memory growth move it; (2) automatic change beats the human fork only where it costs the chip a redesign, and the one such parameter is the memory: layer 2 as declared is not an anti-chip rate (a 32 GB board lasts 60 years at 0.5 GiB a year; the 8 GB card is out at year 12; the E3 the only chip a growth rule ever killed, 20 to 27 months after shipping, at the fleet's own 4 GB limit), so its floor and a per-tier ceiling are the numbers to fix, not the rate; (3) a steered address pattern is always found after launch unless the test lives in the acceptance rule, and every drawn parameter changes layer 4's null, so the census re-derives per era (2.2 s per candidate). CORRECTIONS TO THE 5 OCTOBER FILE: the Antminer X9 withdrawn May 2026 with zero units (not "July 2026 delivery"); RandomX v2 released 25 March 2026 with activation pending (not "no fork"); CryptoNight's secret chips at about 33 months, not 43; Vorick's "survives forks at under 5x" and "13 months for a startup" on no fetched page, marked unverified. Two asks with defaults: layer 2's ceiling (if no word by 20:00 the full report drafts it as GB per tier per year keyed to card-lifetime-2026-10-05.md, with the flag that a dataset tracking state literally outgrows every card inside a decade if state grows as Ethereum's did); the hardware file cross-cited, not repeated. The lane's web-search budget spent (200 of 200); further additions by direct fetch. LANE D'S STATE (11:2x BST by the Mac's clock; its own line read "11:5x"): the first cut committed on class-v6-family-gate at 55c0dc6a with the full gate running; the census at 640 random eras, 298 lossy-cap, 327 width-4 on build-1 and about 500 shape-64 on build-3, the two build-4 corners queued behind a full pool; the landing on the gate's GREEN, the measured coverage table in the 17:00 cut. THE SNAPSHOT DIGEST STAMP (the node lane, 11:2x BST; a wip on release-0.3.25-node under its suites since 10:28Z): every snapshot a node writes carries its consensus digest as a new last field (the day-streams field's fallback shape, so 0.3.24 files decode with no stamp); a node with its digest set refuses a snapshot stamped under another digest ("re-executing from genesis") and one with no stamp ("written by a node before 0.3.25"), the follower starting at genesis; the daemon sets the digest from its params; the tests known-failed first (another digest refused, an unstamped file refused, nothing loaded; a matching stamp resumes, the written file carries the stamp, a digest-less process resumes as before, the wire round-trips); if the suites read green the full gate set runs and it is in the pin at 13:00 BST. THE CONSEQUENCE FOR THE MOVE: every Devnet 3 node restarted on 0.3.25 re-executes from genesis (no file written before 0.3.25 carries a stamp), so the restart takes the chain's re-execution time, which a fresh 0.3.25 node on build-1 since 10:24Z measures now (about 30,000 chain blocks; the rate in the pin line). TWO READINGS BESIDE THE CAUSE: (a) build-1's three nodes differ at 26247 (node1 0x3f53a7b9, the seed 0x717e7dc8, the observer 0x4548c319), and the seed and node1 differ at block 0 already (0x275b0cce against 0x7e37a9fb), which the ba75bf6f file alone does not explain (both resumed their own files across the same restart; the seed also restarted at 02:00Z on 2720d8d2 from a 0.3.22 file); the fresh node's genesis root and its first divergence from each decide whether a second class (an older-object file on the seed, or the resume itself) is in play; (b) the fleet asked for the roots at 26247 and 15611 on hub-1's Devnet 3 node, dn3-g1 and every prover by 12:30 BST with each node's resume line. The loud status for a vetoed node (a veto counter, the last veto's line on the explorer's status, "state not fresh") on the same line if the suites leave time, else 0.3.26, the node lane's word at 12:30. MAIN'S WORD ON LANE A'S ASK (11:2x BST): the default stands (the GB-per-tier-per-year table keyed to the card-lifetime file, with the flag), and one schedule to price beside it so the 20:00 reading carries a decision: a dataset floor of 6 GiB at the v6 epoch (every 8 GB card keeps mining with its cache; the 6 GB 2060 tier drops), 10 GiB two years on (the 8 GB tier drops), 14 GiB at four years (12 GB drops; 16 GB and Apple 16 GB unified hold), each step by height like a class epoch, the schedule itself a consensus field, with the cost per tier stated as the year each falls off and the share of today's measured cards that is; against the chips: the hybrid-bonded DRAM chip sized at launch (the E3 class) dies at the first step it cannot carry, the SRAM store pays capex only, both said. Lane A's corrections to the 5 October file go into the record and the served texts tonight. MAIN'S WORD ON THE STAMP AND THE GENESIS CLASS (11:3x BST): the stamp rides the pin; the re-execution time goes in the pin line and the move plan per tier; the fleet staggers the restarts in thirds so the proving share never reads zero, and the hourly line says "re-executing" with the count until the last prover is back. The second class is a GATE, not a note: the seed and node1 differing at block 0 means one of them runs a different execution genesis, and a hub node on a wrong genesis is worse than any snapshot drift; the pin is not named until the node lane says which file each of build-1's three nodes and hub-1 loaded at genesis, which root is the network's (the fleet's roots at 26247 and 15611 decide it), and the wrong one is corrected or re-walked; if that is not read by 13:00 the pin waits inside the 14:53 ceiling and the shipper slides by its authority. The vetoed-node status rides 0.3.25 if green, else 0.3.26. THE 60x FILE LANDED (the CI steward, 11:31 UK, ahead of 11:45): release-0.3.25 cbbaa8c4 (the whole 81-key file on 907fdaf4, the hook gate GREEN 60) and master e295c0d5 (the same file, the gate GREEN 73); known-failed to green on record: core RED on the one test on all four boxes before, core GREEN on the fixed pair on build-1, build-3 and build-4 after, build-2's re-run running; the full matrix by 12:30. A NEW GATE ON THE PIN (main, 11:3x BST, from the reference-apps lane's read): node1-dn3 and the re-executed observer diverge from chain block 26294 at DAA 60,578, the 10:05 move minute; node1 executed a block the selected chain later dropped and never unwound it, so its numbering runs one high and its state and records diverge; that is the drift class and the likely cause of last night's proving collapse after a move; the stamp does not cure it. The node lane's order: a known-failed reorg test under the exec follower, the fix on release-0.3.25-node if green by 13:30, else the move with the mitigation (every node re-executes from genesis after the minute, the vetoed-node status loud) and the fix as 0.3.26 tonight; plus the roots census to count stale nodes for the fleet's re-walk before the minute; the shipper's slide authority covers the pin inside 14:53; if the fix needs past 14:53, the floor re-cuts from the next minute by the same authority; the explorer lane reads block numbers from the observer node only (the chain the certificates follow) until the fix is live. THE FAMILY GATE'S 12:00 COVERAGE (lane D, 11:3x BST by the Mac's clock, ahead of its clock): 4,900 drawn eras through the per-era tests on three boxes (build-1 random 1,444 and lossy cap 663 at 10 core-seconds per era; build-3 shape 64 at 2,162; build-4's two lossy corners queued behind a full pool); the full gate on the first cut GREEN (73 checks, 381 s), the landing on one re-gate after a merge conflict on export-exclude.txt with the research lane's line (resolved, both kept). THE WORST ERA PER TEST: (1) THE EXHAUSTION BOUND BREAKS AT THE LOSSY CORNER: with or, mul and mulhi all at +4 points (30 of 75 lossy against the table's 18), r per candidate is 0.956 (the table's 0.681) and 8 of 663 eras EXHAUST the 256-attempt cap (mean attempt 18.6, max 252), so 1.2 percent of epochs at that corner would take the last-resort program, which adv-accept-3 showed fails rule (a) in 9 percent of seeds; B = 4 with the lossy ops free to rise is therefore outside the band; the random stratum at B = 4 (every weight drawn, lossy ones included) reads r = 0.718, max attempt 107 and 0 exhaustions in 1,444, but 107 attempts is 4x the shipped max of 28; the ring-A rule the cut carries: the sum or + mul + mulhi at most the table's 18 plus B, so r stays under 0.85 (r^256 under 1e-18); the default by 17:00: B = 4 on the injecting families only, the lossy families capped at their base. (2) THE ERA-STRIDE CLASS AT THE BIT LEVEL ON THOUSANDS OF ERAS: 52 to 58 percent of accepted programs in EVERY stratum carry one site whose address bit R (or R+1, R+2) is biased at over 6 sigma at 2^20, 33 to 40 percent at over 100 sigma, the worst z 1,024 at bit 7 of a site under R = 7 (a product's bit 0 at P = 1/4 landing at bit R): adv-cache-2's mechanism at half the family's epochs on programs (c''') passes (min ratios 0.9950 to 1.0000); the chip price per site about 1.6 percent of a hash's reads at f = 1/2 against the partial-store curve's 1.26x ops cost: the f = 1 verdict stands, the "uniform random reads" sentence does not; the catch structural (the index fold in load_index before the rotation, the class v6 design row), not a floor. (3) The largest-256-item-bucket excess: clean full-window sites +4.4 sigma; the worst eras +94 to +128 sigma at one site (the F8 tail's quarter-bit class at scale, the same mechanism: the bucket at the biased bit); the bound in sigma from the clean spread in the 17:00 cut. (4) The (c''') refuse rate per stratum: random 2.56 percent of candidates, shape 64 3.41, lossy 0.42 (the lossy rejections earlier at (a')); 0 accepted programs under 0.995 anywhere. (5) VOID and rerun: the width-4 stratum ran at width 1 (the era's one-entry allowed set redrawing to the base's width; fixed, the harness rebuilt, restarted at 11:5x with its own label space); the first corner strata sharing the random stratum's label space coincide with its draw a third of the time; the reruns use per-stratum labels; both stated in the cut. Coverage by 17:00 at about 1,000 eras per hour per 16 cores: random 10,000, shape 64 3,000, lossy cap 3,000, width 4 3,000 plus the two build-4 corners; the rule-of-three line for the random stratum at 10,000 eras a failing fraction under 3e-4 at 95 percent for every ring-B test. THE V6 COST ROWS (the hash lane, 11:4x BST by the Mac's clock, its own line reading "12:4x"; four hours ahead of 16:00): with the research lane at scratch v4/ca4-v6-cost-rows.md, every row labelled measured or modelled; the layer-2 headlines: VRAM 3.2, 5.4 and 9.9 GiB at the floor, 2x and 4x; a 12 GB card falls off at about 9.5 GiB (year 15), a 16 GB GPU at 13.5 GiB (year 23), a 16 GB unified Mac at 8 GiB (year 12), the 5090 at 29 GiB (year 54); the DRAM-read cost per hash size-independent (the 5090's 1.11 microjoules of 2.29), so the layer moves capex not joules, and the card rows allow a floor of 4 GiB in year 1 and 8 GiB by year 4 without retiring a 12 GB card (main's schedule of 6, 10 and 14 GiB at the epoch, two and four years sits above that: the 12 GB tier drops at 14 GiB, the 16 GB holds); the measured size rows (the v3 pack at 2, 4 and 8 GiB on the 5090, unlocked and at 1,300) ride the v6 packs job after the AMD grid. The AMD grid: the first run refused in 2 s at no_tune_line (the old installed exe, as designed); the rebuilt exe on PC 1 by the update-return lane's fetch at 11:33, the rerun from amd-clock-25 572c3ee0 live since 11:39 (about 32 minutes, the rows about 12:15). The class key on the mirror (ember-tiers-25 0a838072 in tiers-class-25 081b3ba7, with the shipper since 11:13, inside the 12:30 reading). The Arc read waits on the shipper's PC 2 take; the 12:30 default "no Arc read" stands unless it starts before. THE DRIFT CLASS READ FROM THE LOG (the node lane, 11:4x BST): at 09:42:09Z node1-dn3 accepted 0x6aa6 (DAA 60,578) and at 09:42:10Z 0xb708 (the same DAA and blue score 60,265, both children of 0x0fed at 26293: a tie at one height); its follower executed 0x6aa6 as chain block 26294 (28 transactions) and 1.1 s later 0xb708 as 26295 (the same 28 skipped as already included), with no reorg line between; every consensus view now (the seed, node1 itself, the observer) has 0xb708 as the chain block with the selected parent 0x0fed and 0x6aa6 off the chain, so node1's records hold an orphan at 26294 and number everything after it one high, and its state root diverged from there (the observer, re-executed from genesis, agrees with node1 to 26293). THE GAP: the 0.3.22 continuity rules (ledger N15) check the first appended block's selected parent against the tip at append time and scan the whole record set against the DAG's selected parents ONCE per state generation (a restart or a loaded snapshot); a break landing after that scan, as this one did ten minutes after node1's restart, is never looked for again until the next restart; the fleet's +2 on four shared-devnet boxes is the same gap. THE FIX on release-0.3.25-node (a wip under the exec suite since 10:41Z): the self-check runs every 30 s over the ring (the last 2,000 records) against the DAG's selected parents and in full on a generation change, a break handing the records above it to the reorg unwind (the existing branch restoring the ring state at the fork and re-walking); the test known-failed first on node1's exact shape; on the same commit the snapshot digest stamp (exec 51 of 51 green on its wip) and the vetoed-node status (vetoes counted on the status with the last veto's line, stateFresh false while any stands, on igneum_getNodeInfo and the status RPC); the exec suite's green about 11:46 BST, then the named commit, the full gate set, both canaries (the digest 1b37cb9d unchanged: nothing consensus) and the fast-time pair, the gated tip by about 12:30, inside 13:30. What the fix does not do: name why the tie-break flipped under node1 at 09:42Z (its DAG now reads 0xb708's parent as 0x0fed and the path at the time must have read otherwise; the second "PoW accepted 0xb708" line 0.4 s after the append says the block was processed twice), a reading for the record after the pin. The fresh 0.3.24-object node on build-1 past IBD and executing from genesis; its root at 26247, its rate and its memory peak in the pin line. MAIN'S WORD AT 11:4x BST: (1) lane D's band default stands (B = 4 on the injecting families only, or, mul and mulhi at base, the ring-A lossy-sum rule), and the index fold before the rotation with the bias test as its guard is layer 1's rule; (2) the served sentence "uniform random reads" is corrected today, not at the review: the audit lane rewrites it to the measured statement (reads spread over the whole dataset; a bit-level bias at one site appears in about half of epochs; it prices about 1.6 percent of reads to a chip storing half the dataset and nothing to a full store; the next class folds it out), through the gate and the master-only deploy, with the ledger row; (3) layer 2's table splits Apple by memory size (16 GB unified at its 8 GiB limit, 32 GB and 64 GB Macs holding every step), the M5 Max being the honest best per joule and the Mac tier a large audience; the schedule decision at 20:00 is the founder's with that column in front of him. THE EXPLORER'S SOURCE (the explorer lane, 11:4x BST): it reads one endpoint and always has, the Devnet 3 observer node on build-1 (the execution RPC on loopback 26850 through tools/observer/explorer-indexer.mjs, the observer's own dn3_ tables on 28650); it has never read node1-dn3, so there was no switch; the indexer on 26850 since 10:04 UTC with a full refill from genesis at 10:33 UTC after the root equality read at block 26,247; the pages now name the observer node as the one source, the chain the certificates follow (on explorer-dn3, in the gate; the merge and deploy follow). THE GENESIS GATE'S ANSWER ON build-1 (the shipper, 11:43 BST): the seed was the odd node (its block 0 from the 0.3.22 binary; the rule change for the node lane's record), re-walked from genesis at 11:35:30 by the shipper's hand (the evm moved aside, the same binary and flags, the kept datadir) and reading population A's roots at 11:43:00 (0x47983bd9 at 15611, 0x3f53a7b9 at 26247, head 26,478). THE MEASURED RE-EXECUTION: 26,478 chain blocks in 7 minutes 30 seconds (about 59 a second over the walk; 100 at the start, 30 past 15,000), RSS 5.5 GB; so the move plan's per-tier line: a prover's node is back about 8 to 10 minutes after its restart on 0.3.25 (30,000 blocks at the minute), a Mac or HiveOS app node the same at its update hour, miners unaffected; with the hub and the seed at the minute and the provers in two thirds at +0 and +25, the proving share never reads zero and the last prover is back about 35 minutes after the minute. The node lane's gated tip (the ring check, the stamp and the vetoed-node status in one commit, the digest 1b37cb9d unchanged) by 12:30; the pin after it and the fleet's census; the minute about 14:10 at the earliest if the fix rides, inside 14:53. LANE A'S SCHEDULE SECTION (history.md 4.2a, master 59963461 at 11:45 UK, five hours ahead of its 17:00 clock; three landings today: 4c58ad65, b645762d with the synthesis lane's six items folded in, 59963461): ONE FLAG on main's schedule with the number: under the standing budget rule (the working set under 6 GB on an 8 GB card, the 75 percent reading) a 6 GiB floor does not fit the 8 GB tier (6,398 to 6,744 MiB, 78 to 82 percent of the card; it fits only at a headless-rig reading of about 85 percent); 10 GiB retires the 10, 11 and 12 GB tiers and the Apple 16 GB laptop at year 2 (not the 8 GB tier alone); 14 GiB retires the 16 GB tier at year 4, leaving 24 GB and above. The schedule that drops the tiers in the order main named, priced beside it: 5.5 GiB at the v6 epoch (6 GB falls, 3 percent of the 32 measured consumer cards), 8 GiB at two years (8 GB falls, 22 percent, with the 10 GB RTX 3080 and Apple 16 GB; 12 GB holds at 69 to 72 percent), 11 GiB at four years (12 GB falls, 22 percent; 16 GB holds at 70 to 73 percent); 24 GB and above hold throughout. Against the chips: the f = 1 GDDR7 chip's 32 GB board pays USD 0 through 16 GiB and keeps 5.1x; the hybrid-bonded or soldered chip sized at launch dies at the first step it cannot carry (the E3's shape, 20 to 27 months) but a maker reading a public consensus field sizes to the step it wants (USD 160 of GDDR7 on a USD 470 part); the SRAM store pays capex only at the cache doubling (USD 46 to 111 per die) and keeps 0.92x and 1.86x. So the schedule is a fleet-retirement rule with a USD 0 to 160 chip tax, killing only a chip whose maker ignores the field. The default by 20:00: the full report carries both schedules and recommends 5.5 GiB as the floor that keeps the 8 GB tier inside the rule. Owed: the fleet's hashrate-weighted card census (the shares are by count of the bench table's 32 measured consumer cards). LANE A'S CORRECTIONS SERVED (the site audit lane, master 2119e4f3 at 11:46 BST, gate green on 78166c6c, commit 14ad1a33; seven hours ahead of 19:00): every served "no chip shipped" and "seven years without a shipped chip" sentence (the litepaper's precedents row, the chip-model paragraph, the vs RandomX lead and its track-record row, the limits section; /claims and /randomx following) now carries the Antminer X5 (September 2023, 1.46x per joule over a desktop CPU, silicon believed mining privately from about 2021) and RandomX v2 released 25 March 2026 with its mainnet activation pending; the ledger rows X34 and C2 corrected with lane A's file cited, the pins moved, the public ledger and page regenerated; the X9 sentence already matched lane A's row (sales opened 26 December 2025, shipping scheduled July 2026, withdrawn mid-May with zero units), the precedents and track-record cells now reading "withdrawn in May 2026 with zero units"; the 43-month, 13-month and Vorick figures on no served page; the commit also carrying main's governance line beside the class v5 sentence and six class v4 watts rows; the "random reads" correction with its AP-F8 row next by 13:30; the build-server lane deploys on main's word. LANE C'S FIRST CUT ON MASTER (docs/analysis/class-v6/invention.md at a9f03598, 11:48 BST by the Mac's clock, five hours ahead of 17:00, with the census script under tools/attack/v6-invention/ and its two TSVs): build-1 ran the per-load acceptance census (11 forms x 256 seeds, twice: no era and drawn eras, 80 s each on 48 leased cores) and the verifier benches; the two packs exported and with the hash lane for PC 1; the second candidate (warp-uniform block selection) has no pack form without a generator change, which the no-code rule holds this week, so its row stays modelled. A CORRECTION TO THE CA4 FILE'S VERDICT, FOUND BY LANE C: the counter-asic-4 crate's per-load acceptance (BiasedIndexBit) counts the era window's fixed top index bits 26 and 27 as biased, so under any drawn era it refuses every per-load program (0 of 256 on every form today, 5,536 of 7,862 bias rejections naming those two bits); 20.2a-close's "1.4 percent accepted, 42 of 64 seeds exhaust" (the per-load class's death at 00:0x) was read across drawn eras and so measured the instrument on most rows; on the no-era census the sound form (16 x 256 x 1) reads 0.927 rejection per candidate and 234 of 256 seeds accepted, the iterated 16 x 27 form 0.989 and stays dead; the one-line instrument fix (skip bits at or above 28 minus the site's k_off) is a research-crate change, made today as a research-only change behind the pack by the coordinator's order, and the sound per-load form's verdict is REOPENED as a measured candidate (its energy and rate rows on the 5090 through the hash lane; chip-model-v3 5.11's note on the per-load closure to be re-worded when the re-read lands). THE REOPENING APPLIED (the research lane, 11:5x BST): the reopened wording in counter-asic-4-research.md (20.2a-close and rank 4), class-v6-rotating-family.md (section 7c as layer 5) and chip-model-v3.md 5.11's note, with one precision: the 22:5x UTC census ran the bare class with no era, so its 0.986 is the iterated form's own no-era figure (lane C's 0.989 agrees the 16 x 27 form is dead); the artefact in any drawn-era read before the fix; the fix already on counter-asic-4 as of 10:5x UTC (BiasedIndexBit judging only the bits inside each site's window mask through verify::window, per site), uncommitted until the suite's line lands (the box-2 slot since 10:31Z), so lane C re-reads on that branch once pushed, not making the change twice; the chip-model 5.12 rows (the SRAM store, the base die, PIM's blindness, the M5 Max denominator) in the same tree, riding the same commit before 15:00. A MIRROR NOTE (11:52 BST): lane B read silent 25 minutes by the mirror; its first cut landed at 11:25 and its next clock is the full report by 09:00 tomorrow, so the silence is its finished state, not a fault; the mirror now skips lanes whose clocks are done. A MASTER-ONLY DEPLOY AT 11:53 BST (the build-server lane, on main's own builder-programme landing d86ea00a: /build, /grants, /faucet, /swap asserted; the served sha a9f03598, master's tip; the checks ok; 38 miners rows): it carried the audit lane's 2119e4f3 (the RandomX history correction with the Antminer X5 and RandomX v2, the governance line, the first six class v4 watts rows), which main ordered served tonight and the audit lane cleared for the next scheduled deploy; the "random reads" sentences not yet corrected as served; the coordinator's trigger stands for the 13:30 correction. LANE C'S KNOWN-FAILED TEST FOR THE INSTRUMENT (11:5x BST): igneum-pow/tests/v6_window_bits.rs, the sound form (16 x 256 x 1) accepting on at least 4 of 8 seeds under drawn eras 0 to 7 with 0 window-bit refusals (0 of 8 before the fix), the no-era bit-0 refusal on seed 3 standing; 2 passed, 0 failed on build-1 against a local overlay of the same nine lines, the overlay reverted, the test file an offer to the research lane's suite; the re-read on the research lane's commit by 15:00; meanwhile build-1 runs the lane's uniformity read at 2^20 nonces on 64 seeds for the two sound per-load forms and the class v4 shape (the F8-form top-0.1-percent item share against a uniform control, the per-site distinct ratio) on a harness over the crate's trace_load_indices (the master F8 tool mirroring class v4's execution order), about 20 minutes on 24 leased cores. THE RANDOM-READS CORRECTION ON MASTER (the site audit lane, bf54b08d at 11:54 BST, gate green on db038279; an hour and a half ahead of 13:30): the litepaper's lead reads "dependent reads spread over a multi-gigabyte dataset that changes daily", the table row "the dependent reads are", the "chain of random reads into a table too big for a chip to carry" sentence standing with the measured clause after it (the 0.995 floor on every accepted program over 4,900 drawn eras; about half of epochs with one load site biased at the era's stride rotation bit; about 1.6 percent of a hash's reads to a chip storing half the dataset, nothing to a full store; the fold before the rotation in the next class); evidence row 18 with lane D's family-gate.md and adv-cache-2's section 2.3 as sources; the ledger row AP-F8-7 (AP-F8-6 taken on class-v5): "Open, priced: 1.6 percent at f = 1/2, nothing at f = 1; the served sentence corrected 8 October 2026", the disposition class v6 layer 1's fold with the bias test as guard; the public ledger and page regenerated; no pinned sentence touched; the fud-ledger's quoted history standing; the build-server lane deploys bf54b08d. BUILD-1 AT 11:55 BST (the coordinator's own read): load 107.6 on 96 cores; the lease table: the family gate 32 cores (the random stratum, 10,000 seeds), 16 (the lossy cap, 3,000), 16 (width 4, 3,000, restarted), lane C's uniformity read 24 of 48; 88 of 96 cores held, none waiting, no pre-emptions in the last ten minutes. THE 11:55 BST LOAD LINE (the build-server lane, all four boxes at the minute): build-1 (96 threads) load 113.7, the pool holding 32 for the family gate's random stratum plus 16 and 16 for its corners and 24 for lane C's uniformity read (88 of 96 held), the release and v5 builds outside the pool; build-2 (96) load 81.3, the pool holding 32 for the attack-pass F8 census (the thirds); build-3 (32) load 25.1, the pool holding 16 for the family gate's lossy-base stratum and 2 for the hash lane's x16 rows; build-4 (96) load 89.0, the pool holding 4 x 8 for the attack-pass F9 chunks 0 to 3 plus F1's 40 and F4 done; no release-class waiter on any box; the builders loaded, none idle. The founder's order at 11:2x is met at the minute: every box above 80 percent of its threads bar build-3 at 78 percent of 32, which the two queued build-4 corners and the next v6 pack take. The build-server lane's deploy of bf54b08d served at 11:56 BST, two minutes after the landing: the post-deploy checks ok (api/live igneum-devnet-3, the index strings, the legal line, 38 miners rows, the four builder pages 200), and the litepaper's lead sentence read back from the served page carries the corrected wording (wide parallel integer maths, warp shuffles, dependent reads spread over a multi-gigabyte dataset that changes daily, the program waiting on memory latency); the old "random reads over a multi-gigabyte" is absent. The CI steward's 0.3.25 pre-pin matrix with the shipper at 11:59 BST, 31 minutes inside its 12:30 clock: seven suites on four boxes, every cell green but the one known core red on the pair before the fast-time file (the same single test on all four boxes, the six missing keys), and core green on the fixed tree on build-1, build-3 and build-4 (170 passed each); build-2's re-run queued behind three lanes' suites and lands on its own; counts identical across boxes (pow 113, app 346, exec 49, miner 29, p2p-flows 38, consensus 134); the Mac's full gate on the 9b93e649 tree GREEN, 60 checks; build-3 and build-4 toolchains read as build-1. The matrix worktree sits at cbbaa8c4 (81 keys, igneum-pow identical to the pin's tree); the second matrix waits on the node lane's gated tip (by 12:30), the line by 13:15. The RX 9070 XT's first measured grid on the AMD knob (job run-ca3-pc1-amd-grid-9070-20261008-b on PC 1, 11:40 to 12:10 BST, 24 of 24 rows ok, the card reset to factory at the end): the rate flat at 18.93 to 18.98 MH/s on every point, the knob moving watts only; stock 3,292 MHz 195.8 W (0.097 MH/W); the clock offset alone to 2,924 MHz 159.2 W at -400 (0.119), clamping about 2,920 at -500; the power limit alone does nothing until -30 (184.4 W); best -500 MHz with -30 percent: 2,921 MHz, 149.3 W, 18.96 MH/s, 0.127 MH/W, a 24 percent saving at the same rate. Per tier: a 16 GB AMD home card gains a quarter of its electricity cost at no rate loss once 0.3.25's knob ships; it stays 3.5x behind the 5090's 0.43 MH/W at the lock, so last night's AMD reading stands (the read path, not the clock, is AMD's cost). The v6 packs job live on the 5090 since 12:11 BST (eleven packs including the three dataset sizes, unlocked and at 1,300, about 40 minutes). The Arc re-read not started on PC 2 (the shipper's take holds the box); at 12:30 the default "no Arc read" stands, the pairing 1c420786. The Ember priors committed on ember-tiers-25 at 1e966170 with known-failed tests, its suite queued behind build-2's slots since 11:46; the sha to the UI lane and the shipper on its green; if not run by 12:45 the suite moves to build-1 through a lease. Two master-only deploys from the builder stream, checks ok (38 miners rows, the six asserted pages 200): 0c64b24f at 12:07 BST, the explorer landing (explorer.igneum.network, /proving, /tx/, the dn3_ APIs reading "Devnet 3"; the explorer indexer unit moved to the master checkout and restarted, reading the observer only as main set), and 3355c098 at 12:16 BST (site/vercel.json only: the explorer host's root 307 to /explorer, read live). No chip text changed in either. Still in the stream: the reference-apps lane's /light, /receipt and /oracle (its gate since 11:50, the 13:00 default) and the audit lane's watts rows 11 and 12. A third master-only deploy from the builder stream: f0418c8d at 12:19 BST (main's word via the explorer lane: EXPLORER_EVM_RPC on the production env, so /api/explorer balances read live from rpc.devnet.igneum.network; checks ok, 38 miners rows, six pages); the public RPC's allow list tightened the same minute to igneum_get* (the two igneum_submit* writes refused), reported to main. No chip text changed. The /build lane DONE with every clock beaten: landed on master as d86ea00a (11:47 BST), deployed as a9f03598 at 11:53; /build, /grants, /faucet (the Devnet 3 faucet page) and /swap serving in the nav's Build group; faucet.igneum.network/api/faucet live on build-1 behind Caddy, funded 2,000 IGN by the fleet lane (11:01 BST), the first drip 11:17 BST, 1,989.99 IGN left; the walkthrough PASS through the public RPC and faucet (a contract deployed at block 27055, 24 s end to end, Foundry 1.8.5, docs/build/first-contract.md); the RPC list read from the node in docs/build/rpc.md; the audit's four wording lines in. One open fact to the fleet lane: build-1's Devnet 3 seed at 27810 re-executing from genesis while the faucet reads the observer's 26850 (the re-execution class measured at 7 min 30 s this morning). Lane D's coverage at 12:2x BST, every launched stratum complete (the runs beat the 1,000-per-hour estimate once the pools freed): random 10,000 eras (0 exhausted), lossy cap 3,000 (37 at the 256 cap, 1.2 percent), width 4 at the fixed harness 3,000 (0), width 4 plus lossy cap 2,000 (24, 1.2 percent), shape 64 3,000 (0), the lossy-base band (B = 4 on the injecting families, or/mul/mulhi never raised) 3,000 (0); 24,000 drawn eras through the per-era ring-B tests on build-1 and build-3; build-4's shape-64-lossy and shape-256 strata still queued behind the attack pass's F9 chunks and not needed for the cut. The exhaustion finding confirmed at scale: 61 of 5,000 eras at the lossy corner reach the last resort against 0 of 19,000 everywhere else, so the band rule (lossy families capped at their base) stands on measured rows. The 17:00 clock holds; the cut (coverage table, per-axis table, union-bound arithmetic, harness patch series) likely lands by 14:30 BST. The node lane's gated tip missed its 12:30 clock: the combined wip (the 30-s ring check, the snapshot digest stamp, the vetoed-node status, the reorg-unwind fix on the same commit) sat in build-2's queue from 11:41 BST at normal priority behind a Counter ASIC 4 suite holding a slot since 11:31, found at 12:21 and moved to build-1 at gate priority; the exec suite about 12:25, the named commit on green, the full gate set (build and consensus at gate priority, five suites, both canaries, digest 1b37cb9d unchanged) about 12:50, the fast-time pair about 13:05, inside the 13:30 clock. The coordinator's default revised and taken by the lane and the steward: the second matrix starts on the named commit the minute its sha exists; no sha by 12:50 and the matrix runs on e0644958, the stamp and vetoed status slide to 0.3.26. The pin reads about 13:15 to 13:30 rather than 13:00; the minute about 14:10 holds if the fix rides; reported to main at 12:29. The seed's re-walk read equal to population A at 11:43 BST (0x47983bd9 at 15611, 0x3f53a7b9 at 26247; 26,478 blocks in 7 min 30 s, about 59 a second, RSS 5.49 GB); the fresh node on build-1 executing from genesis since 11:42:34 at about 100 a second at the start, its roots to follow. The lesson for the record: a release gate is dispatched at gate priority or it waits behind research suites; the node lane's wips were not. Main's correction at 12:3x BST on the fleet default: the 10:12 FETCHED count is not a census of state. If the stamp rides the pin, every node re-executes from genesis at the minute and the census is not a gate; if the stamp slides to 0.3.26, the census (block 26294's hash and the 26247 root on every prover) is a gate and the stale nodes re-walk before the minute. The fleet lane silent since 11:31: a one-shot at 12:36 starts a fresh fleet-move lane from the fleet root to take the census, the re-walks, the stagger and the pullers if it has not answered by then; the old lane keeps the hold and the hourly line. The 9070 XT reading goes to the audit lane for its row. Build-2's queued cell landed at 12:24 BST: core GREEN on the fixed tree (177 passed), so the first 0.3.25 matrix is green on every suite on all four boxes. The steward's gate-priority stream for the second matrix written (every suite at gate priority, its own results file), waiting on the node lane's sha with the 12:50 fallback armed; the line by 13:15. The AMD knob closed for the cut before 12:30: the 9070 XT grid's rows in and the efficient point in EFFICIENT_W as 149 W (both floors: clock offset -500 at about 2,920 MHz where ADLX clamps, power limit -30; 149.3 W at 18.96 MH/s, 0.127 MH/W, 24 percent under stock at the same rate); the rate flat over the whole ladder, so the knob is a watts lever only and the knee rule reaches the floor; amd-clock-25's gated tip 1be99aa0 (full gate GREEN 60, suite 298 green) with the shipper as the cut tip, the release section reading measured. The 5090 comparison carries two denominators, both real: 0.43 MH/W at the v4 1,200 MHz lock (133.8 MH/s at 305 W), 0.58 to 0.60 at the 1,300 knee (134.6 at 223 W); the 9070 XT at its floors is 3.5x behind the first and about a fifth of the second; a served row names its point. The Arc default taken at 12:30 BST: no B580 re-read reached the v5 lane, so the pairing line went to the shipper as the FREEZE 1c420786 (0.3.24's, as published) with the kit zip 65b47211 (packs-ca3-v5-20261008T085619Z.zip; its packs, ids and 82b19cbde8557ea5 byte-identical to 1c420786's by the packs test on both trees) and the Intel worker held out; 8f481459 (gate 73 GREEN, suite green, the Intel fix in) stands behind it and becomes the pairing with the Intel kit the minute an equal Arc read lands, with the page's Intel row moved. Nothing else of the v5 lane's in the cut. The shipper at 12:33 BST: (1) the 0.3.25 app tip is 89e83df2 (cbbaa8c4 plus amd-clock-25's gated tip 1be99aa0: the 9070 XT's efficient point 149 W at 18.96 MH/s in the ceiling table, the grid playbook; crate gate GREEN 12:28, 305+35+8, inside the 12:30 app window); the second matrix uses it with the node lane's sha. (2) On the node lane's hint, build-1's Devnet 3 seed and node1-dn3 were found dead since 12:06 and 11:54 BST (logs ending mid-line, no panic, no OOM; the observer and the fresh node lived): the network's seed was down 24 minutes; both restarted at 12:30 on their kept datadirs (the seed resumed its clean re-walk snapshot, node1-dn3 re-walking from genesis). Two reads before the pin: the build-server lane by 12:50 on whether any build-1 run kills igneumd by name (a cleanup that does so reaches the seed at the minute); the node lane by 13:00 on whether the line can die silently under the finality route flood the seed's log shows (a million drops on one peer). (3) The pairing the freeze 1c420786, kit 65b47211, the Intel kit out (PC 2 dark, no Arc read today); the genesis class closed on the fresh node's roots; the pin after the node lane's gate set, the matrix and the census; the minute inside 14:53. The hash lane at 12:4x BST: (1) the Ember search priors on the mirror as ember-tiers-25 1e966170, app suite green (307 + 35 + 8), with the UI lane and the shipper; the cut default stated to the shipper (in by the 13:00 pin or 0.3.26). (2) The v6 packs job on the 5090 (since 12:13): the four packs made on the box or pinned ran PASS unlocked (mx8-genesis 137.65 MH/s at 312.2 W; mx8_sh256x27 137.62 at 464.6; the invention lane's mx8_shl4096x1 135.99 at 428.6; mx8_shl2304x3 135.85 at 483.6; the 1,300 rows follow); the seven exported on the Mac this morning (today's x8 and x16, the two re-weighted, the three dataset sizes) were refused by the worker's seed check in 0 s ("IGNEUM_SEEDW_INIT is not attempt 0 of the epoch seed"): the string-seed export form derives different seed words from the byte-seed form the pinned packs use; re-exported in the byte form (the x8 reproduces the pinned id 73bcbfe8 and seed words exactly; the three sizes too; the x16 pair and the two re-weighted packs on generator 2 differing only in the era, the multiplier or the weight table); kit b and one more PC 1 job of those seven follow the running job's close, about 13:00 to 13:45, rows to the research lane, the invention lane and the coordinator. The invention lane's reading so far: the sound per-load form at class v4's instruction count (shl2304x3, 55,296 shadow ops) costs 483.6 W against sh256x27's 464.6 W unlocked, 19 W more, not under; the one-pass form (shl4096x1, 32,768 ops) 428.6 W; the lock rows decide the per-load candidate's GPU side. The export-form lesson for the record: packs for the worker are exported in the byte-seed form, never the string-seed form. Main's load order at 12:5x BST: lane D's two remaining strata (shape-64-lossy, shape-256) move from build-4's queue (behind the attack pass's pool) to build-3, idle after lane D's strata; build-3 kept fed with lane C's packs and the family census's next corners; nothing new on build-1 (load 142) until the pin is named, its gates at gate priority. Sent to lanes D and C with the 13:05 default. The node lane's two readings at 12:4x BST on the combined tip: (1) the build-1 deaths were the OOM killer (the build-server lane read the kernel ring: the seed at 44.6 GB anon-rss at 12:06:07 BST, node1 the same class at 11:54, two 31 GB attack binaries beside them); what grows is the proof pool's in-memory proof map: since the late-join rule (0.3.17) every proof a node receives is held by hash in memory and never removed (the entries leave the 600-block record window and the on-disk archive drops below the pruning point, the map did not); about 1.2 MB a proof, 14,107 proofs on the observer after a day (17 GB on disk, 13.6 GB RSS), the seed at 128 inpeers took the relays fastest; older than 7bd2940f; the fix (a proof leaves the map and the verdict cache with its record at the window's end unless another live entry names it; carried proofs served from the archive; known-failed test) on the tip under its exec suite at gate priority since 12:35:55. (2) The ring check's known-failed test on node1's shape green (exec 53 of 53 at 12:34:53 before the pruning went in). The named commit (the 30-s ring check, the snapshot digest stamp, the vetoed-node status, the proof-map window, over 7bd2940f's re-announce and keygen and the ceiling switch) follows the exec line about 12:40, inside the 12:50 fallback; the full gate set at gate priority on both boxes, both canaries (digest 1b37cb9d unchanged) and the fast-time pair after it. The fleet's census (12:31 BST): 36 nodes on population A, the network's genesis root 0x7e37a9fb; 21 stale nodes, each with a genesis root of its own, re-walking from 12:35 in thirds; dn3-g1 died a third time at 11:55:47 (the same OOM class on a rented box the likely reading; the fleet's hourly RSS per node with a restart above 32 GB is the guard until every node is on the tip). Lane D on main's order, done 12:36 BST: build-4's two entries cancelled before running; build-3 carries four strata on the fg6 harness (42f2c77f), 8 cores each under class measure: shape256 (3,000) and w4lossybase (3,000) running, shape64lossy (2,000) and w4shape64 (3,000) queued behind them on the 24-core pool; the lossy band at B = 4 across the injecting families is the complete lossy-base stratum (3,000 eras, 0 exhausted, r = 0.595). Build-1's queued attack-f8 rebuild chain cancelled (the point-B live census moves to build-3); what remains there started before the order (four lossy-share strata at +1 to +4 points, 16 cores each, about 900 of 3,000 eras; the point-A live census at 2^24 on 32 cores). The 17:00 cut committed at 2a595e1b with the 24,000-era coverage, its gate re-running. A shared-Mac fault class found at 12:3x to 12:4x BST: the class-v5 lane's shell command ran pkill -f "tools/ci/pre-push.sh" before its own gate, which killed every lane's gate on the Mac: the record's merge gate three times, the invention lane's landing twice (d6955381), the family gate's once (exit 144). The kill-by-name class the 6 October rule bans in scripts (kill-by-name-check.sh), applied by hand on a command line. The word to the lane: kill only your own gate by its pid; gates on the Mac do not share a lock. Reported to main. The research lane's commit 0ab27582 on counter-asic-4 (the mirror, 12:4x BST, ahead of the 15:00 clock; the crate suite green on the committed tree, 116 passed, 0 failed, build-2 12:38, master's new derivation test among them). It carries: (1) chip-model-v3.md section 5.12, the two chips with lane B's figures and marks (the 2 GiB SRAM store on one N2 reticle: 17x at zero shadow, 8x to 30x on the read band, 2.7x at k = 1 and 4.8x at k = 0.5 with the class v4 shadow, 3.7x and 2.0x at the card's whole shadow, USD 400 to 600 of silicon, an N2 project of USD 100 M to 500 M and 18 to 24 months, a break-even cap of about USD 330 M to 1.7 B on the mission lane's model; layer 2 moving its capex, two dies at 4 GiB 15x and four at 8 GiB 13x; the custom HBM4E base die 6.5x to 14x untouched by the four layers; PIM structurally blind, 1.6 percent of reads in-bank at 2 GiB; the M5 Max at 0.78 microjoules the honest denominator, 3.1x the 5090) and 5.11's per-load note in the reopened wording; (2) the merge of master (the sub-version 3 line, the derivation recorder, the re-exported packs) and the per-load bias test's fix (judging only the bits inside each site's window mask; lane C re-reads on this id); (3) the class v6 document through section 9: the lead on the SRAM store, the per-tier schedule table with lane A's checked steps (6 GiB does not fit the 8 GB tier under the 75 percent rule; 5.5 / 8 / 11 GiB drops the tiers in the named order, about a quarter of today's measured consumer cards per step), the measured M5 Max size rows (-12 / -20 / -22 percent of rate at 2 / 4 / 8 GiB, the one card that pays rate for a larger working set), lane D's rings and band, the index fold as a layer-1 rule, the 5070 Ti pair, the x16 mixer at 11.4 ms loaded by the right method (admissible false on the measurement), lanes B, A and C taken in 7a to 7c, and section 9's served-line review with the wording proposed for the 20:00 word. Owed for 20:00: the 5090 size rows (the hash lane's v6 job), lane C's 15:00 re-read, lane D's 17:00 table, the two re-weighted packs' rows; each lands as a row with its label, or its default. Main's word at 12:5x BST on the kill class: the rule "no kill by name on the Mac, pid file only, ad-hoc shell lines included" lands in the agents' standing text with this record landing; the steward makes it a gate check that refuses pattern kills in scripts and logs the sender of every TERM a gate receives. The class-v5 lane's own line: the four pkill lines (12:3x to 12:37) stopped its own superseded gate runs as its tip moved under them; nothing of its uses a name or pattern kill again, its background gate started with its pid recorded and ended by that pid only; its current run (gate 17 on class-v5 79799452, 12:39) runs to its end. The census and the four-item pin taken by main; the clock as the shipper set it. Lane D's interim at 12:5x BST for the 09:00 report, the lossy-share curve at 1,000 to 1,300 eras per point: r rises 0.80, 0.88, 0.92, 0.96 as or, mul and mulhi go +1 to +4 points each; exhaustion appears at +3 (2 of 1,029) and reaches 1.4 percent at +4 (14 of 994); every exhausted era's class v5 last-resort scan passes at its first or second candidate (k = 256 or 257), so the band's edge is between +2 and +3 points of lossy weight and the scan does its job at the corner. Its cut 2a595e1b under the gate, then the mirror landing and the send to the research lane. The attack pass's F8 to 256 seeds landed at 12:37 BST: seeds p66 to p257 (192 new) at 2^24 on the freeze 1c420786 (binary 0f5c98dc, pairing e5a4ac5978462156), the window-model control, build-2 under class measure, validation 0 mismatches (hash_warp agreement on 37,440 warps). 184 of 192 within 1.2x at the top 0.1 percent (mean 1.023); 8 over (p110 1.3527x, p66 1.3403x, p234 1.3156x, p145 1.2750x, p77 1.2664x, p225 1.2457x, p248 1.2188x, p89 1.2065x), each with its hottest item at 263 to 432 reads of 2^31 and the hot-set verdict clear on the windowed control (largest excess X_f/f +0.60). Over all 256: 245 within (95.7 percent), 11 over; the rate at 256 (4.3 percent) is the gate's at 64 (4.7 percent) and the worst fell (1.3527x against p10's 1.5047x). The 6-sigma largest-bucket line flags 57 of 192 (p110 +61.67 sigma): the AP-F8-1 tail mechanism at its rate. Two seeds carry a predicted source, one-one-bit through a load, both passed by (c''') on the frozen tip: p212 (1.1915x, attempt 4, site instr 7, r5, last writer load at 2) and p225 (1.2457x, attempt 0, site instr 37, r5, last writer load at 36), to the hash lane for by-site attribution as the gate's tail was. Verdict PASS at the gate's reading: no card or chip gains a cacheable hot set on any of 256 epochs. The row and f8-uniform.md section (e) on the mirror's attack-pass. Still running: build-4's F9 (six chunks) and F1 (10^6), partials at 17:00. The node lane's named commit inside the 12:50 clock: 42ce0f07 on release-0.3.25-node, both mirrors, 12:39:37 BST, the sha with the steward and the shipper. Content: e0644958 (keygen, the record re-announce, the ceiling switch at 82,800; digest 1b37cb9d) plus four node fixes, nothing consensus: the ring self-check every 30 s over the last 2,000 records with the full scan on a generation change (node1's class, its known-failed test green); the snapshot digest stamp (a snapshot under another object or none refused, the node re-executing from genesis); the vetoed-node status (the count and the last veto on the status RPC and igneum_getNodeInfo, "stateFresh" false while any stands); the proof map's window (a proof leaves memory with its record at the 600-block window's end, the OOM class). Green before the squash on the same tree: exec 54 of 54, the kaspad check. The full gate set at gate priority on both boxes from 12:39:44 (every line by about 12:52), both canaries reading the Devnet 3 digest back at 1b37cb9d, the fast-time pair by about 13:00; the crossing watch at 68,400 on the seed from 12:50; the pin line after the last of those; the TESTNET_PARAMS re-cut at 13:30 unless main says otherwise by 13:15. The invention lane at 12:5x BST: the hash lane's 5090 rows for the two sound per-load packs reverse the GPU-side sign of rank 1: at class v4's own instruction count the per-load form costs the card 19 W MORE than the whole block unlocked (483.6 against 464.6 W) and 6.6 W more at the 1,300 lock, rate 1.3 percent under, 15 to 20 percent more per shadow instruction (19.7 to 20.8 pJ against 17.2); the dead 16 x 27 export's 13 to 14 W saving does not carry (a 16-instruction loop against a 144- or 256-instruction straight segment). Rank 1 keeps its place by the file's own rule (the chip's project cost about 2x against the card's 2 to 4 percent of watts) with the honest sign: the card pays, not saves. The second cut landed at 4315e992, the third (these rows) under the gate. The drawn-era re-read on 0ab27582 built on build-3 but starved (build-3's 16-core pool under lane D's three 24-core leases since 12:38): the coordinator moved it to build-4 at once through the lease pool under class measure (build-1 closed until the pin is named); the 15:00 numbers from build-4, the box named in the row. The class v5 lane's full gate on class-v5 79799452 (the tip on both mirrors) GREEN, 73 checks in 463 s at 12:47 BST, left to run to its end: 0.3.25's pairing row on the page (the freeze 1c420786, kit 65b47211 with the Intel worker held, the Arc read to 0.3.26 with the second PC dark), master merged through its latest (the 60x file taken whole from master after the merge reordered seven keys and duplicated three, values equal), the generated ledger files matching. Nothing of the lane's pending; the one future item the Arc B580 re-read on kit 65b47211 when the second PC is back, which moves the Intel row and sends the 0.3.26 upgrade line. 42ce0f07 reads every gate green at 12:48:10 BST: build 12:42 rc=0 (igneumd 8e17a60b, /srv/artefacts/0325-42ce0f07/node-lane), pow 19, consensus 134, core 177, miner 29, p2p-flows 38, exec 54, all at gate priority; the Devnet 3 canary set with digest 1b37cb9d unchanged, byte 6, the override refused, the 0.3.24 pin refused on the digest both ways; the testnet canary b2e856ed unchanged. The shipper has the line; the steward's matrix runs on it. Two inputs before the pin: the fast-time SUMMARY on 42ce0f07's artefact (about 13:00) and the 68,400 crossing on build-1's seed (the chain passes it about 12:54, the watch from 12:50). The reorg-unwind fix's 13:30 clock met at 12:48 on the same commit. The attack pass at 12:5x BST, the ends brought in: F1's 10^6 was one 40-thread census on build-4 (35 h); the harness now takes --start (attack-v5-frozen ebdb7d4a, smoke-tested: a 20-program census from index 5 writes rows 5 to 24), so the census is split by index range: build-4 keeps indices 0 to 349,999 (its running census, stopped by pid when its progress line reads 350,000; the flushed census.csv holds the lower range) and build-2 runs 350,000 to 999,999 at 80 threads under class measure (binary 42ee04c7, held since 12:48:40 BST after waiting 362 s for the pool to free on its own, no pre-emption). Both halves end about 23:30 BST. F9's six chunks hold on build-4 (48 cores); when build-2's F1 ends tonight the F9 remainder re-splits onto build-2 by seed range (rows keyed by seed, nothing lost), bringing F9's end from about 17:00 BST tomorrow to about 06:00 BST. Cores held: build-2 80 (F1 upper range), build-4 88 (F9 48, F1 40); build-1 and build-3 untouched. Partials at 17:00. RED, a first, at 12:48 BST: Devnet 3 STALLED AT THE CLASS V5 FLOOR. The seed's virtual DAA read 68,403 at 12:49:11, 12:50:23 and 12:51:09 with one sink (07055360), the last block accepted at DAA 68,399 as class v4 at 12:48:14; nothing at 68,400 or above reached the seed, node1 or the observer, no node logged a PoW rejection: no miner found an epoch-19 block on a chain that ran one a second. The nodes held epoch 19's state (the seed installed the streams for epochs 18 and 19 from its snapshot at 12:30). The cause (the fleet lane, 12:52): every miner's --worker is the hive package's igneum-worker-cuda, which runs generators 2, 3 and 4 only; the class v5 kit's worker (82b19cbde8557ea5, the one every v5 gate ran on) was never on any miner's worker path, only its packs were placed; the prepare of epoch 19 fails and the miner sits at 0 MH/s while the templates flow. The fast-time harness crossed this boundary green four times on pairs, which tests the node and the CPU engine, not the fleet's GPU workers or kits. The fleet places the kit worker on every box now; the 0.3.25 hive package and Windows payload rebuild with the kit's workers by 13:30 (the build-server lane); the Mac Metal worker's generator-5 read with the v5 lane by 13:10. The pin and the minute wait on the chain moving and the rebuilt packages; the 42ce0f07 gate set green, the matrix running, the ceiling cut's publish limit (DAA 75,600) standing still while the chain does. GATE RULE for the next cut (the record's and release-rules'): a cut's packages are smoked by preparing the current epoch's pack on every worker binary they ship, on every platform, against the live object; the packs' presence and the kit's own tests never stand for it. The 0.3.24 move's read-back ("36 of 36 FETCHED on the pin") was a node reading; no reading of a worker preparing class v5 existed before the floor. The research lane at 12:5x BST: section 10 ("the floor") open in the class v6 document (counter-asic-4 after 91117093) with each floor lane's term, what the document holds measured for it, the default at 19:30 and the row owed; two measured rows the floor lanes start from rather than re-derive: the SM-sparse lane from 20.3b (a quarter of the SMs holds 98.2 percent of the class v4 rate at the same draw, 460 against 451 W; 99.8 percent of class v3 at 4 W less; watts minus idle per MH/s never below base; the sparse shapes collapsing at the 1,300 lock; its new work the breakdown of the 99 W an idle SM does not save and whether an occupancy shape at full SM count moves it; the worker variants sp-w and the card-free --list-race check on counter-asic-4); the k lane from 15.1a (the GPU side measured per counted op: ARX 11.3 / 6.2 pJ, mul 13.9 / 8.3, mulhi 39.6 / 21.0, prmt 22.3 / 11.5, lop3 24.1 / 13.0, shfl 55.8 / 29.4, fp32 FMA 9.2 / 5.2, the int8 tile 1.4 to 4.1 per MAC; only the chip side claimed; the mix that maximises k priced against the GPU's own per-family cost, the shuffle 4.9x the add on the card). The thirty-ninth landing on master at 12:54 BST (26a3cbe6): the standing rule in CLAUDE.md. The node lane at 12:5x BST on the stall: the worker's refusal line is "program pack generator 5 is not a generator version this worker runs (2, 3 or 4)", faulting at 0 MH/s from the first epoch-19 template; the kit's class v5 worker was benched on 24 cards this morning and never placed on any miner's --worker path; the nodes read 0 PoW rejections and hand the right template (the CPU id-read from build-1 confirms epoch 19 as class v5). The fleet places the kit worker and its pack on every mining box, w-target first; the chain moves when the first card prepares. The record's lesson: a worker that cannot run the next class must refuse at the pack prepare, loudly, hours before the boundary (the plug, tune, play rule), and no hive tar ships without the class the object names. A second bug read off the stall: the pool admits at the next block's DAA (chain id 4464 past the floor) while eth_chainId answered the executed tip's id (4463 with the tip stalled at 68,399); the fix (eth_chainId and net_version answer the id a transaction sent now must carry, the status carrying both ids, the known-failed test on the stall's shape) a wip under its exec suite at gate priority since 12:54:27, landing as the SECOND commit on release-0.3.25-node over 42ce0f07 (nothing consensus, digest 1b37cb9d unchanged), its full gate set and fast-time pair by about 13:15; that commit the pin's node sha, 42ce0f07 if it reads red. THE CROSSING READS CLEAN. The first class v5 block (epoch 19, epoch seed a75c5624) was accepted on build-1's seed at 12:57:40 BST, 9 minutes 26 seconds after the last class v4 block, the minute the fleet's first kit worker prepared; then 13, 14, 71, 165 and 78 blocks a minute (the backlog clearing, the rate settling), DAA 68,547 at 13:01:37; seven stale-pack attempts refused between 12:59:24 and 13:01:10 (the harness's known-failed shape), none since; no state-wait, catch-up, stale-dataset or digest line on the seed, node1 or the observer; no honest block refused. Devnet 3 runs class v5 at byte 6 as the 0.3.24 object names (the v5 signal share 1,407 bps at the floor; the seed's template at 13:1x: epoch 19, class 5, version 1538, era the genesis, day 20,734; the executor serving epoch 19's stream, 869 records, root 0x1fd55139...4561). The pairing check holds three ways: the kit's igneum-pow (8f481459's tree, the freeze's hash object) names attempt 2, program id 3d375a55029e7e60 for epoch 19; the node lane's 0.3.24 pin miner (igneum-pow 1c420786) read the same id live at 12:56; the DMG's Metal worker on the Mac prepared epoch 19 against the live seed with the same id (869 leaves, 26 MH/s). The stall's two causes, both miner-side, neither in the object: every fleet miner's worker was the hive package's CUDA worker (generators 2, 3 and 4; it refuses a generator-5 pack with a line, the miner at 0 MH/s retrying, loud in the log and the plug-tune-play fault only on the dashboard), the DMG's Metal worker from the freeze's tree the same (the v5 worker path is the v5-kits lane's 5c9ed959, in class-v5 from e208dfea on; the freeze is the hash object, not the hosts); and a miner not told its node's exec RPC port cannot prepare class v5 at all, so every fleet loop needs --exec-rpc. The fix: the kit's workers (zip 65b47211) and --exec-rpc on every box; the hive, Windows and Mac packages from the kit tree (the hive and Windows payload carrying d84b1b6c / be23bc68 and e1bfd582 / 55722527 on the worker path; the Mac side closed on release-0.3.25 44d1815a, proto-metal from class-v5 79799452). The stall's cost: 9.5 minutes of blocks and every prover's share for that span. The standing rules from it (release rules 16 and 17 on ship-docs-0321 cb570365): the kit worker and --exec-rpc on every miner loop before any class boundary; a worker that cannot run the object's next class refuses at the pack prepare, hours ahead; a cut's packages are smoked by preparing the current epoch's pack on every worker binary they ship, on every platform, against the live object; memory against the container's cap. All of it on the class v5 page's section 0 at class-v5 2494f3f8 (both mirrors 12:59, master merged, its full gate running by pid). The second node commit 5f316c21 on release-0.3.25-node (both mirrors 12:56:22 BST) = 42ce0f07 plus the chain-id answer (eth_chainId and net_version return the id the pool admits at, the next block's DAA, 4464 past the floor; the status carrying both ids; the known-failed test on the stall's shape), nothing consensus, digest 1b37cb9d unchanged; EVERY GATE GREEN at 13:04:05 BST (build 12:58 rc=0, igneumd 3812b2a2, /srv/artefacts/0325-5f316c21/node-lane; consensus 134, exec 54, core 177, pow 19, p2p-flows 38, miner 29, all at gate priority; the Devnet 3 canary with digest 1b37cb9d unchanged, byte 6, the 0.3.24 pin refused both ways; the testnet canary b2e856ed unchanged). 5f316c21 IS THE PIN'S NODE SHA. The one input before the pin line: the fast-time SUMMARY on 42ce0f07's artefact (the run waited 796 s for build-1's pool, 88 of 88 leased at or above v5, nothing to pre-empt; running since 12:55:54, v5 from epoch 8 at 13:04:19, the line about 13:10), a run on 5f316c21 after it. The shipper's close: the app tip 9a71e784 (crate 89e83df2), the DMG 43cd8c94 staged, the tarball 1ae1810d, move id m5f31-1; the pin about 13:25 after the SUMMARY, the matrix and the hive; the minute about 14:00 to 14:20 inside 14:53. The TESTNET_PARAMS v5-at-0 re-cut's default moved under the rule by the node lane: it lands through its full gate set on release-0.3.24-node 30 minutes after the seed reads the first ten class v5 blocks accepted clean, so at 13:32 BST unless main says otherwise before then; a red crossing would have meant no re-cut. The audit lane's 9070 XT row on master at f37f497b (12:55 BST, gate green on 33b0ad06), ahead of 13:30: 18.96 MH/s, watts "149.3 with the 0.3.25 knob (195.8 stock)", 0.127 MH per watt, the tuned text with the 24 points' flatness and the date, the source the status row with the job id; the note carries the grid's stock point beside the app's 202 W reading of 7 October, the two single-lever points, and names both 5090 denominators (3.5x behind at the class v4 1,200 MHz lock, 0.43; about a fifth at the 1,300 knee, 0.60); the qualifier drops when the cut serves. With f37f497b: the complete class v4 watts rerun (22 rows), the /income calculator, the /economics page, the governance line, the two served-text corrections with their ledger rows. The build-server lane has it to deploy. The hash lane's kit b on the 5090 (12:49 to 12:58 BST, all PASS; with the research lane and the floor lane): the mixer multiplier x8 against x16 costs the GPU nothing (137.73 against 137.72 MH/s, 320.2 against 320.1 W unlocked; 127.44 against 127.46, 212.0 against 211.7 W at 1,300), so the verifier's 1.86x per doubling is the whole cost of that draw; the shuffle-heavy table on the base program moves 7 W unlocked and nothing at the lock (a 2 percent term); the pinned class v3 program at 2, 4 and 8 GiB costs a tuned 5090 5, 11 and 14 percent of rate at the 1,300 lock (4, 8 and 10 percent per hash) and 3 to 4 percent unlocked, which corrects the layer 2 line: the size term is real at the knee (the page-walk cost the latency-bound regime exposes). Kit c (the multiply-heavy table) running; kit d (both tables inside the shadow block, the row layer 1 needs) exports on build-2 and runs after, about 13:45. W = 8 for the floor lane: the crate's width set is three fixed word widths (1, 4, 16; WIDTH_WORDS, the mix arrays, the emitters for CUDA, OpenCL and Metal, the verifier's fold), so a 32-byte load needs a generator and emitter change before any pack exists (two to three hours of crate work on the readwidth line plus the PC 1 row); the ask to main with its default: say so by 14:00 and the lane starts it on the readwidth branch (a research class, no consensus object); silence means W = 4 pins and the floor lane hears so at 17:30. The F8-256 attribution runs for p212 and p225 on build-3 (the attack-pass crate d08e1e0f built there at 13:01), rows by 16:00. Main's ids for the floor lanes, for the record: SM-sparse af65f8187569666d0, shadow k a3c9601a6d4686fe1, SRAM and dataset floor acecab7195ea66621, honest denominator a4d39e20a0762646d, invention a734c5330f17be3c2; the research lane delivered the two starting rows to each with their 19:30 defaults. Two more master-only deploys from the builder stream, checks ok (38 miners rows, 18 asserted pages, the checkpoint API and the explorer stats API): d28cf8fc at 12:50 BST (the explorer wording c4ca746f, the audit lane's ace5c294 with /economics, the /income calculator and the class v4 watts rows, the DEX lane's 9126e4d6 and 825d19bd) and f37f497b at 13:04 BST (the reference-apps b7f1e0d7 with /oracle's BLS-verified root, the 9070 XT knob row on /miners). No chip text changed beyond the audit lane's own landings. The fortieth landing on master at 13:14 BST (90b180f2). Main's word on W = 8 at 13:1x: start it, research class with no consensus object; the order on the hash lane: the 0.3.25 lock rows and kit b first, then the readwidth generator and emitter, the PC 1 row by 17:30; a miss means W = 4 pins, the floor lane told, the W = 8 row later as a v6 sub-version check. The 13:32 testnet re-cut on its default. A RED THE MOVE ITSELF WOULD TRIGGER, read on build-1 at 13:05 BST by the node lane: a node re-executing from genesis (the fleet's 21 re-walks now; every node at the move under the snapshot stamp rule) has its executor thousands of blocks below the chain, so its pool admits at the executor's next DAA, names the old chain id 4463 below the floor, refuses every relayed transaction signed with 4464 as a state-free fault and disconnects the relayer as misbehaving ("wrong chain id: expected 4463, got Some(4464)" on the seed and node1 from peers at 13:05); for the length of its walk, about 8 minutes, it drops every peer that relays a transaction, and at the move every node would do it to every other: a partition. The fix, a wip under its exec suite at gate priority since 13:08:06: the admission height is the larger of the executor's next DAA and the chain's virtual DAA plus one (eth_chainId, net_version, eth_sendRawTransaction and the relay read it), and a mismatch between the network's own two ids is a refusal, never a strike; the known-failed test is the re-walk's shape. It lands as the line's third commit over 5f316c21 (nothing consensus, digest 1b37cb9d), the full gate set and the fast-time pair on it by about 13:35; the pin waits on it. The second thing in those logs is the stale class, not a bug: the 21 nodes with a divergent execution state compute a divergent class v5 dataset, refuse every honest v5 block as invalid PoW and ban build-1's seed for an hour ("Reject(BlockInvalid)" on the fleet's side), cured by their re-walks in progress; a node that cannot check a v5 header for want of the epoch's state holds off, as designed. The crossing is clean on the honest side; the chain runs. The fast-time crossing on the 0.3.25 pair 42ce0f07 (12:55:54 to 13:08:50 BST) read green on every claim (rung 1 at 13:02:22, v5 at byte 6 from epoch 8 at 13:04:19, 12 of 12 ids equal to the CPU verifier's, the stale node refused, the restart step resynced in 19.1 s with the catch-up done, four sinks equal, 0 PoW rejections on honest nodes); its SUMMARY read FAIL on one harness check: the final epoch's row held one miner's line when the run ended at that epoch's boundary (the id equal to the CLI's); not a node finding; the check now reads the final row by its id (v5-fasttime 130562a2); the clean rerun on the same artefact from 13:1x, SUMMARY about 14 minutes after its lease. Lane D's 17:00 cut LANDED on master at 238100b0 (13:13 BST), gate GREEN (73 checks, 355 s) on 2a595e1b, four hours early; the research lane has the layer-4 line; docs/analysis/class-v6/family-gate.md carries the measured coverage (24,000 drawn eras, per stratum and per axis, the bound arithmetic), the rows, logs, scripts and the harness diff under docs/analysis/class-v6/logs/. Build-3: w4lossybase done (3,000, 0 exhausted), shape256 1,910 of 3,000, shape64lossy 1,895 of 2,000, w4shape64 queued, then the point-B live census on the family attack-f8 build (74784428); build-1 the four lossy-share strata near done and the point-A live census. The class v5 lane's full gate on class-v5 2494f3f8 (the crossing row, master merged) GREEN, 73 checks in 407 s at 13:06, run to its end by pid, nothing killed. The third node commit inside the shipper's 13:20 clock: d5b68fae on release-0.3.25-node, both mirrors, 13:14:12 BST = 5f316c21 plus the admission fix (a transaction admitted at the larger of the executor's next DAA and the chain's virtual DAA plus one on the relay, eth_chainId, net_version, eth_sendRawTransaction and the status; a mismatch between the network's own two chain ids a refusal, never a strike; the known-failed test on the re-walk's shape), nothing consensus, digest 1b37cb9d unchanged, pairing 1c420786; exec 54 of 54 and the kaspad check green on the same tree before the squash. The full gate set at gate priority from 13:14:19, every line by about 13:26; the fast-time pair asked on it; the 42ce0f07 rerun's SUMMARY (about 13:24) the gate's record on the same object. The pin's node sha d5b68fae if green, else 5f316c21. The steward's 0.3.25 matrix at 13:17 BST: node 5f316c21 with app tree 89e83df2 GREEN on all seven suites on build-2, build-3 and build-4 (no RED); 42ce0f07 complete green on the same three; build-1 out; at 13:21 the third sha d5b68fae core and exec GREEN on the three boxes, six of six: the pre-pin suite read closed. d5b68fae reads every gate green at 13:22:43 BST (build 13:15 rc=0, igneumd b0e7b8b5, /srv/artefacts/0325-d5b68fae/node-lane; p2p-flows 38, pow 19, consensus 134, exec 54, core 177, miner 29 at gate priority; the Devnet 3 canary digest 1b37cb9d unchanged, byte 6, the 0.3.24 pin refused both ways; the testnet canary b2e856ed unchanged): THE PIN'S NODE SHA IS d5b68fae. The fast-time SUMMARY PASS (cross-0325-42ce0f07-2) at 13:22:57 BST on the 0.3.25 pair 42ce0f07 (13:10:07 to 13:22:57 on build-1 under class v5: rung 1 at 13:16:33, v5 at byte 6 from epoch 8 at 13:18:43, the stale node refused, the restart step resynced in 11 s with the catch-up done, four sinks equal, 0 PoW rejections on honest nodes); the d5b68fae pair running side by side since 13:16:13 on its own cores and port base, SUMMARY about 13:30, the last input before the pin line. The reading behind the fleet's partition line at 13:17 BST (hub-1 at one sink, dn2-1 alone on its own branch, w-poison a third, dn3-g2 and dn3-q03 stuck at DAA 68,403 refusing every v5 block): epoch 19's class v5 dataset derives from the execution state after the epoch's reference block, the last chain block below the cut 19 x 3,600 - 600 = DAA 67,800: chain block 28,462, hash a75c5624 (the epoch seed), state root 0x1fd551393d (build-1's seed, node1-dn3 and the fresh node agree; the kit's stream names the same root). Any divergence of state OR numbering between 26,294 and 28,462 puts a node in a cluster that refuses the other clusters' proof of work and bans their relayers for an hour; root-equal at 26,247 was not the gate. The census now reads hash and root at 28,462 on every box (epoch 20's height moves to the last block at DAA at most 71,399); every cluster but the one on a75c5624 / 0x1fd55139 re-walks; build-1's observer node, the explorer's only source, is one of the drifted (its 28,462 another hash at DAA 67,787: the orphan-append class during its 11:22 re-walk, so the explorer's numbers are off by a few; the shipper has it). The cure is the move itself: every node restarted on the pin's binary re-executes from genesis under the snapshot stamp with the ring self-check running and lands on the one state; the gate on the minute is the fleet's census at 28,462 after the re-walks (31 boxes on the one state at 13:19:44, the rest the numbering class the move cures), with an unban of every held address per box once its root reads equal, since bans persist on disk across restarts; a box whose root there differs after a re-walk on the pin's binary is a new class and a stop. Lane D's measured correction at 13:2x BST for the full report: the lossy-corner exhaustion is a shape-256 interaction, not corner-wide: at the lossy cap the per-candidate rejection is 0.877 at shape 64 x 108 (0 of 2,000 and 0 of 1,000 eras exhaust), 0.923 at 128 x 54 (1 of 1,010), 0.980 at 256 x 27 (36 of 990, 3.6 percent; 24 of 670 at width 4); at r = 0.98 the independent-attempt figure is 0.98^256 = 0.6 percent, so the per-era correlation is about 6x, not the 1,000x the mixed-shape average suggested; the band rule stands either way (lossy families never raised), and the cheapest shape for the draw is also the fastest on the cards. The hash lane's attribution: run 2 (the attack-pass branch's own crate) reproduces p225's 1.2452x but not p212's (1.57x against the gate's 1.19x, a different draw, the crate differing from 1c420786); run 3 on the 1c420786 crate is the authoritative one, running. The W = 8 pow suite on build-2; the three state-term packs (w4, w32, w64 on +sh256x27+state, the node1 state file, --era-widths 4/8/16) export on its green; the read-width kit (those three, the v5-genesis pack, the two 5 October packs, which are string-seed class v2 packs the worker accepted on 5 October, no re-export) runs on PC 1 after kit d; the L2::64B hint variant is not in the worker exes, so it is lane 5's kernel line, nothing to build. STANDING RULE from the founder relayed by main at 13:2x BST, applied to every lane the coordinator runs and every default clock: work as fast as possible; anything doable in 30 minutes to 2 hours gets a clock inside that window, never a target hours out; fan work out (one pod per point, one box per variant) rather than queue it. The floor close is 15:45 BST. The coordinator's re-read of the 16:00, 16:30, 17:00 and 19:30 lines: the F8 attribution rows 14:00 (run 3 running, three minutes a census); lane C's drawn-era numbers 14:00 (an 80-s census on build-4) and its cut 15:00; the class v6 per-tier cost rows and layer 4's tests 14:30 (kit d about 13:45); the W = 8 PC 1 row 15:30 (the crate work fanned: the suite on build-2, the exports on build-2's slot, PC 1 the moment kit d closes); the floor lanes' rows 15:30 for the 15:45 close; the synthesis and the served-line review table 16:30; lane D's full report 16:30 with every stratum fanned across build-2's and build-4's free cores rather than queued on build-3; the DEX lane's swap UI 15:00 and the Sepolia verifier 16:00; the reference apps already served (b7f1e0d7 at 13:04). Main's word at 13:2x BST to every lane: while GitHub is suspended, landings go to the box mirror's master through the gate, never to Forgejo master, which is a rewritten copy replaced at cut-over by the box mirror's final tip; pushing a branch to Forgejo for safekeeping is fine, landing there is not. Relayed to every lane with the pulled clocks. The SRAM and dataset floor lane's row is complete at 13:18 BST, two hours inside its pulled 15:30 clock: the full row at 7bc9de4b and the clock references at 8e9588de on the box mirror's branch class-v6-floor-sram (safekeeping, no master landing), gate green on every push, all arithmetic on build-3; docs/analysis/class-v6/floor/sram-and-floor.md. What the 15:45 close carries: the capex wall on the corrected project floor (no chip project below about USD 23 M a year of miner revenue, IGN 0.03, USD 62 K a day; every DRAM-board project at a third of the network above about USD 340 M a year, IGN 0.44, USD 0.93 M a day, where the SRAM project also starts); the read width as the only wire lever on the SRAM die (66x at the hash's 4-byte width at zero shadow, 44x at W = 4, 31x at W = 8, 19x at W = 16 if the 5090 passes the PC 1 job, 36x at the measured w64 row); the shadowed die at 6x to 10x at the honest cards' whole latency shadow on the k lane's synthesised core, kept beside the k lane's sequencer-core row as the floor-k worst case, never under 2x by any shadow; the floor as a ticket lever (5.5 / 8.5 / 11.5 GiB = 3, 5, 6 reticles, USD 1,500 / 2,500 / 3,000; USD 5,000 per store is 20 GiB and retires every card under 32 GB; the 5090 pays 4 / 8 / 10 percent per hash at its knee and the M5 Max 12 / 20 / 22 percent of rate at 2 / 4 / 8 GiB, both measured); the four other candidates (per-era and per-block re-fill, straddling atoms, a second hot table) dead with numbers. Amendments after the close, each labelled with its time: the W = 8 or W = 16 PC 1 row (the hash lane), the k lane's shuffle row and its re-fold, the Apple rate curve past 8 GiB. The DEX lane closed with every clock met before the pull, all on the box mirror's master through the gate: the AMM live on Devnet 3 at 12:0x BST; the swap UI serving at igneum.network/swap since 11:36 with the Igneum Wallet bridge live from the 12:50 deploy; the Sepolia certificate verifier live at 13:3x (0xAf74f3F512081291D663Bb1d6b6d37E99e37D744, suite 10 of 10 on build-3, Devnet 3 checkpoint 2127 recorded final and one Devnet 3 balance proven on it); the one named gap: no on-chain link from checkpoint to state root yet (docs/bridge/light-client-bridge.md); final master 825d19bd. The forty-first landing on master at 13:35 BST (937cc82ae); during its branch push the hook "died of signal 15" once more (the merge's own gate ran green and landed), so a kill by name on the Mac still reached a gate at 13:3x: the steward's TERM-sender log is the read. STOP ON THE PIN d5b68fae at 13:29 BST, the fast-time pair: SUMMARY FAIL (cross-0325-d5b68fae), the failing check v5_ids_equal_the_cli_v5_id, a node finding: on epoch 9's attempt-3 seed ec0a8cf9 the d5b68fae miner and nodes drew program id 65b57e3b847d362e (its nodes accepting 4 of 4 on it) while the freeze CLI 1c420786 and the ab6f980b CLI both draw ebf64b32e2d84c5b, state or no state; the three other v5 epochs agree with the CLI. A node on the freeze's igneum-pow would refuse that epoch's blocks: a split on the first divergent seed, a chain split class. The 42ce0f07 and 39f127a1 PASSes met no such seed, so they do not clear it. The cause from the box's build log: the d5b68fae, 42ce0f07 and 5b673577 pairs were built "pairs_with": "igneum 05b21835 (detached) with uncommitted igneum-pow changes", not against the freeze 1c420786 (39f127a1 and c8f9b383 were, against ca3-v4-node commits 4c24903e and 0e4ec18a); every 0.3.25 node binary embeds "igneum-pow-v5/src", not the freeze's crate; rule 7's pairing broken in the node lane's build path. The orders: the node lane folds the freeze pairing (a clean rebuild from the freeze's exact igneum-pow, the build row's pairs_with read before any lease) and the ceiling re-cut to 90,000 into one commit (sha by 14:05, the gates and a new digest by 14:20, the SUMMARY with the seed in the set by 14:35); the build-server and fleet lanes read the live 0.3.24 miners' pairing path by 14:00 (if the live network carries the same divergence, the move is its cure before the first attempt-3 seed; 5b673577 is the live pin); the artefacts rebuild on the new sha; the pin about 14:35, the minute about 14:55 to 15:10 BST. The coordinator's order to the v5 lane: the pairing read-back on the rebuilt pair by 14:30 (the freeze CLI against the new sha's miner on ec0a8cf9 and the three other v5 epochs, id for id, and the live miner's path the same way). The record's rule for the pairing gate: the fast-time set carries an attempt-3 seed on every run (the epoch seeds of a run are its block hashes, so the divergent seed cannot be forced; the pairing row is the check that reads first); a pair's build row names its igneum-pow commit, and "uncommitted changes" in pairs_with is a refusal before any lease. Lane D's fan-out at 13:4x BST, one stratum per lease, class measure (every box's pool read 0 free at submission, each waiting in the measure class ahead of adv work): build-2 w1band (width 1 under the band, 3,000 eras, the fg7 harness with the refused-ratio column) at 16 cores, and the mixer verifier rows mx4m4g, mx4m8g, mx4m16g with the 256 x 27 shadow, one core each (the x16 row); build-4 w4shape64 (3,000) at 16 cores; build-3 the point-B live census (64 seeds at 2^24, shape 64 x 108 with a band era's weights) at 24 of 64 seeds PASS, and w4band (width 4 under the band, fg7) at 8 cores, 179 of 3,000; shape256 (3,000) and shape64lossy (2,000) COMPLETE; build-1 untouched (the point-A live census at 31 of 64 PASS, no test fired; the four lossy-share strata complete at 3,000 each); build-3's queued copies killed and their partial rows marked PARTIAL. The full report by 16:30 on the mirror's master through the gate; what has not finished by 16:00 goes in as a partial with its count. The corrected line for main: at the lossy cap r = 0.877 at shape 64 x 108 (0 of 3,000 across the strata), 0.923 at 128 x 54 (1 of 2,000), 0.980 at 256 x 27 (3.3 to 3.6 percent of eras in three strata). The hash lane's clocks at 13:4x BST: p225 reproduces on the 1c420786 crate (1.2452x against the gate's 1.2457x, by-site rows in hand, the close by 14:00); p212 does not: the tool at d08e1e0f over the 1c420786 crate draws a program at 1.5715x with a hot set ("site instr 5, r7, one-one-bit, last writer add at 4"), not the gate's 1.1915x attempt-4 program, because the gate ran a chain path (class v5 with the dn3 state) the pushed tool has no flag for; the attack-pass lane's exact command asked by 13:50, default: p212 reported as unreproduced on the pushed tool, labelled so. Kit d: the first two exports hung on a build-2 slot (a stale lock of the lane's own run, cleared); take 3 direct and bounded, packs about 13:45; PC 1 held by floor lane 1's two jobs, so kit d's job starts the minute the card frees and closes 8 minutes later (rows by 14:00 only if PC 1 frees by 13:50, else PC 1's free minute plus 10, inside 15:30; past 15:30 the microbench arithmetic stands). The per-tier cost rows and layer 4's tests delivered at 12:0x (scratch v4/ca4-v6-cost-rows.md), the kit b and c numbers folded in at 14:15. W = 8: the suite on build-2 (restarted 13:23 after a slot wait); the three state-term exports follow it on the same box; the PC 1 read-width job after kit d; the 15:30 row holds if the suite is green by 14:00 and PC 1 frees by 14:30, else W = 4 pins. The explorer lane's correction at 13:4x BST: the explorer's source is no longer the drifted observer: the build-server lane re-pointed the indexer unit, the observer and the public RPC at node1-dn3 (EVM 26870) at 13:25, and the three indexer tables were wiped and refilled from node1-dn3 from chain block 0 at 13:27 (about 3 min); balances, receipts and accounts are node1-dn3's, the DAG tables the observer process's reading of node1-dn3 since 13:25. The notice landing by 14:00: the header names node1-dn3 as the source since 13:25 BST, the observer drifted at DAA 67,787 and re-executes from genesis, a block list read before 13:27 may differ by a few blocks until the move; the same line on /block and /tx. eth_chainId on node1-dn3 answers 4464 since the floor, so the explorer's chain id is read from the node; every page printing 4463 as a fixed string (/build, /swap, /metamask, the nav's title) is one off, told to the build-server lane at 13:28. The attack pass's split under the fan-out rule, running from 13:30 BST, every lease class measure: F9 (900,000 seeds left on 1c420786) as twelve chunks: build-4 keeps the lower 85,000 of each of its six 150,000-seed ranges, restarted from each chunk's lowest missing seed (rows keyed by seed, a merge dedupes), six leases of 8 cores; build-2 takes the upper 65,000 of each range, six leases of 6 cores. F1 (10^6 class v5 programs): build-4 keeps indices 0 to 349,999 at 40 threads (at 76,000 at 13:19; stopped by pid at the 350,000 line), build-2 393,662 to 999,999 at 52 threads (its first 47,000 rows from 350,000 kept, merged by idx at the end). Cores held at 13:36: build-4 72 (F1 40, four F9 chunks of 8; two chunks waiting on lane D's 16-core w4shape64 lease there), build-2 24 (four F9 chunks of 6; F1's 52 and two chunks waiting): build-2 contested (lane D's w1band 16, the invention lane's per-load acceptance census on 0ab27582 48, the hash lane's attribution at class adv, the hash lane's igneum-pow suite at class release for 88 cores, which pre-empts every measure lease there when it starts; the class order decides). Ends at the measured rates if every lease holds: F9 build-4 halves about 04:45 BST, build-2 halves about 07:00; F1 build-4 range about 23:20, build-2 range about 05:40; the build-2 ends slip by their waits. The 15:30 reading carries the counts and re-stated ends. THE EXPOSURE READ at 13:50 BST (the node lane's fingerprints, the shipper's correction): THE LIVE NETWORK IS ON THE FREEZE. The igneum-pow tree each binary linked is the untracked igneum-pow-v5 copy beside its release worktree (the .cargo/config.toml paths override); every copy fingerprinted against git archive 1c420786 igneum-pow by two methods (the node lane's: find src -name '*.rs' | sort | xargs sha256sum | sha256sum; the build-server lane's: find . -name '*.rs' | sort | xargs cat | sha256sum | cut -c1-12): the freeze reads cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 and 29106189ca1e; the 0.3.24 line's worktree (vendor/igneum-node-0321, where 5b673577 and every 0.3.24 pin was built, the gate pair a3b1a2c9/cfa9f5ca, build-1's seed, node1 and the observer) reads the same on the Mac and both boxes; the fleet's shipped pairs the same (29106189ca1e); the kit workers on the freeze (the freeze CLI built at exactly 1c420786 on build-1, binary sha256 7ba781db, names Devnet 3's epoch 19 as attempt 2, program id 3d375a55029e7e60, equal to the 0.3.24 miner's live read). So no live node or worker diverges, no attempt-3 seed can part them, epochs 20, 21 and 22 are safe, no hub-side holding action; the shipper's 13:45 line to main withdrawn and corrected. What diverged: the 0.3.25 line's worktree (vendor/igneum-node-v5) carried a pre-freeze copy (fingerprint e01ea128fab1: accept.rs without the (c''') per-site distinct-index floor, MIN_DISTINCT_RATIO_V5 0.995 and its HotItemSite refusal; generator.rs and memhard.rs older); every 0.3.25 gate artefact c6629572 through d5b68fae was built on it, none shipped; on an attempt-3 seed it draws attempt 2's id where the freeze goes to attempt 3, the fast-time FAIL; replaced by the freeze's tree on the Mac and both boxes at 13:34 (fingerprints equal). The builds.jsonl pairs_with rows name the parent repo's HEAD, not the override copy, so they never said which tree was linked; the fingerprint is the only reading. The predictability: an epoch's attempt and program id are a deterministic function of its epoch seed, fixed 600 DAA (ten minutes) before the epoch starts, so any two trees compare ahead on every seed by both CLIs; across the freeze and the pre-freeze tree the hash lane's census puts the share of seeds that differ at 2.4 percent (112 of 4,600), a per-epoch roll that only matters where a pre-freeze binary is live, and none is. The boundaries at 1.0 DAA/s from the 13:01:37 read: epoch 20 at DAA 72,000 about 13:59 BST (seed fixed 13:49), epoch 21 at 75,600 about 14:59, epoch 22 at 79,200 about 15:59. RULE 19 and the rebuilt sha inside the shipper's 14:05 clock: 6ccaf9e9 on release-0.3.25-node, both mirrors, 13:41:28 BST = d5b68fae plus rule 19's build-time half (consensus/pow/build.rs fingerprints the linked igneum-pow tree by the shell's method and refuses the build unless it equals packaging/pow-freeze.txt, "cbc5bd0a… 1c420786 class-v5-freeze 2026-10-07", unless IGNEUM_POW_FREEZE_CHECK=0; IGNEUM_POW_FINGERPRINT in every binary's strings, on igneumd's start lines and igneum-miner's engine line; the handshake field on the next commit with its own gate) and the Devnet 3 ceiling re-cut to 90,000 (the publish limit DAA 82,800, about 16:53 BST; the digest moves, named by the canary). The wip's check, pow and core suites read "igneum-pow fingerprint cbc5bd0aa10585c8 (the freeze)" at 13:40. The full gate set at gate priority from 13:41:35 (the build on build-1 with the fingerprint strings read back from both binaries, six suites on build-2, both canary sets), every line by about 13:55; rule 19's known-failed case on build-2 beside it (the pre-freeze copy under the override must fail the build); the fast-time lane's watcher fires on the artefact (about 13:45), reads the fingerprint string before its lease, its SUMMARY with the attempt-3 seed about 14:05; the v5 lane's flip case (the harness taking POW_BIN, the freeze CLI, beside FORK_BIN) reads every v5 epoch's id on the pair against the freeze CLI, 13 minutes a case, within 15 minutes of the sha. The testnet v5-at-0 re-cut landed by its default at 13:32 as 3ffcf83b on release-0.3.24-node (its pairing the freeze), its gate set from 13:40:39, its digest from its canary. The pin line follows 6ccaf9e9's last gate and the SUMMARY. The v5 page's section 0 carries the STOP and the pairing rule's new line at 3b894a4d. The counter-asic-4 documents landed on the box mirror's master at 13:35 BST as 868fea52 (full gate GREEN 73, the stamp on c21f1f38): docs/analysis/counter-asic-4-research.md, docs/design/class-v6-rotating-family.md (the branch's text at 08641162), docs/analysis/chip-model-v3.md (5.12 and the capex correction), tools/ci/export-exclude.txt (+4); igneum-pow/src, igneum-pow/tests and proto-cuda stay on counter-asic-4; no served page changed. The research-landing lane's next: floor-sram (8e9588de) about 13:55 from the Mac on its green stamp (the full gate RED 5 of 73 on build-3, all box-environment classes, the steward told as owner: the gate is the Mac-side script that reaches the boxes from inside), floor-k with tools/chip-model/rtl about 15:45, floor-sm documents by 15:30, the denominator and invention lanes on their words. The 6a5fa763 deploy at 13:42 BST (the explorer's source notice and chain id from the node, b092fa17; /swap reading eth_chainId at load, 46eb9e4b; /metamask on 0x1170 and the public RPC, the nav pill, /faucet and /build on 4464 with the floor dated): Devnet 3's eth_chainId moved from 4463 to 4464 at the floor; checks ok, 19 asserted pages. Lane C's 14:00 numbers: the no-era half in hand on 0ab27582 (the sound form 0.927, 234 of 256, unchanged on the fixed instrument; the control sh256x27 now reads sub-version 3's own 0.682 because the merge brought master's (a') pass to that spelling, so the two sit on one instrument); the era sweep on build-2 on the first free cores; the 15:00 cut after it. The attack pass at 13:46 BST: build-4's F1 lower range stopped by its pid file (83,000 distinct rows kept from indices 0 to 349,999) and restarted at 8 threads from its lowest missing index 78,082 (the 4,900 interleaved rows above it redone and deduped by idx at the merge), freeing 32 cores for the census lane; at 15:30 the shard restarts at 40 threads the same way; its end moves from about 23:20 to about 00:15 BST. A print-only move of the sha at 13:45 BST: c9ad753a on release-0.3.25-node, both mirrors = 6ccaf9e9 plus igneum-miner embedding the full IGNEUM_POW_FINGERPRINT=<64 hex> string on its engine line (igneumd carried it; the miner's binary had only the sixteen-character start-line form, so the pair's read-back on both binaries failed on the miner); no code path, object or digest change. The Devnet 3 digest on the pin: 2066aa57505e5ecbd585d061364abb0032d5b5b29cc41c54f4b38cb81c2ba6eb (the ceiling at 90,000; the publish limit DAA 82,800, about 16:53 BST); the fingerprint cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 (the freeze); the 0.3.24 pin refused both ways on its canary. Its full gate set at gate priority from 13:45:59 (every line by about 14:00, both binaries' strings read back in the build log); 6ccaf9e9's own gate set and rule 19's known-failed self-test by about 13:55; the fast-time SUMMARY on 6ccaf9e9 (the same node code and object) about 13:59 stands as the gate's record; the v5 lane's flip case on the pair follows; the pin line after the last of those. The forty-second landing on master at 13:54 BST (c340a9d4a). The shipper's pin candidate: c9ad753a on release-0.3.25-node (d5b68fae plus rule 19's build fingerprint against the freeze, the ceiling re-cut to 90,000, the miner's full fingerprint line; digest 2066aa57; the publish limit DAA 82,800 about 16:53 BST; the fingerprint cbc5bd0aa10585c8 in both binaries' strings); the app tip b5be4edf (crate 89e83df2); the gate set on c9ad753a by about 14:00; the fast-time SUMMARY on 6ccaf9e9 (the same node code and object) about 13:59; the matrix cells on 6ccaf9e9 stand; the v5 lane's read-back on the 6ccaf9e9 pair stands for c9ad753a; the fleet's binary the build-server lane's seed pair on c9ad753a (the freeze's crate, 29106189ca1e); move id m9ad7-1; the pin about 14:35, the minute about 14:55 to 15:10. PC 1's queue at 13:5x BST: floor lane 1's two jobs (floor-pc1-build-2 "build patched sp1-gpu-server", floor-pc1-restore) hold the card since 13:06; queued behind them, published and signed: kit d's fetch and run (9 minutes) then the read-width run (W = 4, 8 and 16 under the class v5 state term, each its own draw on generator 5 with the era and the node1 state, plus the v5-genesis reference and the 5 October w4 and w64; the W = 8 pack exported at 13:48 on the w8-v5 branch, efb68fce on the mirror, suite green; about 20 minutes). The coordinator's order: floor lane 1 names its end minute by 14:10; an end past 14:30 means its job yields the card at 14:30 (pid file, state restored first), kit d and the read-width run take 30 minutes, its job resumes after; so kit d's rows and the W = 8 row by 15:00 at the latest, inside the 15:30 close. The F8-256 attribution rows at 14:00 BST. p225 (the gate's 1.2457x): reproduced on build-3 with the attack-f8 tool at d08e1e0f over the pow crate at 1c420786 exactly, 1.2452x over the window model at 2^24 nonces, the hot-set verdict clear on both controls, the hottest item 0xb7e000 at 332 reads with no saturated or lossy source. By site: the excess sits at site 4 (instr 23, source r7, window 2^23 items, offset 1, last base writer mad at 21), 1.30 percent of its reads into the top 0.1 percent of items against 0.103 flat (12.6x), with site 9 (instr 37, r5, window 2^22, offset 2, last writer load at 36; the gate's predicted one-one-bit source) second at 0.38 percent (3.7x); every other site at its flat share. Both sites read full index entropy (15 of 15 and 14 of 14 bits) and a largest 256-item bucket at its window expectation, so unlike the morning's tail (a bucket concentration) p225's residue is a value-level concentration on specific items from a mad-written index, the class the gate's one-one-bit prediction names, carried mainly by the mad site and a quarter by the load site it predicted. p212 (the gate's 1.1915x, attempt 4): not reproduced; the pushed tool has no class, state or day flag, so its default path draws a different program for seed 212 (1.5715x with a hot set, the string-seed class v4 draw); the run on the gate's own line (its binary, day 20733, class v5, the dn3 state) on build-2 never started (0 of 12 cores free 13:29 to 13:54 with a higher class ahead; build-1 closed); the attack-pass lane runs p212 with --diag 1 on its own harness when its lease frees; default, p212 stays "predicted source only" in the record. No consensus object moves. THE PIN IS NAMED AT 14:08 BST: release-0.3.25-node = c9ad753a (the 0.3.24 pin 5b673577 plus igneum-miner keygen, the proof-record re-announce, the proving-fee ceiling switch at DAA 90,000 in the Devnet 3 object, the ring self-check every 30 s, the snapshot digest stamp, the vetoed-node status, the proof map's window, eth_chainId and the admission at the chain's height with the network's other id a refusal, rule 19's fingerprint, the testnet re-cut beside it); pairing the class v5 freeze 1c420786, fingerprint cbc5bd0aa10585c8576e71e37a8ee47a045ae51754e9ddf749d0c21e6a535f88 read back in both binaries; Devnet 3 digest 2066aa57505e5ecbd585d061364abb0032d5b5b29cc41c54f4b38cb81c2ba6eb; the app tip b5be4edf. Every gate green at 14:01:14 BST (build 13:47 rc=0, igneumd 68526b25, igneum-miner d4f4c98d, /srv/artefacts/0325-c9ad753a/node-lane; miner 29, core 177, exec 54, pow 19, consensus 134, p2p-flows 38 at gate priority; the Devnet 3 canary with the digest, byte 6, override refused, the 0.3.24 pin refused both ways; the testnet canary b2e856ed). On the same node code and object (6ccaf9e9): every gate green at 14:00:56; the fast-time SUMMARY PASS (cross-0325-6ccaf9e9) at 13:57:35 with the pairing read before the lease as the freeze fingerprint on both binaries (13:44:45 to 13:57:35 on build-1: rung 1 at 13:51:10, class v5 by signal at byte 6 from epoch 8 at 13:53:28, 12 of 12 ids equal to the freeze CLI's, the stale node 73 of 73 refused, the restart step resynced in 10 s with the catch-up done after 5 s and nothing of its own mined during it, four sinks equal at 662, 0 PoW rejections and 0 submit timeouts); the v5 lane's read-back PASS id for id on epochs 8 to 10 (13a54a0dd793ca79 attempt 2, d35cd0e9cb186d00 attempt 1, 6104176723170d72 attempt 2, miners 3 of 3 against the freeze CLI at exactly 1c420786); the matrix green on build-3 (build-4's consensus cell unreadable under load 510, the steward's clean run once the load is under 96, its line by 14:25). The FAIL seed re-read: on ec0a8cf9 with the FAIL run's era, day and epoch-9 stream, igneum-pow at exactly 1c420786 draws attempt 3, program id 1f1cf82877f46ee6 (8f481459 the same), so NEITHER id in the FAIL was the freeze's ("cli v5 ebf64b32" came from the release worktree's pre-freeze copy, the pin miner's 65b57e3b from igneum-pow-v5/src); the fingerprint pairing is the gate that catches both; the miner's side of that seed cannot be re-read offline (igneum-miner reads ids from a node's template only), so the pin rests on the fingerprint equality and the record says the attempt-3 seed's miner id was not re-read. The ceiling lands at 90,000 (epoch 25) about 18:53 BST, the publish limit 82,800 about 16:53. The re-execution reading: 27,000 chain blocks in about 8 minutes, RSS peak 12.6 GB on IBD plus walk. The fleet fetches m9ad7-1; THE MINUTE = the last FETCHED plus ten, about 14:30 to 14:40 BST; the Mac and HiveOS entries at it; Windows on PC 2's return; the card after the Windows entry. The minute's gate on the fleet's side: the census at 28,462 (a75c5624 / 0x1fd55139) after the re-walks, the unban per box once equal, the first checkpoint lock after it. The attempt-3 rule's shape: the miner's half of a seeded read did not exist; today it is the v5 lane's kaspa-pow program-id binary on its fork branch (class-v5-node 22920380, the template prepare's own path); igneum-miner program-id with the same flags and output line is the first item on the next node line, after which the harness points at the miner. The testnet v5-at-0 re-cut, landed by the default and amended once for its pinned digest constant: 0d05e795 on release-0.3.24-node, every gate green at 14:03:47 (pow 19, exec 47, miner 28, consensus 134, p2p-flows 38, core 175; the testnet canary with digest 1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f, byte 6 from genesis, the old-object seeds refused; the Devnet 3 canary on that line cc902690 unchanged); the rows with the testnet lane, with the note that the go seeds should run the 0.3.25 pin's node code with that object (one merge commit onto c9ad753a and its gates after the move's read-backs). Rule 19's known-failed self-test waits on build-2's pool cores (it pre-empted the attack pass's F1 upper range at 14:03 by the class order, 48 cores, 2,023 s in, 4,000 fresh rows kept; re-queued from index 397,292 holding 52 cores; cost about 25 core-hours, the build-2 F1 end about 06:30 BST). The attack pass's p212 run alone on the gate's exact line with --diag 1 --by-site (build-4, 8 threads, 13:56 to 14:01; binary 0f5c98dc, day 20733, class v5, the dn3 state): ratio reproduced 1.1917x (the gate's 1.1915x); hot-set verdict clear; 6-sigma buckets64 flagged at +91 sigma. The excess is one site: site 9 (instr 35, src r6, k_off 2 offset 0, window 2^22) carries 1.789 percent of its reads into the top 0.1 percent, 16.4x its flat share, index entropy 13.981 of 14 bits, the largest 256-item bucket 1.75x the window expectation, saturated source 0; the eight hot positions are site 9 in iterations 0 to 7; every other site at full entropy and its bucket at expectation; the predicted-source site (site 1, instr 7, r5, one-one-bit through a load at 2) reads 0.237 percent, the ordinary 2x of a 2^23 window, so the prediction is not the excess; the hottest items (0x000010 at 296 reads, 0x00000d, 0x00000e, 0x3c001f, 0x18001a) low addresses near the window base. Verdict: p212 is the AP-F8-1 tail class (a per-site bucket concentration at one narrow-window site, 0.019 bits short), not a lossy source (the log at /srv/builds/igneum-wt-attack-v5/p212-diag/p212.log on build-4). The hash lane's reading of both: p212 the bucket class, p225 the value-level class the one-one-bit prediction names; in both the predicted-source line points at the wrong site, so the prediction stays a hint and the by-site histogram is the attribution. The consequence for class v6's layer 4 (to the research lane): the per-site bucket bound at about 2x that would refuse the morning's four refuses neither of these (1.75x and none); the value-level test catches p225; a bucket bound near 1.5x would take p212 at a clean-seed cost nearer 3 to 6 percent. The AP-F8-1 ledger paragraph amended with it on the hash lane's next gate run (ordered). The research-landing lane's landings: floor-sram documents on master as de3d32af (13:55 BST; the lane's text at 8e9588de; full gate GREEN 73, the light gate on the merge; the gate pid rule kept) and floor-invention documents as d28a7656 (14:03; the lane's text at 033ff8d8; full gate GREEN 73): docs/analysis/class-v6/floor/sram-and-floor.md and invention.md; waiting on floor-sm (15:30), floor-k (15:45, with tools/chip-model/rtl), floor-denominator (no word yet), then the counter-asic-4 close follow-up after 15:45. Two more deploys from the builder stream, checks ok (21 asserted pages): 9a029677 at 13:50 BST (/metamask reads eth_chainId at load, 0x1170 pinned as the fallback, read back equal to the public RPC's answer) and 7902e235 at 13:55 (/build's networks table and /faucet name 4464 since the class v5 floor; the faucet signs with the node's chain id); the build-server lane's lease-pool memory rule in its gate (a lease declares its GB, the box ceiling 100 GB with the hands' residents counted; the shipper's order after the 12:06 OOM kill of the seed). Lane C's drawn-era re-read on 0ab27582 at 14:0x BST, run on build-2 (build-4's pool never freed, the waiter withdrawn, named in the row): the sound per-load form (16 x 256 x 1) accepts 254 of 256 seeds under drawn eras at 0.819 rejection per candidate, mean accepted attempt 4.3 (no-era on the same binary 234 of 256 at 0.927); the form at class v4's count (16 x 144 x 3) 254 of 256 at 0.811; every sub-block of 36 instructions or longer 0.80 to 0.84 under eras; the iterated 16 x 27 form 66 of 256 at 0.991 under eras and 128 of 256 at 0.979 no-era, dead on both instruments; the class v4 shape through the same binary reads sub-version 3's own 0.666 and 0.682. So the per-load prototype's verdict of 00:0x was an instrument artefact as the record reopened it, and the sound form stands at 0.82 to 0.93 per candidate with the dataflow rule in execution order as the named fix. The cut with these rows and the 5090 rows lands by 15:00. Floor lane 1 (SM-sparse) at 14:00 BST: its PC 1 jobs are run-ca4-pc1-floorsm-5090-20261008 (the ladder at the 1,300 lock, since 13:07, a 66-minute cap, the card free by 14:13) and the memory-clock ladder at the lock (about 20 minutes); floor-pc1-build-2 and floor-pc1-restore are the prover-floor lane's; every rented pod of lane 1's destroyed (spend USD 27); the stock rows, the decomposition and the self-tune in docs/analysis/class-v6/floor/sm-sparse.md at ccafd9a4 on the mirror; the lock and memory-clock ladders the two rows owed for 15:30. The coordinator's PC 1 order at 14:12: floorsm to 14:13, kit d to about 14:22, the read-width run to about 14:42, memclk to about 15:05 (republished behind them), the 7600 card-in at 15:05 (the hash lane: any Thunderbolt housing on any PC 1 port, the job keys on the new card against the 10:04 baseline; the pass about 50 minutes, rows by 16:00: detect and VRAM, 8 GB: the 1 GiB prototype dataset and the genesis 2 GiB floor fit, 4 GiB fits at about 5.4 GiB needed, 8 GiB does not; the class v5 and v4 fingerprints and the stock bench on the OpenCL kit worker; the app's own rate and watts; the AMD knob grid as on the 9070 XT; the Efficiency, Balanced and Maximum rows; the dataset rows at 2 and 4 GiB from the class v3 packs ds29b, ds30b; the 5.5 GiB row by interpolation, labelled, since the exporter takes power-of-two datasets only; a 5.5 GiB pack is a crate change for tomorrow unless main wants it today, default not today). The founder's order through main at 14:4x BST: Devnet 3 comes back first, the users' cut second. The sink-age guard has no switch (service.rs:1131 hardcoded), so the node lane cuts the hotfix now; the fleet, hub-1 and build-1's four nodes move onto it by a +0 file on the fast-time PASS alone (about 15:00), the full gate set and both canaries running behind for the node-only 0.3.26, a re-move if the set finds a red (nothing risked, the chain being dead). release-0.3.26 open at 822f8767 (the version bump only, the app crate unchanged); its DMG, hive and Windows entries re-cut on the hotfix sha and published at a minute after the network is back. PC 2 back and mining as of 14:4x: its queued jobs run on logon (the 0.3.25 install take first, the sign.ps1 self-test, the UI lane's two, the hash lane's Arc read); the 0.3.25 Windows entry on a clean take, the 0.3.26 one on its own. The DEX lane's /swap fix in its gate at 14:4x (the pools table 640 px wide at 768 px with no overflow, the sentence in a wrapping line under the table). The record's forty-fourth landing's merge gate killed by signal 15 at 14:4x BST on the Mac, a second kill since the rule landed; the steward's TERM-sender log is the read; the merge re-run. THE HOTFIX landed at 14:42:44 BST as f8da7515 on release-0.3.25-node (cold_start_replays: Err only for a node that synced nothing or whose retention root is above genesis; a node holding the chain from genesis replays with a stale sink, one line said; the known-failed test cold_restart_tests::a_node_holding_the_chain_from_genesis_replays_whatever_the_sinks_age; nothing consensus, digest 2066aa57 unchanged); the guard was 10 * 60 * 1000 hard-coded at exec/src/service.rs:1131 with no env, flag or config field; the shipper's prepared 4831c372 dropped. release-0.3.26 = 602bce8c (the bump plus the pin f8da7515; the app crate unchanged). The clock: the seed pair and tarball about 14:52, the fleet fetching from then, the fast-time PASS about 15:27, the fleet, hub-1 and build-1's four on it at about 15:35, the gate set and canaries behind for 0.3.26, a re-move on a red; the users' 0.3.26 entries after the network is back; the testnet go cut re-cut on f8da7515 after. The first block's time to main from the shipper. The 1.5x test's measured row ahead of 15:30 (the fleet hand on RunPod secure cloud, 14:28 to 14:39 BST, pods destroyed, USD 0.62 of the 60 incl. a re-rent loop fault that rented five extra 4090s for 14 pod-minutes, all destroyed by 14:36): the class v5 base (v5-genesis) against knob 3 (hl-k3-sh1024: the 1,024-instruction shadow block at 27 passes, 4x the shadow ops, a class v5 research pack on generator 5), the kit worker d84b1b6c, --batches 250 --batch-log2 24 --block-warps 1, watts the mean of nvidia-smi power.draw over the busy window. RTX 5090 (driver 595.91.07, sm_120): base 140.83 MH/s at 442.7 W (3.14 µJ per hash, fingerprint ae74193ddad19e19 equal to PC 1's), knob 3 111.07 MH/s at 551.1 W (4.96 µJ; at the full 60 s it sits on the 575 W limit at 110.0 MH/s, 5.23 µJ), fingerprint d0d9eccde24b30af. RTX 4090 (driver 570.195.03, sm_89): base 62.41 at 279.3 W (4.48 µJ), knob 3 62.64 at 439.2 W (7.01 µJ), the same fingerprints. Reading: knob 3 costs the card 1.58x the energy per hash (5090) and 1.57x (4090), the same on both architectures; on the 5090 it is power-bound and reads as 21 percent fewer MH/s, on the 4090 the rate holds and the watts climb 61 percent; per shadow instruction the long block costs 0.40x the 256-block's (the per-pass overhead amortised); the 4090/5090 rate ratio 0.44 on the base, 0.56 on knob 3. For the founder's 1.5x: the GPU pays 1.58x for this knob while the k lane's chip-side figure for the same knob is its row; knobs 1, 2 and 4 not benched today (2 has no GPU knob, the k lane agrees; 1 and 4 are new ISA, priced by the microbench until a generator line exists). Logs under the scratchpad's 1p5x/fb-1p5x-5090 and -4090. The DEX lane's /swap fix committed on dex-devnet3 (the syncing and no-answer sentences out of the pools table into a wrapping line under it; both tables fixed layout and normal white space; the row reads "RPC syncing" or "no answer"), checked at 768 px with the public RPC at block 0: no overflow; its first landing's full gate killed at 14:4x by another lane's pkill -f tools/ci/pre-push.sh (the kill-by-name class again), the landing re-running, on master before 15:00 unless killed a third time. The record's forty-fourth landing's re-run merge gate read RED at 14:5x on that same /swap clip at 1600 px dark (the sweep renders the live page while the RPC re-executes), so the record lands after the DEX fix is on master. The forty-fourth landing on master at 14:5x BST (e694030f, after the DEX lane's /swap wrap 92b6da6f reached master at 14:48 and cleared the sweep's red). THE INTEL ROW CLOSES at 14:46 BST: the Arc B580 on the second PC reads the rebuilt kit 65b47211 EQUAL at its logon turn (run-ca3-pc2-v5-intel-bench-20261008: v5 fingerprint 82b19cbde8557ea5 = expected, match True, check PASS, 10.794 MH/s quiet; the v4 control 892b6d55a7ddcfcb PASS at 10.718; both self-tests 96 of 96; the host's "rotr_var rewritten to the shift form before the build" line present, sub-group size 32 with sub_group_shuffle_xor), so the rotate fold was the whole Intel fault, the sub-group patch stays unapplied, and the class v5 kit reads one fingerprint on six platforms: CUDA (RTX 4090), Metal and Apple OpenCL (M5 Max), AMD (RX 9070 XT), Intel (Arc B580), the CPU verifier. The page's Intel row at class-v5 916925f5 (both mirrors 14:51); the 0.3.26 line to the shipper by its rule: the post-freeze class-v5 line with the Intel kit in, 0.3.25 on 1c420786 as published; the shipper carries the Intel kit into the first app cut after 0.3.26. PC 1 at 14:50 BST: no job taken since 14:13 (kit d, the read-width run, the memclk ladder, the card-in detect all "no uploads"), the default ran at 14:48: the signed restart job kind for the app (restart-app-pc1-20261008-cardin); if the app is polling it restarts itself and the queue drains in order; if it is hung or gone only the founder's hand at PC 1 brings the runner back (the ask with main since 14:36). At 15:00 with no job started: kit d's rows and the W = 8 row miss the 15:30 close (the op mix the microbench arithmetic, W = 4 pins), the 7600 pass and the 5.5 GiB rows move to PC 1's return. Floor lane 1's close row to main and the research lane at 14:50 with the memclk ladder labelled owed; its file complete at 32132943. Floor lane 2 (shadow k), the design sweep at 14:5x BST (synthesis-only, 8 lanes, ASAP7 TC 0.70 V, gate-level random-input VCD at two run lengths with the steady state solved; k absolute at N3 against the 5090's 6.2 pJ at the 1,300 lock, 11.3 at stock, the M5 Max 6.9): base (32 regs, 256 imem) 186k cells, 6.9 pJ per lane-op (2.4 clocking), N3 3.5, N2 2.5, k 0.31 / 0.56 / 0.50 (stock / lock / M5 Max); (1) the 64-register file (40-bit word) 268k, 9.7 pJ, N3 4.8, k 0.43 / 0.78 / 0.70, a new ISA on the GPU side (in energy about free on NVIDIA, 255 registers per thread; rate paid only when occupancy drops below the latency-hiding point); (3) the 1,024-instruction imem as built (a flop array) 325k, 12.0 pJ, N3 6.0, k 0.53 / 0.97 / 0.87, measured on the GPU at 1.58x energy per hash for 4x the shadow instructions; (3) with the imem as a 4 KB SRAM macro (2 to 4 pJ per 32-bit read, shared by the lanes) about 7.2 pJ, k about 0.32 / 0.58 / 0.52; (4) the drawn select tree 187k, 6.85 pJ, k 0.30 / 0.55 / 0.50, nothing on either side; (2) 32 lanes and (2') 32 lanes at 16 regs in sim, clock 15:30; (5) all four together in ABC on build-3, clock about 16:00. The reading: the 64-register window is the one robust knob (+0.22 of k at the lock, per lane, not amortisable); the long block adds little once the imem is SRAM; the select tree adds nothing; (1) + (3) as built reaches k about 1.2 at the lock but a chip maker builds the imem as shared SRAM, bringing it to about 0.81 (0.45 at stock), and wider SIMD amortises the fetch further; k 0.85 is not reached by any knob a chip maker cannot amortise away; the DRAM board under 2x at the lock needs the register window AND the long block AND the honest card at its knee, and holds only if the chip's imem cost stays unamortised, which it does not. The node column (claimed from TSMC's headlines: N7 to N5 x0.70, N5 to N3E x0.72, N3E to N2 x0.72; the 5090 and 4090 on 4N, N5 class; the M5 Max N3): base 6.9 ASAP7 / 4.8 N5 / 3.5 N3 / 2.5 N2, k at the lock 0.78 / 0.56 / 0.40, the GDDR7 board at the lock 2.4x / 2.8x / 3.2x; the 64-register core 9.7 / 6.8 / 4.9 / 3.5, k 1.09 / 0.78 / 0.56, the board 2.0x / 2.4x / 2.8x. The one line: of the 2.8x at k 0.56, the N5-to-N3 node step is worth 0.4x (a factor 1.17, claimed); the rest is the memory system (3.6x at zero shadow at the lock) less what the class v4 shadow takes back on the card's own node; on the card's own node the base core sits at k 0.78 and the 64-register core at 1.09, so "near 0.9" is reached node-for-node by the window alone; what it does not survive is the node step a chip project buys (an N3 core gives back the 0.4x, an N2 core 0.8x). The placed 8-lane core in detailed route on build-4 at nice 19 (about 16:00). Branch class-v6-floor-k. The hash lane's reading of the 64-register window: not exportable inside 20 minutes: eight registers fixed in four places that must agree bit for bit (the generator's operand draw modulo 8 and the register init from one seed word each; the three kernel texts r0 to r7 selected by (i + 1) & 7; the CPU verifier's register array; the warp's hash fold over the eight), a 64-entry window needing an init rule for the 56 extra registers (a design choice) and a fold rule for the output, then the emitters, the verifier and the vector check: a half-day line; the GPU-side figure modelled: 64 live registers a lane on top of the kernel's forty-odd puts a thread at about 110 of its 255 registers, occupancy to about half, the rate expected to hold under the latency-bound read chain (the 5090 hides about 330,000 ops a hash, chip-model-v3 5.7), the energy per hash to move little, the per-lane register traffic the unmeasured term; the half-day line can start after the 7600 pass if main wants it tonight (default not tonight). The research-landing lane: class-v6-floor-denominator at fc265d8d landed on master as d461e365 (14:50 BST; denominator.md plus the three app/igneum-app/tiers files; full gate GREEN 73); floor-sm (32132943, sm-sparse.md only, 717 lines; the worker patch on the branch) in its gate, landing about 15:03; k by 15:45; the close rows within 30 minutes of 15:45. Two deploys at 14:53 BST, checks ok (21 asserted pages): d461e365 (the DEX lane's 92b6da6f: /swap's RPC-syncing and no-answer lines under the pools table, both tables wrapping) and c8ce4b52 (the UI lane's site-fee-words on main's order: the dev fee as the fixed 1% fee with the app's Settings sentence on /miner and /dev-fee, "switch" and "switchable" gone from the fee card, the "Off with" row and the description metas; no "switch" string served on /miner). No chip text changed. The hotfix f8da7515's full gate set and both canaries read green at 14:50 BST (exec 55 with the dead-chain test, the mixed-version step HANDSHAKE on the unchanged digest), so THE SECOND MINUTE IS 15:05:00 BST, named on the gates rather than waiting for the fast-time pair: every box at +0 (81 of 97 fetched at 14:57, the rest by the pull), hub-1 and build-1's four by hand; the fleet's tarball 29f11d85 (igneumd 07a522f3, the miner unchanged eead4d0c, both fingerprints the freeze's). The merge default taken: 33 solo miners stopped at 14:53 to 14:57 (the fastest branch 122 under the epoch 21 cliff at 75,600, past which branches never merge); they restart with the move and the branches merge inside epoch 20. The 0.3.25 Windows entry skipped for good (a 0.3.25 Windows node would deadlock); the Windows line lands with 0.3.26 (602bce8c; the installer's copy-step fix on that tree by 15:30). The next readings: the first block on the rejoined chain, the replay rate, the first lock. Floor-sm (32132943, sm-sparse.md only) landed on master as 69335fc1 at 14:58 BST (full gate GREEN 73); the landings today: 868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1; open: floor-k by 15:45 with tools/chip-model/rtl, the design document's close rows within 30 minutes of 15:45. PC 1 is back: kit d closed on the 5090 (run-ca4-pc1-v6d-packs-5090-20261008, 14:51 to 15:0x BST, all PASS; rows with the research lane and floor lane 5), the runner's stall 38 minutes (14:13 to 14:51, the founder's hand or the restart job). The op-mix row inside the shadow block: against the same worker's w4 base (119.95 MH/s at 308.2 W unlocked; 100.55 at 190.5 W at 1,300), the shuffle-heavy table costs the block 155.5 W unlocked and 80.6 W at the lock (level with the stock table's 152 and 84 this morning), the multiply-heavy table 104.6 W and 62.0 W (31 and 26 percent less), the rate flat within 0.4 percent: the weight table is a 30 percent lever on the block's watts on Blackwell, with the sign the microbench gave for the multiply end and smaller magnitudes than its arithmetic on both ends. Floor lane 5's hinted w64-l2: 92.35 MH/s at 369.1 W unlocked (23 percent under w4, 1.56x its energy per hash) and 37.59 at 164.1 W at the lock (2.3x), dead at the knee as at stock. PC 1's queue: the read-width run (the W = 8 row about 15:30), floor lane 1's memclk ladder, the 7600 detect about 15:5x and its pass (the first 7600 row about 16:00, the stall's slip); the register-window hand for 16:30; the 5.5 GiB kit from the worker lane at 16:00 with the rented 5090 row behind it. Lane D at 15:1x BST, every stratum COMPLETE: w1band 3,000 (build-2), w4band 3,000 (build-3), w4shape64 3,000 (build-4), shape256 3,000 and shape64lossy 2,000 (build-3), the four lossy-share points 3,000 each (build-1), the F8 label space's p2 to p65 and p212 to p225 through the sigma form (build-2); point A DONE on build-1 (64 seeds: 45 PASS, 3 beyond 1.2x, 2 hot sets p38 and p54, both REFUSED by the class v5 floor at 0.9932 and 0.9945 in the floor read on build-3); point B at 54 of 64 on build-3; the x4/x8/x16 verifier rows resubmitted on build-3's free cores after waiting on build-2's pool since 14:5x; 38,000 drawn eras in all today, about 90 core-hours; the 16:30 report holds with sections 6.4 (the lossy curve per shape), 6.5 (the width-4 floor decision), 6.6 (point A), 6.8 (the seven known-failed seeds through the sigma form, the bucket bound retired into the bit read) in the tree; point B and the verifier rows by 16:00, as partials if not. The floor-invention knee-row amendment (3951528d) landed as 66c3401e at 15:12 BST (full gate GREEN 73); the landings today: 868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1, 66c3401e. The fast-time SUMMARY PASS (cross-0325-f8da7515-2) at 15:17:51 BST on the hotfix f8da7515 (the freeze fingerprint on both binaries read before the lease; 15:04:51 to 15:17:51 on build-1: rung 1 at 15:11:28, class v5 by signal at byte 6 from epoch 8 at 15:13:20, 12 of 12 ids equal to the freeze CLI's, the stale node 78 of 78 refused, the restart step resynced in 6 s with the catch-up done after 3 s, four sinks equal at 662, 0 PoW rejections); the first run on the same artefact (15:03:21) read the crossing green too, its FAIL line the late joiner's wait letting two epochs past the observation window into the id rows (harness scope, fixed); the cold-restart class is the node lane's unit test, the pair cannot read it. The shipper's preview 1 at 15:1x BST: preview-26-1 at 57476931 on the mirror = the coordinator's f2781776 plus app-ia-26 e4773cf0 (item 4, the Tune page), release-0.3.26 f44baa25 (602bce8c plus install-detach-26 b39d5dd5, the take-3b copy-step fix) and the preview mark (state.preview from IGNEUM_PREVIEW at build time, appended after the version on the About line and the footer, empty on a public cut; no constant on any branch); the build-server lane cuts the kit, the cross with the env, the payload with the f8da7515 Windows pair and PC 1's host (host-0326 ahead in PC 1's queue), the install takes on PC 1 and PC 2; the Mac DMG by the Mac chain and the install over the founder's app by the shipper's hand; each machine's version and time to main. One red on e4773cf0: ui/heat-region.test.mjs:137 (a resting card's wording), the UI lane's by 15:35; the preview ships with it named, the public 0.3.26 app cut waits on green; take 3c (the public 0.3.26 Windows entry) on f44baa25 behind the preview takes. PC 1 at 15:14 BST: the founder's restart of the app at 15:06 ended the read-width run at 194 s (exit -1, "script was ended") after its three stock rows landed: v5-genesis 118.83 MH/s at 423.5 W, W = 4 under the state term 117.54 at 430.9 W, W = 8 117.54 at 451.5 W; so THE W = 8 ROW EXISTS AT STOCK (the rate equal to 0.01 MH/s, 4.8 percent more energy per hash; with floor lane 3 and the research lane); the 1,300 lock rows and the W = 16 state-term row owed from a republished run (run-ca3-pc1-readwidth-5090-20261008-b, behind the detect and the memclk ladder, about 16:30). The runner had already resumed at 14:51 on the signed restart job (kit d 14:51 to 15:02, the read-width run from 15:03), so the founder's hand restarted an app that was polling; no harm beyond the lost rows. PC 1's queue: the 7600 detect, the ds55 kit fetch, the memclk ladder (about 25 minutes), the read-width run b, the shipper's host preview build, then the 7600 pass (the OpenCL bench with --cards-off on the new key, the grid, the tier rows, the 5.5 GiB rows on the 7600 and the 5090). A caveat on every PC 1 row since 14:2x: the 5090 reads about 13 percent under the morning on the same packs and worker (v5-genesis 118.8 against 135.9), a host-side change with the eGPU swap; the next job's card line reads the PCIe link, the first suspect. The 5.5 GiB kit done (the worker lane, ds55-v5 at b57045fb, the emulated worker's self-test PASS on the 5.5 GiB pack; the kit on build-1, sha 2d7f55e8) and with the fleet lane for the rented 5090 row. The forty-fifth landing on master at 15:27 BST (6ae577e40). THE CLASS V6 FLOOR CLOSED at 15:28 BST, 17 minutes ahead of the 15:45 clock on the ship-on-green rule, every lane's last row in, on the mirror's counter-asic-4 (docs/design/class-v6-rotating-family.md section 10; the tip 725d2945 at 15:27; the full gate green on the branch; the landing on master by 16:30). THE TABLE (10.0 with 10.0e), the honest tier's measured class v4 joules per hash over the chip's modelled joules, the chip's core the k lane's synthesised sequencer core with the 64-register window (10.0c: the one knob a chip maker cannot amortise, k 0.78 at the lock at N3; the card's window cost modelled, labelled) and the per-unit floor (k 0.18) beside it as the worst case: the RTX 5090 at its 1,300 MHz knee (2.33 µJ): GDDR7 board 2.4x (2.8x without the window; 4.0x at the unit floor), HBM3 stack 2.9x, SRAM die at the genesis width 4.3x; the RTX 5080 at its 1,100 MHz lock, the honest NVIDIA floor (2.06, measured; lane 4's finding that the floor is the 16 GB Blackwell card, not the 5090): 2.2x, 2.5x, 3.8x; the Apple M5 Max (1.40): 1.5x, 1.7x, 2.6x; stock rows: the 5090 3.5x / 4.1x / 6.2x, the 4090 and H100 in 10.0. The node row: 2.0x against a chip on the GPU's own node, 2.4x a node ahead, 2.8x two nodes ahead (node-for-node the window core is k 1.09); the honest tier moves to the next node with every GPU generation while a chip must re-tape-out. SM-sparse: no change on any card (measured on the 5090, 4090, H100: 1.3 to 3.9 percent at best; the residual the clock domain). W = 16 killed on measured energy on four cards at stock and at the 5090's knee (+25 to +34 percent per hash on the card against the chip's +33). STATED PLAINLY: the GPU-tier floor is about 2.2x to 2.4x per joule at the knee against the chip anyone can build, under 2x only against the Apple tier; Monero's RandomX measured 1.0x to 1.5x beside it. THE CAPEX WALL (10.3): no rational chip project of any kind below about USD 23 M a year of miner revenue (IGN 0.03); every DRAM-board project at a third of the network above about USD 340 M a year (IGN 0.44); the project cost moves the threshold 5x, the chip's edge 1.4x. THE SERVED LINE in two units: under 3x per joule at the knee (2.2x to 2.4x with the window), under 1x per hash over its 180-day class life only above about USD 300 M a year of miner revenue (10.0a). THE FOUR CLASS V6 CHANGES: (1) the op mix stays class v4's with the lossy families capped at base (0 of 3,000 eras exhausted under the band; a multiply-heavy table lowers the card's premium a quarter but the chip's further, mul and mulhi k 0.03 to 0.08; the shuffle weight costless to the card and can rise inside B = 4 if the chip's butterfly k reads high); (2) no SM-sparse default (--sm-sparse auto off, on in Efficiency and Balanced at its measured 1 to 2.5 percent); (3) the dataset schedule 5.5 / 8.5 / 11.5 GiB (the 5.5 GiB step measured on a rented 5090 at stock: 3.5 percent of rate, about 4 percent of energy, the non-power-of-two mapping no cliff on sm_120, safe to adopt at the v6 epoch; about 9 percent at the knee, interpolated) with the read width pinned at 4 words (8 measured not free at +4.8 percent of the card's energy for 0.2x of the die's shadowed edge, 16 never); (4) the 64-register window per lane as the core shape, its GPU side modelled until measured. The rotation schedule adopted (10.0d): hourly 8,766 / weekly 52.18 / family 2.03 / vote at most 2.03 extra boundaries a year, the 6 h vote window. Precedents sourced (10.0b): RandomX 46 months to a chip at 1.0x to 1.5x; Ethash 36 months to a chip worse than a GPU, 14x today; Kaspa 21 months, 167x to 725x. MISSING AT THE CLOSE, each with its default in the document and owed as an amendment with its own minute: the k lane's 32-lane rows and placed core (about 16:00; the +30 percent placement and the register-file gating roughly cancel, provisional); the card's measured window cost (a half-day generator line); lane 1's memory-clock ladder; the W = 8 lock row (16:30) and the RX 7600 8 GB-tier row at 5.5 GiB (16:00 to 16:30); lane D's full report 16:30; lane C's drawn-era F8-form read. THE 5.5 GiB ROW measured two hours ahead of 17:30 (the fleet hand on a rented secure 5090, 15:19 to 15:23 BST, USD 0.32, the pod destroyed; the kit igneum-ca3-ds55-kit-20261008.zip sha 2d7f55e8 with its own worker d43be462, program id 73bcbfe8ccf988f1 in both packs): the pinned class v3 program at 1 GiB 141.48 MH/s at 325.6 W (2.30 µJ, fingerprint 90f794dd556f7a3b, the pin, 1,914 MiB used) against 1,476,395,008 words (92,274,688 items, not a power of two: loads are (src * words) >> 32) 136.56 MH/s at 305.3 W (327.6 steady; 2.24 to 2.40 µJ), fingerprint 23ced07a4d28b465 (the new pin, stable over two passes), the self-test PASS 96 of 96 lanes, 6,522 MiB used; the --batches 500 passes 141.38 and 136.54 with the same fingerprints. So the genesis floor costs a 5090 3.5 percent of its rate at stock, about 4 percent of energy per hash, no cliff from the mapping, on the 2 and 4 GiB stock rows where the interpolation put it. Caveat: that host capped the card at 328 W on both packs (the 1p5x 5090 on another host pulled 443 to 575 W), so the µJ figures are capped-card numbers; the rate and fingerprints stand. The emulated worker's known-failed counterpart reads 96 of 96 bad lanes on the old mapping. The 7600's 8 GB reading and the 5090's knee rows at 5.5 GiB from PC 1 after its queue, as amendments. The attack pass's 15:30 reading (counts at 15:21 BST), two non-zeros sent at once: F9 to 10^6 on 1c420786: 135,836 of the 900,000 new seeds drawn (build-4 99,456 across its six lower chunks, build-2 36,380 across its six upper), 0 exhausted, 0 panics, max attempt index 32: one seed, 718097 (build-4 chunk 4), accepted at index 32, past the record's "0 past 31" line but nowhere near the 256-attempt cap; the histogram tail 24: 5, 25: 2, 26: 2, 27: 1, 28: 1, 32: 1, the geometric tail at its rate (one in 136,000 at 32 against the 10^5 record's one at 30); not a finding: the exhaustion gate is the cap and the deterministic last resort, both untouched; the record carries the max as read. F1 to 10^6 class v5 programs: 172,310 distinct programs done (build-4 83,000 of its 350,000 lower range, build-2 89,310 of the upper on four 13-core parts), differential mismatches 0, verifier mismatches 0, 0 panics, programs over 5 percent: ONE, attack-f1/392513 (attempt 0, 6,912 to 6,561 per iteration, 5.0781 percent, 13 of 256 per pass), the same saving to the digit as the v4 10^5 letter miss attack-f1/37341 (AP-F1-1); the next worst 369298 at 4.6875, 373345 at 4.2969. Under the ruling on AP-F1-1 (gate (1) re-worded to compressible beyond the honest compiler's own simplification; a letter miss at honest-compiler parity is a PASS) a letter miss to be read at parity: the section 7.3 and 7.4 readings (explain, emit-c, the compiler pass) running, the parity verdict within the hour; if the compiler does not find the same 13 it is a finding on the v5 bound (AP-F1-1's v5 half reopens). Ends: F1 about 05:00 BST (build-4's lower range back at 40 threads from 15:30, about 01:30; build-2's parts about 04:40); F9 about 11:30 BST tomorrow (build-4's lower halves at 3,400 seeds per hour per chunk the long pole; build-2's upper halves about 08:30, taking more of build-4's range when F1's parts free their cores). Two pre-emptions on build-2, none on build-4. The shipper at 15:2x BST: the founder's Mac runs preview 1 since 15:21:53 (the DMG 94327b68 from preview-26-1 57476931, installed over 0.3.24 by the engine's own helper, the state reading version 0.3.26 preview "preview 1", the node on the f8da7515 pair replaying); PC 1 and PC 2 follow through the job runner once PC 1's host-0326 lands. Build-1's seed and node1 replayed on f8da7515 from 15:06:39 to the sink at 15:13:47 (7 min 8 s), 94 peers, the sink advertised again; the chain stands at 72,001 until one miner runs; the one-miner word to the fleet lane at 15:23 (the heaviest branch's box, the rest as their sinks converge; dn3-q03 and dn3-relay to a wipe and resync, their branch mined past the floor under the old rule). The 0.3.26 public stage complete (DMG 6f717c78, hive e3e4482c); its minute after the first block. MAIN'S CLASS V6 BUILD ORDER at 15:3x BST (the close 725d2945 in; the no-consensus-code hold lifted by the order), five lanes fanned under the founder's clock rule, each sent with its default: (1) the hash lane, the generator: the 64-register window per lane with its init and fold rule, the index fold (layer 1's remedy for the era-stride bit; the known-failed set p4, p8, p10, p15, p34, p212, p225), the op-mix re-weight table (13,11,6,10,8,8,7,2,6,4) behind the fold, W = 4 unchanged, the ds55 mapping as the dataset form; four packs (window, fold, re-weight, all together) exported by 21:00; (2) the census lane re-spawned on the four packs through the sub-version 3 harness on build-3 and build-4, PASS or FAIL by 22:30, a dry PASS on the freeze's pack by 18:00 as its readiness line; (3) the node lane, the object: the class v6 object with the dataset schedule 5.5 / 8.5 / 11.5 GiB tied to state at the era cut, the family bank's first entries as admissible flags, the floor DAA on Devnet 3, the digest, the worker-smoke rule and the fast-time crossing with the cold-restart and template cases, by 23:30; (4) the shipper, the cut: 0.3.27 as the class v6 line, the pin tomorrow morning on the gates, the Devnet 3 flip at a floor at least 90 minutes after the pin, the fleet on the kit workers first, Mac, HiveOS and Windows at the minute, the card after; release-0.3.27 opened tonight after 0.3.26's minute; (5) the audit lane, the served chip page rewritten to the close's sentence and the node column, the harness and the scoring rules published with it, on master by 17:30 (the 20:00 hold lifted by the order). The first packs and the census verdict to main with their times. Floor lane 2's remaining sweep rows at 15:2x BST (synthesis-only, ASAP7, N3 claimed, GPU measured; absolute k at the 1,300 lock): (2) 32 lanes, 32 registers: 5.55 pJ per lane-op ASAP7, 3.9 N5, 2.8 N3, 2.0 N2; k 0.63 / 0.45 / 0.32; the GDDR7 board at the lock 2.7x / 3.1x / 3.5x; (2') 32 lanes, 16 registers: 4.2 / 2.9 / 2.1 / 1.5, k 0.47 / 0.34 / 0.24. The register-file cost is linear in its entries (16 to 32 entries +1.35 pJ, 32 to 64 +2.8 pJ per lane-op at ASAP7), the one term a chip cannot amortise; the imem and sequencer amortise 1.35 pJ from 8 to 32 lanes. The shuffle (routed): 1.24 pJ per lane-op ASAP7 against the card's 29.4 at the lock, k 0.021, the lowest drawn family. The mix optimiser over the layer-1 band lifts the unit-floor k_eff from 0.097 to 0.137 (add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0) and the core's k by about 15 percent. (5) all four together in ABC on build-3 (about 16:15); the placed 8-lane core in detailed route on build-4 (about 16:00); the crossbar, scratch and int8 tile rows after them. Amendment 1 to the class v6 floor close (15:3x BST, counter-asic-4 after 725d2945): the k lane's routed 32-lane butterfly reads k 0.011 to 0.021 (the card pays 29.4 pJ at the lock for a move the chip does for 0.63), the lowest of every drawn family, and its mix optimiser over lane D's band puts the best genesis table at add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0 (+42 percent of k_eff on the unit floors, +15 percent on the core: 0.56 to about 0.64, the window core 0.78 to about 0.9); change (1) moves from "the op mix held at class v4's" to "the band's best mix as the genesis table", subject to one acceptance pass through lane D's harness (ordered by 18:00; the census lane's neighbouring table at 256 of 256 both ways the fallback); the edge moves about 0.1x in the card's favour at the knee (2.4x to about 2.3x with the window); the core32 row in (k 0.45 at the lock at N3). The coordinator's default to the hash lane: the re-weight pack on the amended table unless main says otherwise by 17:00, both tables exported if free. The shipper took lane 4: release-0.3.27 opens tonight after 0.3.26's first block and minute (the bump only; the node line release-0.3.27-node from the object cut); the runbook at scratch r0327/RUNBOOK-0327.md: 0.3.25's twelve steps plus the worker smoke per platform and the attempt-3 read before the pin, the fleet on the kit workers first, the root gate off for a move after which executors start from nothing, every node with --unsaferpc, rules 16 to 19 in their places; tomorrow's pin clock stated as a time on the three inputs (packs 21:00, census 22:30, object 23:30), the flip's floor at least 90 minutes after it. The forty-sixth landing on master at 15:38 BST (3ce4fd7e5). MAIN'S AMENDMENTS to the class v6 build order at 15:5x BST, from two external reviews the founder accepted: (1) the generator's 64-register window carries the liveness rule (the fold forming each load address consumes all 64 registers; the result depends on the whole window; a liveness tool is an acceptance test beside the census) and the op-mix target is the k lane's optimiser split (add 16, xor 14, mad 12, rotl 11, sub 10, rotr 10, shfl 4, mul 4, mulhi 2, or 0); (2) the served chip text does NOT take the 725d2945 sentence: the close is amended by 17:00 into three separate statements, energy, economic and response capability, with the lifetime claim and the USD 300 M / 340 M safety-boundary wording withdrawn (a programmable chip survives epochs on firmware), and the audit lane serves the amended text by 18:00; (3) three research lanes beside the build (connected state a4d3518190ad011fc, mixed FP32 aa943688eaa06c538, multi-family adversary a1a9876a88f5a72fc) with rows from 18:30, feeding v7 not tonight's cut unless the connected-state row passes its gate before the object closes at 23:30. Relayed to the audit, research and hash lanes with the clocks. The five lanes' takes: lane 1 (the hash lane) fanned at 15:50: hand A (the window) on reg64-v5 off w8-v5 with the amended spec (the address fold consuming all 64 registers, the end fold over the whole window; ptxas registers, occupancy and spills on the 5090 and 4090 beside rate and watts for the k lane by 18:00), hand B on class-v6-fold off ds55-v5 (the index fold before the stride rotation with the known-failed seven as the per-site index-bit test; the re-weight on the k lane's split, 16,14,4,12,4,11,10,2,10,0 in draw order, sum 83, as hl-v6-rw, the census lane's 13,11,6,10,8,8,7,2,6,4 as hl-v6-rw2 if cheap, hl-v6-foldrw on the k lane's table; the suites on build-3; the packs byte-seed on the node1 state with a drawn era, generator 5, to build-1, the fold pack first); hand A's hl-v6-win and the all-together pack by 21:00. Lane 2 (the census lane afb2fb655385dc259) at 15:4x: per pack (1) the sub-version 3 acceptance with the (c''') per-site floor and the bit-level era-stride read (lane D's fg7 harness, the class v5 crate plus the family-gate diff), (2) attack-f8 at 2^24 on 64 seeds with the window control by site against the pack's state, the hot-set verdict and the known-failed set (p212 and p225 added for the fold pack), (3) the attempts census over the pack's epoch stream; fanned one pack per box, class v5; the f8 point the long pole (45 to 100 core-hours per 64-seed point, about 90 minutes on 48 cores; four packs on two boxes fit 21:00 to 22:30 only with 48 free cores each, which build-4 under the attack pass's 88 and build-3's 24-core pool do not give now); the dry PASS on the freeze's pack by 18:00 as the readiness line, the clock stated when it lands. Lane 3 (the node lane) at 15:4x: the object on the fork branch class-v6-node off release-0.3.25-node at 6e04f7fc (carrying the cold-restart and genesis-stream fixes), program-id first (lifted from the v5 lane's kaspa-pow bin as igneum-miner program-id by 19:00); the fields, each with its own digest arm entered only when set and a key in override-60x.json: program_class_v6_activation_daa (the floor; Devnet 3's value set tomorrow by the floor cut at the pin's publish minute + 7,200 rounded up, at least 90 minutes after the pin; tonight u64::MAX on every network, the devnet-suffix profile for the crossing at 60x), class_v6_dataset_steps ((height, GiB) pairs 5.5 / 8.5 / 11.5 with the state rule's constants: 64 bytes a record, the era-cut read, the genesis ceiling; the item count derived by the ds55 mapping's rule), class_v6_family_flags (a bitset: bit 0 the window, bit 1 the fold, bit 2 the re-weight, bit 3 the lossy band at base; off means not drawable), the class signal byte 7 (CLASS_SIGNAL_V6) stamped from the floor, packaging/pow-freeze.txt as a per-class list with the class v6 entry, tools/ci/worker-smoke.sh for the worker rule (reads the object's fields from the node binary, refuses a cut without one PASS line per platform), the fast-time crossing by the fast-time lane with the --cold and template-at-boundary cases (in its harness since 336639b1); its three questions to the hash lane by 21:00 with defaults (items = floor(GiB x 2^30 / 64); the four bits as listed; the freeze = the last green commit on ds55-v5 at 23:00, class-v6-freeze). The 6e04f7fc go-cut pair landed at 15:33 (the testnet lane's thread). Lane 4 (the shipper): release-0.3.27 opens after 0.3.26's minute; the runbook r0327/RUNBOOK-0327.md. Lane 5 (the audit lane): the old sentence's anchors on every served page staged (home, the litepaper's chip model and table, /miner, evidence row 17, the X35 and X36 ledger rows and pins), the 10.0 scoring definition (whole-card joules per hash over whole-chip joules per hash, the card measured under class v4 with the shadow on, the chip's memory modelled, the chip's shadow priced on the synthesised core and on the per-unit floor), the class v5 harness links to the class-v5 branch's sections 14, 13 and 0 on the git host (moving to master's path on a merge); waiting on the research lane's amended text by 17:00, the landing by 18:00. The register window's first measured row ahead of 17:00 (the hash lane's hand on a rented secure 5090, 16:1x BST): the pinned class v3 base 141.74 MH/s at 303.1 W (2.139 µJ, 30 registers a thread, 24 blocks per SM) against the arithmetic-only window pack hl-reg64 (two interleaved 32-register programs, twice the work per hash by construction) 80.38 MH/s at 308.6 W (3.839 µJ), 96 registers a thread by ptxas and the worker, 0 B spill, 20 blocks per SM (3,400 of 4,080 resident warps, 83 percent). Per unit of work the card is level with the base (160.8 base-equivalent MH/s against 141.7; 15.0 nJ a load against 16.7; the watts level): on Blackwell the 64-entry window costs no energy, no spill, and the 17 percent occupancy loss does not reach the rate under the latency-bound chain; the "half occupancy" model was pessimistic. The 4090 row and the full-chain form on both cards (the address fold over all 64 registers, hl-reg64c) before 17:00. The build-server lane's lease-pool memory rule on master as 5636a0d4 (15:36 BST) and installed on the four boxes at 15:37 (lease sha 82cc0564): a lease declares its resident memory (--mem N or "about N GB" in the label, default 8), the pool waits rather than take the box past 100 GB with the hands' residents counted, the holder line carries the figure; the cause the 12:06 OOM kill of the seed under a 31 GB attack binary. THE REGISTER WINDOW'S MEASURED SET, complete at 15:45 BST on the hash lane's rented secure 5090 and 4090 (the lane's own stamps read CEST; the record carries BST; USD 1.22, the pods destroyed): the 5090 arithmetic-only window pack hl-reg64 (two interleaved 32-register programs, twice the work per hash by construction) 80.38 MH/s at 308.6 W (3.839 µJ), 96 registers a thread, 0 B spill, 20 of 24 blocks per SM (83 percent occupancy), against the pinned class v3 base 141.74 at 303.1 W (2.139 µJ, 30 registers): per unit of work level (160.8 base-equivalent MH/s against 141.7; 15.0 nJ a load against 16.7; the watts level); the 4090: base 62.67 at 208.9 W (3.333 µJ, 29 registers) against the window 31.57 at 210.3 W (6.663 µJ), 104 registers, 0 B spill, 16 of 24 blocks (67 percent), per unit of work level to the digit (63.1 against 62.7; 26.0 nJ a load on both); the 5090 full-chain liveness form hl-reg64c (every load's address mixes all 64 registers, id 3deee2320e70e1bf, fingerprint 4e7cc25967eba280, PASS, on build-1): 70.96 MH/s at 320.3 W, 4.513 µJ, 88 registers, 0 B spill, 20 of 24 blocks; against the arithmetic-only window the 2,016 extra ALU ops an iteration cost 12 percent of rate and 4 percent of watts (the mix in the load latency shadow); against the base the loads a second level (18.2 against 18.1 G) at 17.6 nJ a load against 16.7; the 4090 full chain 31.38 MH/s at 216.5 W, 87 registers, 0 B spill, 20 of 24 blocks, fingerprint equal. THE SINGLE NUMBER THE SERVED LINE TURNS ON: the GPU loses at most 5 percent per load to the liveness window (5 percent on Blackwell, 4 on Ada) and no rate per unit of work, no spill, the occupancy cut (83 and 67 percent) never reaching the throughput; the "half occupancy" model was pessimistic; the 2.0x or 2.4x is the chip side's k, which the k lane holds. The sound class form (+reg64c, the full chain, the only form the liveness rule passes) exports as hl-v6-win on build-3 with its acceptance test in the suite. PC 1 at 15:44: the runner on floor lane 1's memclk ladder (from about 15:20, 25 minutes), the shipper's host-0326 preview build next, then the 7600 detect (about 16:10), the ds55 kit fetch and the read-width run b; the first 7600 row about 16:30, the grid 17:10, the ds55 rows after. Floor-k (bfccc26ed) landed on master as cc49bc6e at 15:39 BST (shadow-k.md plus tools/chip-model/rtl, 78 files; full gate GREEN 73): ALL FIVE FLOOR DOCUMENTS ARE ON MASTER (868fea52, de3d32af, d28a7656, 018a0877, cb71b766, d461e365, 69335fc1, 66c3401e, cc49bc6e). The 15:45 close landing dropped by the research-landing lane: nothing from 725d2945 lands; the close rows land as a documents-only delta from the research lane's amended "complete " by 17:00, replayed from 08641162 onward. Lane C's drawn-era F8-form row on master at 5cd69d3d (15:41 BST; invention.md section 3.5): under drawn eras the sound per-load form (16 x 256 x 1, 64 seeds, 2^20 nonces, build-2) is NOT the clean row the no-era read gave: 7 of 64 seeds carry a load site under the (c''') floor of 0.995 (min 0.940 at seed 50; seed 27 at 0.956 with one item at 1,938 reads, 67x the uniform control's maximum), the few-item hot-set class and the era-stride class the in-house pass bounded for class v4 at the same order, structurally because the per-load class as built runs neither (c'') nor (c'''); the share column against a uniform control (median 1.15x, max 1.49x) is the window layer, labelled so. Consequence: layer 5 must take the (c''') floor with the dataflow rule, layer 4's generalisation and nothing new; G5-draw's pass line now "0 of 64 seeds with a site under 0.995 under drawn eras" with the seven seeds as the known-failed case; the acceptance figures (0.819 under eras, 0.927 no-era) stand as the pre-floor rate; the chip model does not move (a 1 MB hot set at 0.3 percent of reads is the in-house pass's 1.002x). Lane C closed: five landings (a9f03598 to 5cd69d3d), the harnesses under tools/attack/v6-invention/, six TSVs; owed at 09:00: the Apple footprint of the 4,096-line block, the 4070 and 9070 XT rows, the F8 read under eras against the window-model null. LANE D'S FULL REPORT LANDED on master at 81b90128d (15:46 BST, gate GREEN 73; a first landing de184157a at 15:39 lacked the point-B row by an edit fault), 44 minutes ahead of 16:30: family-gate.md with every row measured and its log. The rows since 13:13: (1) the lossy-share curve per shape at 3,000 eras a point: the exhaustion a 256 x 27 interaction (3.3 percent of its eras at the +4 corner, r = 0.98, about 6x the independent-attempt figure; 0 of 5,015 shape-64 eras at any share), the band's edge at +2; every exhausted era passed class v5's last-resort scan at k = 256 to 258. (2) The width-4 floor: with W = 4 pinned at genesis, (c''') at 0.995 stays at its measured cost (14.6 percent of the candidates reaching the 2^20 pass, +0.3 attempts an epoch), because the width-4 pre-floor spread has a real tail (10 percent under 0.991 against 2 percent at width 1) no single floor removes at the width-1 cost, and the floor refused both hot sets of the live point-A census. (3) Ring C, 128 live epochs of the band at 2^24: point A (shape 256, a band table) 2 hot sets (p38, p54), both refused by the class v5 floor at 0.9932 and 0.9945; point B (shape 64, a band table) 0 hot sets, 5 over 1.2x (the shipped class's own tail seeds), the floor refusing 1 of 64; the bit-R bucket class on 36 of 128 live epochs against the shipped class's 4 of 64. (4) The seven known-failed seeds through the sigma form: p4, p8, p10, p212, p225 all at z = -511 to -567 at address bit R (the product's bit 0, z = -512 exactly), the bucket bound seeing only the three on narrow windows above bit 12; one value-level test ships (the per-site index-bit read as a per-era record and the structural fix's known-failed set), the bucket bound retired into it; a refusal band of 300 sigma catches five of seven at 16 percent of epochs redrawn, 6 sigma would redraw half. (5) The verifier rows on one build-3 core: x4 3.73 ms, x8 4.12, x16 7.13 per warp (1.73x), so x16 scales over the 10 ms gate on the 2019-class core and the half-core proxy: the mixer band is {4, 8}. (6) Bounds: 9,000 band eras with 0 exhaustions and 0 under the floor bound the failing fraction at 3.3e-4 at 95 percent; the floor's miss rate on hot sets under 0.27 on 11 of 11 cases. Running for the 18:00 amendment on build-3: the best-mix genesis table (renormalised 14,13,4,11,3,10,9,2,9,0) through attack-f8 at 2^20 on 64 seeds (16 cores) and the attempts census with the refused-ratio column at widths 4 and 1 (1,500 eras each, after the fg8 build; the fg7 harness could not hold a fixed non-base table at B = 0). Lane 5's served text at 15:4x BST on branch spec-accept-23 be21940f5, read by the coordinator (the IGN-price lines held out by the standing rule; one verb queried, "retains" against "adopts"; the landing by 18:00). The sentence from 10.0h, on the home line, the litepaper abstract, chip section and limits item, and the miner page: "Class v6 retains the 64-register window. Current modelling estimates a 2.2x to 2.4x energy-efficiency advantage for the strongest specialised designs assessed against the GPU tier (2.0x on the GPU's own node). The long-program and select-tree proposals were rejected. Economic resistance depends on development cost, deployment economics and productive hardware lifetime; family transitions receive an obsolescence benefit only where a loss of competitiveness is demonstrated; programmable multi-epoch designs are included in the assessment." Beside it on /litepaper#chip-model: the labels paragraph (2.2x to 2.4x modelled; the GPU side measured, the RTX 5080 at its 1,100 MHz lock 2.06 µJ per hash, the 5090 at 1,300 2.33, class v4, 8 October 2026; the chip side claimed, the synthesised 8-lane sequencer core with the window, ASAP7 scaled to N3 on the foundry's headline factors, the window's k synthesis-derived and not a lower bound; the memory modelled; 2.0x node for node modelled, k 1.09; the 32-lane rows pending); the three-row table (energy resistance 2.2x to 2.4x a node ahead, 2.0x own node, 2.8x two nodes ahead on the 8-lane core, the honest tier moving with every GPU generation while a chip must tape out again; economic resistance on development cost, deployment economics and productive hardware lifetime, the first cut: the price at which a project pays scales as project cost over share times discounted life and moves by under 5 percent with the per-joule edge, a fixed-lane chip under rotation needing 4x the price a programmable one needs, "stated as the conditions under which development is attractive, not as a forecast"; response capability: a passed boundary proves the rotation works, not that hardware dies; the schedule hourly / weekly / 180-day family / emergency vote); the measured cost paragraph unchanged; the precedents as 10.0b sources them (the Antminer X5 46 months after the fork at 6.37 J per kH at the wall, "an observed comparison, not a ceiling"; the X9 pre-order, withdrawal, no benchmark; RandomX v2 released 25 March 2026, activation pending; Ethash 36 months, the iPollo V2H about 14x; Kaspa 21 months, 167x to 725x; the commodity cohort = discrete GPUs, the Apple row beside, never the headline); the scoring rule (min over workloads of max over free adversarial designs of E_GPU over E_adversary under the 10 percent GPU-cost budget at the lock, the verifier limit, cross-vendor correctness, hardware accessibility; the rejected long program, select tree, wide read and scratchpad as negative controls with their rows; the next programme: connected state, mixed integer and FP32, the multi-family programmable adversary); the links to the close on master and the class-v5 branch's sections 14, 13 and 0. Struck from every served page: the 2.1x/3.4x launch line, the 5x to 9x baseline, the ladder's 2.8x rung row, the USD 100 M pay-back row, the k about 0.33 column, the "band Igneum's model sits in" sentence; never served: the lifetime claim, USD 300 M/340 M, any chip-arrival probability, the 725d2945 sentence, W = 8. Evidence row 17, ledger X35/X36 and the ledger-text-check pins move with it; docs/plans/counter-asic-3-public-text-2026-10-07.md section 1 superseded on the served pages (the coordinator's to amend). The hash lane's clock corrected at 15:49 BST (its afternoon stamps about fifty minutes fast, the hands' and the box's CEST copied in; every minute read off TZ=Europe/London date from here). Its open minutes: the 7600 detect about 16:10 (PC 1's runner on the shipper's host-0326 preview build; the memclk ladder closed done at 15:4x), the first 7600 row about 16:30, the grid 16:40 to 17:10 with the tier rows, the ds55 rows on the 7600 and the 5090 by 17:40, the read-width lock rows between them; hand A's hl-v6-win and hand B's fold pack about 17:00, the re-weight packs by 18:00, the class-v6 merge, the all-together pack and the freeze sha to the node lane by 21:00. The forty-seventh landing on master at 15:58 BST (022bc52bd), the 7 October public-text file marked superseded. THE PUBLIC 0.3.26 CUT: release-0.3.26 = 1f4904e0 (app-ia-26 ebb20c46 whole, the audit's PASS, the detach fix, the node pin f8da7515; the preview mark empty; the push gate green 15:50; the crate gate green on d1edf2ad at 314+35+8 and running on 1f4904e0 on build-3). THE MINUTE for Mac and HiveOS is 16:00:00 BST on the founder's "push now" (the DMG building on the tip, the hive e3e4482c staged); Windows host-less by main's word about 16:15 (the PC 2 installer build on 1f4904e0), PC 1 and PC 2 by their update checks. The founder's Mac runs preview 2 (a96efbab = effc48e9 whole + the mark) since 15:40:22. The node side: the snapshot short-capture class (the node lane's read at 15:48: every converging node refused its own epoch's blocks after a mid-epoch resume) cured on the fleet by the snapshot-aside restarts running now (24-minute replays; the first hub block about 16:10), its fix acaf08b0 under gates for the fleet's +0 move and the users' next node-only OTA; 0.3.26 ships on f8da7515 since an updating user replays from genesis. release-0.3.27 opens after the 16:00 minute. THE FIRST TWO CLASS V6 PACKS on build-1 and with the census lane at 15:58 BST, an hour ahead of the 17:00 line: hl-v6-fold (id 482dc0dad937135b; the seven failing seeds fire at -58 to -567 sigma on the plain address and read under 3.5 sigma with the fold, the same attempt accepted both ways) and hl-v6-rw (id 30628f8adcf6035e, the k lane's table, the op counts within 0.1 point of the table over 1,000 draws, the plain path byte-identical to the pinned pack); hl-v6-foldrw and hl-v6-rw2 next, hl-v6-win from the window hand on its suite's green. THE CENSUS LANE'S READINESS LINE met at 15:53 BST, seven minutes inside 18:00: a dry PASS on the freeze's class v5 pack (v5-dn3-epoch0, program id e5a4ac5978462156 re-drawn from the pack's own seeds, class and era) through the whole pack harness on build-4, the known-failed set reproducing the record to three places. The harness (branch class-v6-census-fg at 3602d4ad on build-3 and build-4; ds55-v5 b57045fb plus lane D's family-gate diff 3dc3117c plus a sitestats command and the attack pass's f8 tool with a --load-class path; binaries pinned on both boxes, byte-identical): per pack (A) the program re-drawn and judged by the whole rule with (c'''), then per site over 2^20 evaluations the distinct ratio, the 256-item bucket sigma and the index-bit era-stride sigma (4 s on one core); (B) the attempts census over 256 chain-shaped seeds of the pack's class under its era and state (16 cores, 2 minutes); (C) the F8 census on the live state-keyed dataset: the known-failed set at 2^24 one program per 8-core job (4 to 5 minutes each) and 16 seeds at 2^22 on 16 cores (about 30 minutes); class v5, nice 19, pid files under /srv/builds/v6-census/pids/. The dry rows: (A) accepted, min site ratio 0.99923, bucket sigma max +5.5, one site at bit 9 at -448 sigma (the era-stride class on today's load_index, the record's own); (B) 256 of 256, 0 exhausted, r 0.716, (c''') 1.66 percent of candidates; (C) p4 1.2163x FLAGGED (+67.7 sigma bucket), p8 1.3787x, p10 1.5052x, p212 1.1917x (+91 sigma) FLAGGED, p225 1.2457x BEYOND the 1.2x gate, p15 and p34 PASS at 0.9999x, the hot set clear on all seven; the 16 seeds 2 of 16 done, both PASS, max 1.0064x. The per-pack pass line: (A) accepted with every site clear of 0.995; (B) 0 exhausted of 256 and r under 0.90; (C) every seed within 1.2x over the window model and no 6-sigma bucket outside the known-failed set, the known-failed set reading as it does here (the fold pack expected to move p212 and p225). Per pack one box, the next pack the other. Two defaults: the all pack's F8 point at 1,476,395,008 words needs the hash lane's DatasetGeom threaded through the tool (at 2^28 today), threaded after the three single-feature packs or named owed at 22:30; the 64 x 2^24 point per pack (45 to 100 core-hours) owed in every case, the 16 x 2^22 plus the known-failed set standing in. THE RX 7600 READ (the card-in run on PC 1, 15:46 to 15:50 BST; the detect script of 10:10 still switched the card through /api/cards before the morning's fix, so it ran the whole pass at once): the new key amd:gfx1102 "AMD Radeon RX 7600", 8,176 MB, discrete, the 9070 XT gone, the OpenCL device [1] gfx1102 on AMD-APP 3683.0 (a duplicate [3] on the older 3652.0 platform hidden); the class v5 and v4 fingerprints MATCH on the kit worker; the stock bench 13.88 MH/s at 113 W quiet (0.123 MH/W); the app's own row 13.4 MH/s at 113 W mining; the 1 GiB dataset fits. Per tier: an 8 GB AMD card at 0.123 MH/W sits level with the 9070 XT's 0.097 stock and 0.127 tuned, a quarter of a 5090's per watt; the knob grid (IGNEUM_GRID_CARD=7600) and the 2, 4 and 5.5 GiB rows follow on PC 1 behind the read-width run b (the grid about 16:50, the sizes and the ds55 rows by 17:40); the tier rows from the grid, to the denominator and UI lanes. Lane 5's landing state at 15:5x BST: the gate green on be21940f5; the "retains" verb with the research lane (the default: the review's text verbatim at 17:15; "adopts" re-gated as one word and landed by 18:00); the served link to the close points at the design document on master, so the landing waits for the research lane's master sha (its 17:00 line) and falls back at 17:30 to the branch path. The review's manifest order on the next branch (release-manifest-8, its gate running): site/release-manifest.json served at /release.json with the chain id (4464, 4463 below the floor), the node commit f8da7515 with the pin c9ad753a and acaf08b0 pending, igneum-pow 1c420786 with the freeze fingerprint, the mining class (v5 since DAA 68,400, v4 at genesis, the ladder at rung 0), the dataset parameters, finality rule v3 (two thirds of active and two thirds of total, the frozen table from checkpoint DAA 0), the SP1 program ids from the ELF manifest, the verifier off per P21, the fee schedule, the versions per platform with SHA-256, every block labelled; /build, /economics, /miner, /evidence and the litepaper's Devnet 3 line read from it at build (held by a new gate check); /light, /receipt and the light client now say two thirds of total weight; 4463 marked historical in spec 07 and six older docs; every dated /bench entry with a "Historical record of " line; the evidence page's sixth label "activated" and the reference-repository wording; landing after lane 5, before 19:30; the economics "who pays for proving" section by 21:00. The floor-sm amendment (66bc6ca7, the memory-clock ladder) landed as b1b8d833 at 15:57; the denominator amendment 6d0f11e5 about 16:07. THE AMENDED CLASS V6 CLOSE LANDED on master at 16:12 BST as cbf5aa46 (the merge of counter-asic-4 0c8a0625, full gate green 73, pushed to all three box mirrors), 48 minutes inside the 17:00 clock: docs/design/class-v6-rotating-family.md section 10: 10.0 the table; 10.0a the lifetime unit marked superseded; 10.0b the precedents sourced with the RandomX wording; 10.0c the sweep; 10.0d the rotation schedule; 10.0e the window with the card's cost MEASURED (within 5 percent per load, no spill, on a rented 5090 and 4090); 10.0f the first review's five corrections with lane 3's profitability surface; 10.0g the second review's seven; 10.0h the served text, the one word made honest with the audit lane ("Class v6 adopts the 64-register window and retains it across every rotation"); 10.0i the adversary's re-optimised core and the bracket the served figures sit in until the k lane's placed gated rows (17:30; the audit lane holds for them and serves once, 18:30 if late). The coordinator's earlier copy of the design file on master superseded in the merge. An amendment after the landing, on the branch for the next landing: the multi-family adversary lane's first core puts the 64-register window in a macro at k 0.40 node-for-node for the whole draw and reads that the window knob buys the card nothing against a macro file; the k lane's own SRAM-banked model says the opposite (8.5 to 10.5 pJ, not cheaper than its gated flops); carried as a disagreement the two lanes' placed rows settle (17:30 and 18:30), the served window line read as: measured cost under 5 percent, about 0.13 of k against a flop-file adversary, possibly nothing against a macro-file one. The multi-family adversary lane's first rows at 16:4x BST (synthesis only, ASAP7 TC, random-input gate-level VCD; the SRAM macro term modelled; node factors claimed): one in-order SIMD core with the 64-register window in an SRAM macro per 8 lanes and the imem in two macros, every unit operand-isolated, a 5-phase single-port slot, every bank entry as firmware (fold constants, select tree, shapes, W = 4, atoms as programs). The genesis-only variant (10 families, 8 lanes, 66,973 cells plus 3 macros) on the class v4 draw: 5.9 pJ per lane-op at ASAP7 (5.1 to 7.7), 4.1 at N5, 3.0 at N3; against the card's measured 10.3 pJ per op on the same draw at the 1,300 lock, k = 0.40 node-for-node (N5) and 0.29 a node ahead (N3); at stock 0.22 / 0.16. Per family at the lock (k N5 / N3): add, sub, xor, rotl, rotr 0.45 / 0.33; or 0.36 / 0.26; mul 0.32 / 0.23; mad 0.55 / 0.40; mulhi 0.12 / 0.09; shfl 0.083 / 0.060; the load with the fold 0.43 / 0.31. The whole-hash shadow at 102,612 ops: 0.42 µJ at N5, 0.31 at N3, so the GDDR7 board with this core reads 2.33 / (0.466 + 0.42) = 2.6x against the 5090 at its lock node-for-node (2.9x a node ahead), the 5080 at its lock 2.3x / 2.6x. Meaning: the adversary's re-optimised core (SRAM state, port time-multiplexing, operand isolation) sits 15 percent under the k lane's 32-register flop core and 40 percent under its 64-register flop core at the same node, so the 64-register window is not the robust knob it read as; the review's rule 5 holds. The full 18-family variant (95,678 cells, +43 percent) in the power step, the placed 8-lane core at CTS, the 32-lane cores in synthesis; six rented hosts, USD 1.2 an hour. The connected-state lane at 16:55 BST (class cs64s27x16, research, behind --class, never a chain class; branch class-v6-connected 69649ab45): a 64-register window per lane; per step a 4-byte load from a window register, then a block of 27 distinct instructions run 16 passes, the next address from the block's last instruction on a fresh spine, the result folding all 64 registers; 128 loads + 55,296 ALU per hash (v5: 128 + 55,680); text 448 per iteration (v5: 320). Liveness (seed igneum-v6c/0): 63 of 64 registers necessary for a later address at every one of the 128 addresses until the last iteration's tail, the result reading 64; per step an address depends on 1 to 15 registers of the previous address point (mean 11.2): the chain narrow per step, the whole window necessary over the hash; each block touches 16 to 24 registers, every register read 384 to 3,208 times and written 128 to 1,664 times per hash; a specialist must hold 64 x 32 bits live per lane and can bank them (about 20 hot per step, the set moving with the text). Census (the sub-version 3 harness, (c''') on): no era 256 of 256 accepted, 0 exhausted, 0.28 rejections per candidate (the control mx8+sh256x27 0.67), mean attempt 0.39 (control 2.0); eras 0 to 7 at 32 seeds each with the window-bit refusal on: 256 of 256, 0 exhausted, mean attempt 1.7 (control 4.9), 306 window-bit refusals (control 218): the product-bit class the layer-1 index fold removes, present as in v5; F8 form at 16 seeds x 2^20: the top 0.1 percent share 0.999 to 1.002 of the uniform control. GPU at stock on a rented 5090 at its 575 W cap (the class v5 nvcc harness, 250 batches of 2^24, both packs minutes apart): cs64 64.93 MH/s at 574.8 W against v5-genesis 65.30 at 574.8 W, energy per hash +0.6 percent (8.85 against 8.80 µJ in this harness); ptxas 80 registers per thread (v5 48), 0 spills, 24 resident blocks per SM; fingerprints cs64 ad0cec2a42c84aff, v5-genesis ae74193ddad19e19, vectors 3 of 3 PASS. Meaning: the window costs the card under 1 percent of energy per hash at stock, far inside the 10 percent budget, and a chip a 64-entry live file per lane. The 4090 row by 17:15, the PC 1 lock row owed (the bound emitter building); the k lane's score and KEEP or KILL at 18:00; connected-state.md with every row by 17:45. The 0.3.26 Windows entry live at 16:11:04 BST (installer 8e674bd5 from 1f4904e0, host-less, both folders and the public alias, read back live): EVERY PLATFORM ON 0.3.26 (Mac and HiveOS 16:02:53, Windows 16:11:04), the PCs by their update checks. The network: dn3-g1 refused dn2-1's branch at 16:06:55 with a genuine InvalidPoW after its full replay (dn2-1 sat in the held group and mined on 5b673577's object through the stall, so its branch's state past e1f65284 and its epoch 21 reference are foreign to every f8da7515 node); the fleet's default taken at 16:12: the chain is p1-4090's branch (sink 486a7cb6, mined on c9ad753a's object from 14:50, under the epoch 21 line), its miner at its sink, the rest by IBD, the hubs as they converge, dn2-1 wiped after. The rule candidate for the next line (the node lane's reading asked): a held box never mines on the old object past a digest-moving minute. The denominator RX 7600 delta (29df04cf, denominator.md plus class-v5-tiers.json at 31 classes) landed as c3911a8c at 16:12; twelve research landings today. The class v5 lane's ask at 16:4x: no class v6 order had reached it (the shipper's relay named its items second-hand); the coordinator sent the order's text at 16:45 with the lane's item: the class v6 kit, the six-platform fingerprint read on the hash lane's class-v6 merge on the all-together pack, the known-failed case first (the plain-address pack reading a different id from the fold pack on every worker), the kit zip on build-1 with its sha by 23:00, the Arc and the AMD through the PC job runners, the Mac by the Mac chain; a miss means the kit ships tomorrow morning on the merge's last green commit with the platforms read so far named, and 0.3.27's pin waits on six equal reads. The enforced-proving lane (ledger P21) at 16:15: the test set and the full crate suites green on build-2 ahead of 18:30 (igneum-exec 64/64, kaspa-consensus 138/138, kaspa-consensus-core 171/171): a valid SP1 proof a condition of payment in consensus behind the named switch verifier_in_consensus, false on every compiled object (the live Devnet 3 object unchanged; igneum-testnet-1 gains the payment rule on its DAA floor 0; the class v6 object carries the switch true); six consensus-side and seven executor-side tests named per refusal, known-failed first; branches enforced-proving (b6a538b65: docs/spec/proving-enforcement.md, the P21 and P22 rows, the 60x switch listing, infra/fast-time/proving-enforcement.mjs) and enforced-proving-node (the fork, edf45887 plus one import fix, off acaf08b0 with f8da7515). The coordinator's word at 17:00: the main-repo branch lands on master through the gate now; the node commits take release-0.3.27-node, the line the node lane cuts from the class v6 object tonight, the branch tip and its suite lines to the node lane for the merge under the object's gate set; the verify-cost row by 20:00 (the stated 0.26 to 0.53 s cold verify per record labelled stated if no core by 19:00). The record's forty-ninth landing's merge gate killed by signal 15 twice more at 16:1x BST on the Mac (rule 4 refuses the class in scripts; a hand command still reaches it); the third run in the background. The three gate kills at 16:14:24, 16:17:20 and 16:18:15 BST found by the coordinator in the lanes' transcripts: the site audit lane's shell ran pkill -f "tools/ci/pre-push.sh" in its spec-accept-23 scratch tree each time, the kill-by-name class the CLAUDE.md rule forbids since 12:5x; the lane told to end its own gate by its pid file only; the record's forty-ninth landing re-run a fourth time. The steward at 16:33: the class v6 matrix on the node lane's first sha 617cb441 (class-v6-node, app tree 89e83df2, the class v5 freeze tree linked, the parent's 60x file at bf2c878d's three keys) started 16:33 on build-2 and build-3 at gate priority, seven suites each, the line by 16:55; the object commit's matrix the same way the minute its sha lands. IGNEUM 2.0, decided by the founder (main's relay stamped 17:45 and 18:2x to 18:3x on a clock two hours ahead of the Mac; the Mac read 16:28 to 16:36 BST): "this is now Igneum 2.0, Miner v2.0.0, the testnet is scrapped (the go ran, nothing mined, seeds stopped and held), Devnet 3 is the network", then at 16:3x everything off and the network restarting as the Igneum 2.0 devnet (igneum-devnet-4, node 2.0.0, fresh genesis, enforced proving from block zero; the shipper leads, the fleet and build-server lanes execute); the reference docs/plans/igneum-2.0-reference.txt with the pins in docs/plans/igneum-2.0.md ("This is your reference, always, do not stray"), landed on the box mirror's master as the first act by the build-server lane (72a5f9bd on build-server; the coordinator's own landing of the same two files failed its gate on the site sweep's live /swap render and was dropped). The plan's objective: durable GPU competitiveness, not chip destruction; the positioning line on every served page: "A GPU-secured network for Ethereum-compatible applications and verifiable computation"; the three boundaries wherever the proof architecture is explained; the standing rules carried in (more layers is not more resistance; rejected knobs stay out as regression controls; the adversary re-optimised after every change, synthesis k never a lower bound, placed rows score; the 10 percent GPU-cost budget set before results; "every chip dies within a family epoch" out of the baseline economic model, no chip-arrival percentages; no ASIC detection, whitelists, attestation, quotas or self-reported bonuses; rotation optional to the security argument; energy, economic and response capability reported separately, the cohort = the discrete-GPU population; mining resistance, proving competitiveness and system stability three questions). D1 the frozen reproducible baseline (the coordinator with the hash and node lanes; the pass: an independent operator reproduces it from the served kit alone); D2 two experiments (a) CLOSED by the connected-state lane's KILL (1.10x against the 1.25x gate; window width the one robust knob; rearranging the same ops moves nothing) and (b) memory sharing, recomputation and data-local execution against v6 (the adversary lane); D3 the programmable survivor chip (the adversary and k lanes; placed rows, the three-year life, the next-generation matrix, the dataset schedule scored per step, state coupling justified or dropped; 1.5x energy a research goal, not the pass); D4 the five-year coexistence model replacing the capex wall (the research lane; the sunk-dev-cost case mandatory; miners react; the tip-share discrepancy resolved); D5 the no-rescue network exercise (the node and build-server lanes on the three ex-testnet seeds; enforced proving the prerequisite); pools, architecture and product, versioning (Miner v2.0.0 from the 0.3.26 line; node 2.0.0 once enforced proving is on the network), the leadership tests (benchmarks against Ravencoin KAWPOW, Ergo and Firo's reference miner; the ranking ceiling "serious contention for the top of the GPU-mining space on engineering and operator proposition"), and the site reset (the served site starts at 2.0; site-pre-2.0 tagged; the facts page wiped; the FUD ledger written fresh with every entry naming its pin). THE DRAIN at 16:37 to 16:50 BST (the Mac's clock), ordered by the founder ("have we pulled all current jobs from all builders and boxes? and spinning up 2.0 work?"), read-back to main at 16:50 and accepted. Stopped by pid file: the attack pass's ten leases on build-2 (five F9 upper chunks, three F1 parts, the chunk-5 and parity waiters) and seven on build-4 (six F9 lower chunks, the F1 lower-range waiter), rows kept (F9 135,836 seeds, max attempt 32, 0 exhausted; F1 172,310 programs, one letter miss at 5.0781 percent, parity unread), the partial landing on attack-pass as lane (d) rows; the build-server lane's two bs0322 zigbuilds on build-2; the node lane's Devnet 3 monitors on build-1; the steward's 617cb441 matrix; the shipper's host-0326 preview on PC 1 and the 0.3.25 takes on PC 2; the acaf08b0 move withdrawn; release-0.3.27 superseded; every rented pod of the hash, size, knob, connected-state and mixed FP32 lanes destroyed. One reversal by main: the finality-boundary lane's two build-3 runs (the v3.mjs split50 harness and the N1B/N2B sim), which the coordinator stopped by pid at 16:39 under the drain's default, are KEPT under D5's partition row; the lane restarted them at 16:40 (pids 866903 and 866905, class measure, pool 4) with rule v4 and the measured N1 to N6 on branch finality-boundary (286cb43e8). Kept with pin: D1 on build-1 (the node lane's object checks and crossing), build-2 (the hash lane's window suite and re-exports, the enforced-proving crossing on local nodes), build-3 (the census's rw2 points, lane D's best-mix acceptance at widths 1 and 4), build-4 (the census's control and foldrw points), PC 1 (the read-width lock rows as controls, the 7600 grid, sizes and ds55 rows); D2(b)/D3 the adversary's six hosts; D3 the k lane's pods; the enforced-proving suites on 74803660 (the devnet-4 cut). Started with pin: release-2.0.0-node (the node lane, devnet-4), the seven-refusal re-run on the cut sha, the D2(b) harness on build-2's freed cores, the 2.0.0 matrix on release-2.0.0, the coexistence harness on build-4. The pool vote-key commitment design doc assigned by main to the attack-pass seat (a first complete draft by 20:00); the second-prover pin held (no box work tonight). The consolidated map to main at 16:58. The afternoon's rows under the new pins. The census sheet (D1): hl-v6-fold PASS (the program accepted, min site ratio 0.99986, bucket +5.25 sigma, worst free index bit 2.84 sigma, no site over 6 sigma against the class v5 control's -448 at one site's bit 9; the attempts census 256 of 256, 0 exhausted, r 0.701, mean attempt 2.34, max 14, (c''') 0.35 percent; F8 at 2^22 on p18 to p33 16 PASS at most 1.0455x; the known-failed set at 2^24: p4 1.0057x from 1.2163x, p8 1.1663x within the gate with a +6.58 sigma bucket from 1.3787x, p10 1.1868x from 1.5052x, p15 PASS, p212 1.0411x with a +27.3 sigma bucket from 1.1917x, p225 1.2414x BEYOND the gate unmoved (the value-level class, not an address bit), p34 1.0486x with a +11.9 sigma bucket the fold creates, the one regression): the fold does what it was drawn for, the four tail ratios fall from 1.22 to 1.50x into 1.01 to 1.19x, the stride-bit bias gone from the address, and against the class v5 control on the same 16 seeds (5 of 16 flagged on the 6-sigma windowed bucket) the fold's 0 of 16 is a measured gain. hl-v6-rw PASS (accepted, min ratio 0.99990, r 0.117, the lowest per-candidate rejection ever measured on the family, 256 of 256, 0 exhausted, max attempt 2, (c''') 0.34 percent; F8 at most 1.1526x; its 4 of 16 bucket flags at the control's own rate of 5 of 16). foldrw (accepted, min ratio 0.99993, no biased bit, r 0.117) and rw2 (accepted, min ratio 0.99990, two sites with the stride bit at -64 sigma as expected without the fold, r 0.410, (c''') 1.15 percent) with their F8 points queued; hl-v6-win not yet on build-1; the all pack's 5.5 GiB geometry in the f8 tool, untested. The hash lane's D1 line: the window hand's suite and the hl-reg64c and hl-v6-win re-exports on build-2; PC 1 in order the read-width run b, the 7600 knob grid, the 7600's 2 and 4 GiB sizes, the 5.5 GiB rows on the 7600 and the 5090 (the 5090's 1,300 MHz row at 5.5 GiB = the PC 1 lock row), then the cs64 row at the tail. The research lane's third close landing d6bee526 at 16:38 BST (10.0m the adversary's whole-machine rows; coexistence-model.md as its own file, the sunk case first: the GDDR7 board passes all six conditions at a one to three year life, the N2 SRAM die fails five once built, the only condition holding it that nobody pays to build it; 10.0n the three statements re-read: energy whole-machine per tier, economic from the model with capex per accepted hash the main term, response capability as versatility not life), its second landing fc1f9b62 at 16:26 (10.0l the objective and the claim statement), and 10.0o on the branch: the mixed FP32 candidate KILLED (determinism bit-exact on CUDA and the CPU across three cards; the determinism tax the whole economics: +14.8 percent energy per hash for fp12 on the 5090, +19.0 on the 4090, +26.5 for fp24, against about 7 percent of chip edge, the operand confinement integer work at integer k; the exponent-byte bias on address bits 23 to 30 a new instrument reading worth a layer-4 rule; FP32 a negative control; docs/analysis/class-v6/mixed-fp32.md on class-v6-mixedfp 255be026). The app window audit lane: the window rebuild ebb20c46 already an ancestor of release-2.0.0 b891444f and 0.3.26's 1f4904e0, so the v2.0.0 clock starts from b891444f; its record on master at c86a7e23. The site audit lane: spec-accept-23 and release-manifest-8 landed as 2966599e at 16:33 (the chip serve with the claim statement and the bracket, /release.json, the economics proving section) and tagged site-pre-2.0 at 16:35, the pre-reset state closed; the reset on three branches (site-2.0-lite, site-2.0-pages, site-2.0-facts) on main's clocks: the wipe 17:15, the facts and ledger 17:45, the litepaper and positioning 18:00; its gate moved to build-2 under /srv/builds/_site-gate; the Devnet 3 manifest regeneration and the 2.1x placed-row swap stopped as superseded. The shipper: the copy pass its own hand (the session's concurrent-subagent cap of twenty reached, so no opus hand spawns from any lane until one closes): the About and footer positioning line, proving on NVIDIA against mining on AMD and Apple, "the Igneum 2.0 devnet" wherever the app names the chain, the engine's network move to igneum-devnet-4 with the testnet choice gone, on release-2.0.0 by 17:05; the readiness clock to main at 17:00 on the UI lane's network step 17:10, the update-return lane's prover-host install 17:20, the devnet-4 node artefact 17:15, the chain about 70 minutes behind the last. The attack pass's partial on the mirror's attack-pass at d7943c8a (feature gate GREEN, 16:4x BST): F9 206,980 new seeds (306,980 with the record), 0 exhausted, 0 panics, max attempt index 37 (seed 421302; 718097 at 32); F1 217,310 programs, 0 mismatches, TWO letter misses at 5.0781 percent (attack-f1/392513 and 865158, both 13 of 256, the v4 miss's exact saving; rate 9e-6, the v4 rate), parity owed and not made, both named for the D1 harness on the class v6 generator; both boxes clear of its leases; the seat takes the pool vote-key commitment design doc (docs/design/pool-vote-key-commitment.md on master by 18:30, the sha and the surviving attack to main). Main's three additions to the map at 17:1x: D1 includes the spec (docs/spec/01-lottery-hash.md at 0.2 of 4 October, generator v2; the node lane re-cuts section 01 to the frozen object with the five digests in the 23:30 landing); the pool lane's 0.3.20 branches rebase whenever that lane next answers; the second-prover pin held; the finality lane's two D5 leases wait on build-3's pool, and at 17:30 the census's lowest-priority F8 run moves to build-4 to free them. Every active lane mapped and told by 17:16: the hash lane D1, the census lane D1, the node lane D1 and devnet-4, lane D D1 (the acceptance) with the rotation prototype paused, the k lane D3, the adversary lane D2(b) and D3, the research lane D4, the enforced-proving lane the devnet-4 cut, the steward the 2.0.0 gates, the site audit lane the site reset on main's three clocks, the reference-apps lane compatibility, the attack-pass seat the pool design, the finality lane D5, the shipper versioning and the devnet-4 move, the build-server lane execution and deploys. A SHARED-DEVNET FACT FROM THE FLEET (not this lane's, with the shipper and the infra lane): the Hetzner live seed 188.245.5.161:26611 is still on the old override object (digest eada4bda) 1 h 40 min after the 0.3.20 sweep (the fleet never touches Hetzner nodes, so it was outside the sweep); the 0.3.21 wipe canary c22-1 took five digest-mismatch rejects from it; an app with the packaged peers is refused at the seed and syncs through node1 and the hub only, a fresh joiner with only the seed cannot join, the 14 voters and the hub are unaffected; the owner puts the floor file ov16-floor-900000.json (sha 294f1f80) and the c4459193 pin on it. 0.3.21's STAGING (the node lane): the order dry-merges onto 55768f88 with nothing moving to 0.3.22; the late-join fix is 52e96c94 (70e4601e rebased onto 55768f88, exec suite 33 green with both new tests); f067f7c1, b0444f51 and 437f0438 merge clean in order; 2e32d5f6's one conflict (DST_ADDRESS beside pool-finish's DST_BINDING in consensus/core/src/finality.rs) kept both; the live-file digest eada4bda after each (every switch at never); the staging waits on the shipper's sweep-end word; the re-pin held. PC 2 DOWN AGAIN (main, 16:5x UK): the founder takes PC 2 down for cable work (PC 1 back but his desk); both PCs out of the sweep's waves, each updates on its poller on return; no PC job to PC 1; the Windows G1 completed before the outage, nothing reruns. 0.3.21's SECOND GATE LINE on 55768f88 (sha256 279b1b690e854fc9): the ten-minute mixed-version gate beside the 5899f603 pair, 13:37:40Z to 13:47:52Z, SUMMARY PASS (one digest b0afb2ee on five nodes; 223 new and 381 old blocks accepted by the old hub, 0 rejected; counts equal at 319, 486 and 604 through both clean joins and the restart step at 13:45:22Z; no panic); the node lane's two lines on 0.3.21's first candidate complete, in plan 6.9 on ca3-v4-node; the fleet's set on it (the bare-child 12 GB line, the wipe, the kept read, the cases) is the fleet's. 0.3.21's FIRST GATE LINE on 55768f88 (sha256 279b1b690e854fc9, the string read back; pairing igneum-pow 8c728ca3 at byte 5): the digest gate 13:35:41Z to 13:37:19Z SUMMARY PASS (a89be8a7 on both binaries with the peers; db9a85f9 refused, no peer; the live file's eada4bda unmoved); the ten-minute mixed-version gate from 13:37:40Z, line about 13:50Z. The 0.3.21 order as the shipper sent it: 55768f88; f067f7c1 and 70e4601e; b0444f51; 6eb21fc9; db28d331; then the re-pin from 8bdcbdd8 on the coordinator's word; suites between, the digest read after every one; the mirror's release-0.3.20-node back at the pin c4459193, release-0.3.21-node open at 55768f88. THE LATE-JOIN COMMIT (N9's second half, the node lane): 70e4601e on the box mirror as branch proof-hold-fix, from c4459193, two files (igneum/exec/src/proving.rs, protocol/flows/src/v10/proving.rs); the gap was the fetch side on the joiner (the served record ran the native check against the joiner's trailing exec state before anything was stored, the check refused it, the proof was never held, the body rule read "not held" for 20 s and failed the IBD); the fix holds the proof by hash before the checks (the pool entry still needs them) and the serve side says when it holds fewer than asked; the exec suite 32 passed at 13:26Z with the known-failed shape first, the flows check green 13:28Z, igneumd on build-1 at the 0321 worktree path built 13:32Z, sha256 17649eeb2f7d1290, string read back; with the testnet lane (the resume form, B alone); it joins the 0.3.21 staging as its own commit. THE WIPE CANARY ON c19-1, c4459193 (sha 45be9b02d1b002f5, string read back): FORM END rc 0 at 13:50:53Z. Wipe synced 13:35:50Z (57 minutes, inside the 98-minute class); mining 13:36:00Z to 13:47:07Z, 66 mined, 66 accepted, 0 rejected, isSynced true at the tip throughout; the hub holds 41 of its blocks in its last 700 with 0 rejects (13:47:09Z); the restart on its kept datadir at 13:47:15Z: the old process stopped at once (the new process's first lock line seven seconds after the marker; the watchdog held nothing, the b7cc37e7 fault closed), synced again at 13:48:39Z after 84 s, 109 templates read with max 3,432 ms and 0 timeouts; the kept read on pool-1's 0.3.17 copy on the same pod passed at 13:38Z (the rewrite line once, a clean second start). The pin's set on c4459193: the digest gate PASS, the mixed-version gate PASS, the wipe canary PASS, the kept read PASS, the restart PASS, the 12 GB line proves and verifies (paid is a race, not a gate); CASES END from c20-1 (about 14:50Z) is the last pin line. THE INTEROP FACT stands from the void run: the 5899f603 hub accepted 235 object-byte-5 blocks from the 8097d600 node with 0 rejected, one digest on all five nodes on the live sixteen-field file. The gates: the digest test and the kaspa-pow vector test (the amended devnet epoch-0 id 1a4230699a6b9c60 must equal, c120d7963abdcd96 must differ, the v3 control unchanged) on the box; the mixed-version Devnet 2 gate (the amended 0.3.20 node beside a 5899f603 node for ten minutes on the live file without the v4 fields) after the Mac build; the fresh-join canary the 0.3.20 cut's | | Main's rulings (7 October, morning) | no generator change to v4 on the live devnet; the record's null is the window model with numbers, sent by the hash lane to the attack-pass lane so AP-F8-1 re-gates against it; a fault beyond the model (a low-entropy source at site 15) stops at the coordinator with the two options priced (a 0.3.19 class amendment before the flip, or the flip held at the floor), nothing shipping without the founder's word; the tighter tail, an acceptance bound on the hot-set share, is a CLASS V5 item (sent to the v5 lane a6410f3b8abefb762 with the 64-seed census as its gate; the bound's number follows from the model) | ### AP-F4-1, the weak-day MUL draw (the attack-pass lane, 7 October, morning): PASS against v4, a class v5 rule diff --git a/docs/plans/igneum-2.0-reference.txt b/docs/plans/igneum-2.0-reference.txt new file mode 100644 index 000000000..d23b64a25 --- /dev/null +++ b/docs/plans/igneum-2.0-reference.txt @@ -0,0 +1,132 @@ +INGEUM 2.0 


Yes—if the programme delivers the independently verified results we defined, my judgement is that Igneum would belong in the top tier of GPU-first mining projects, with a credible case for technical leadership. +That is different from automatically becoming the largest, most profitable or most trusted GPU network. You can engineer a leading system; adoption and sustained demand still have to follow. +The distinction is between shipping the proposed changes and demonstrating that they achieve the objective. The latter is what would earn that position. +Where successful execution would put you +Area +My assessment of the proposed end-state +Keeping ordinary GPUs competitive +A potential leadership position, provided independent hardware analysis confirms the result against programmable, multi-epoch competitors. +Quality of the resistance evidence +A major strength if you publish reproducible measurements, realistic adversarial designs and economics that do not assume chips automatically expire. +Miner experience +Potentially top-tier: straightforward installation, effective tuning, transparent earnings, reliable payouts and retained control. +Usefulness of the hardware +A compelling proposition if the same accessible hardware can earn from genuinely purchased proving work as well as securing the chain. +Security and decentralisation +A credible contender after independent review and failure testing—not something a feature list establishes. +Miner profitability and market leadership +Still dependent on demand, competition, liquidity and operating costs. These cannot be guaranteed by protocol design. +The strongest potential advantage is the complete package—not one supposedly unbeatable hash. +You would be competing with serious projects +The space is not empty, and I would not claim Igneum had surpassed these projects merely because its design is newer. +Ravencoin already expresses a closely related objective. Its KAWPOW approach is intended to keep consumer GPUs competitive, explicitly allows for future ASIC development, and does not envisage further algorithm forks as the normal defence. Igneum would need to demonstrate a stronger result or a more valuable overall offering—not just restate that goal. +Ergo already has a GPU-oriented, memory-hard mining design, with implemented changes to pooling, emissions and difficulty adjustment. That gives you an operating system to benchmark against, rather than merely a competing whitepaper. +Firo is actively improving commodity mining accessibility. Its September 2026 reference-miner release supports NVIDIA and AMD, charges no developer fee, and reports performance within roughly 1% of popular closed-source alternatives. That performance figure is Firo’s own report, but it illustrates the practical standard Ember would need to meet. +Those are useful reference points, not an exhaustive league table. They also show why “GPU-friendly” is the entry requirement, not sufficient differentiation. +What could make Igneum stand out +Your proposed combination is more interesting: +Competitive commodity mining + application execution + verifiable proving + an accessible operator application + meaningful miner control. +The litepaper already frames mining, proving and Ethereum-compatible execution as separate but connected parts of the system. The opportunity is to make that combination work reliably and economically—not simply to have more features than another chain. +For a miner, the strongest proposition would be: +“My hardware remains useful and competitive, I can earn from more than the mining subsidy, and I do not have to surrender control to participate.” +For a customer buying proofs: +“I receive a correct result at a competitive price and reliable delivery time, without needing to care which independent operator produced it.” +Deliver both, and Igneum would have a strong reason to exist beyond attracting miners from another coin. +However, the proving-income distinction matters enormously. The current economics page describes internal proving payouts on a valueless devnet and says the external proving market is not yet built. Internal reward distribution demonstrates the mechanism; repeat purchases by outside customers would demonstrate demand. +What separates “top-tier technology” from “the leading network”? +I would look for three outcomes. +Miners stay through difficult conditions. Not because the launch is temporarily lucrative, but because hardware compatibility, operating costs, payouts and control remain attractive. +Customers repeatedly pay for the output. Not subsidised pilots or partnership announcements: useful work purchased at prices that support reliable service and operator margins. +The network works without the founding team holding it together. Independent operators build the software, enforce the rules, survive failures and continue operating without emergency intervention. +Those would be my tests for leadership. A small specialist-hardware advantage alone would not establish any of them. +My direct answer +The ceiling is category leadership. Successful, independently validated execution would put Igneum in serious contention for the top of the GPU-mining space on engineering and operator proposition. +But I would not give it an unsupported “number one” ranking before comparative results and real-world adoption exist. +The progression I would expect is: +Demonstrated technical advantage → credible top-tier project → repeat customer demand and miner retention → potential category leader. +You have a plausible route to the top. The decisive move is now to prove that ordinary operators can succeed on the system—not to make the design sound more ambitious. +


Yes—EVM-compatible applications with ZK-proven execution are the right default for Igneum. But I would position and build it as a GPU-secured L1 with a flexible proving layer, not simply “another zkEVM chain.” +The architecture I would choose is: +EVM for developers. A general-purpose zkVM for proving. Igneum’s own consensus for security. External customers for additional proving demand. +Those choices fit together, but they are not the same decision. +1. Separate the three architectural choices +Decision +My recommendation for Igneum +Why +What developers build against +EVM-compatible execution +Let builders use familiar contracts, languages and tools rather than requiring them to learn a new application platform. +How execution is proved +An established general-purpose zkVM, initially your SP1-based implementation +Prove the EVM implementation without developing an entirely new proof system yourselves. Preserve a carefully versioned replacement path. +Where the network obtains consensus and finality +Your sovereign GPU-mined L1, subject to the security gates we discussed +This preserves your actual objective: an independent network secured by accessible hardware, rather than a proving service attached to someone else’s settlement system. +Your litepaper already points broadly in this direction: it identifies revm for EVM execution and SP1 behind a versioned proving interface. I would refine that architecture rather than restart it. +A zkVM and a zkEVM are not competing choices here. SP1 proves programs compiled for RISC-V; one such program can implement EVM execution. Succinct’s RSP project demonstrates this composition using Reth and SP1, although that repository explicitly warns that it is not audited or production-ready. +2. Why EVM is a sensible application layer +I would not make attracting developers harder while you are already solving difficult mining, consensus and proving problems. +EVM compatibility lets developers reuse familiar languages and infrastructure. Ethereum’s documentation identifies precisely that benefit: applications can use established tooling while gaining proof-based verification. +For Igneum, my preferred developer experience would be: +“Deploy familiar contracts, understand a small, clearly documented set of differences, and obtain verifiable execution.” +That is a stronger starting point than asking developers to adopt a new language, wallet model, execution environment and security model simultaneously. +However, compatibility needs to be demonstrated, not described as “everything runs unchanged.” Your ledger already acknowledges differences in block context, randomness and two-dimensional fees. Those can matter to application behaviour even where the bytecode executes successfully. +I would therefore make compatibility testing a product deliverable: representative contracts, wallet fee estimation, indexing, failed transactions, receipts and application-specific assumptions. +3. ZK-proven execution is also aligned with where the technology is going +This is not a case of choosing an architecture whose only purpose is Ethereum rollups. +The Ethereum Foundation’s current zkEVM programme is working towards proof-based verification of Ethereum’s own L1 execution, beginning with optional execution proofs and aiming later for mandatory proofs. Its approach explicitly involves general-purpose zkVMs. +That supports your architectural direction: +Keep a familiar application environment, while changing how execution is verified. +It does not establish that Igneum’s implementation is secure or that customers will choose it. It does mean you can build on a substantial shared engineering direction rather than invent every component. +My recommendation is to benefit from that work while concentrating your own effort on what is distinctive: accessible operators, distributed proving, reliable payments and the GPU-mined base layer. +4. I would not turn Igneum into an Ethereum L2 by default +Using EVM execution and ZK proofs does not require moving Igneum “onto Ethereum.” +A conventional Ethereum ZK-rollup uses Ethereum to enforce state updates and make the necessary state-reconstruction data available. That is a different security and settlement arrangement from operating a sovereign L1. +An L2 could be the better choice for a project whose primary objective was Ethereum settlement and an Ethereum-facing application. But it would not automatically be a better implementation of your objective: an independent, durable home for GPU operators. +There is a real cost to choosing sovereignty: you must establish your own consensus security, data availability and credible cross-chain verification. Adding execution proofs does not make those responsibilities disappear. +My preferred commercial relationship is: +Serve Ethereum and other networks without requiring Igneum to become subordinate to one of them. +Customers should be able to purchase supported proofs for their existing systems. Requiring every customer to migrate its application to Igneum would unnecessarily narrow the business. +5. The proving business should be broader than your own zkEVM +This is the most important strategic refinement. +Make EVM the main application interface, but do not make EVM execution the only useful work your proving infrastructure can eventually support. +A general-purpose zkVM gives you a potential route to additional verifiable workloads. It does not make every proof format interchangeable: each supported service still needs its own validated program, inputs, verification rules, performance measurements and delivery requirements. SP1’s general-purpose execution model supports that broader direction. +I would start narrowly: +First: reliably prove Igneum’s own execution. +Next: support one external customer’s exact workload, with repeat paid jobs. +Then: add further workloads where the existing operator fleet has a demonstrated advantage. +Your economics page still describes the external proving market as unbuilt. That is an opportunity to shape correctly—not established demand that should already be included in revenue assumptions. +Igneum should not need to win a contest for the largest application ecosystem before its operators can sell useful computation. +6. The conditions that make this the right choice +I would keep this architecture only while enforcing four requirements. +Proofs must become a protocol guarantee +Your ledger currently states that proof verification occurs outside the consensus path in proving v0; a modified producer can include a matching statement without the valid proof and cause an undeserved payout. +Closing that gap is essential. Otherwise, the network is demonstrating proving activity rather than enforcing a permissionless proving economy. +The hardware requirements must match the miner promise +The litepaper currently distinguishes NVIDIA proving from AMD and Apple mining support. That is an important limitation to preserve in the product language. +I would judge the proving stack on the complete pipeline: inputs, proving, aggregation, verification, payment, memory footprint and mining income forgone. +A fast shard result is not sufficient when aggregation or memory pressure makes ordinary operators uncompetitive. +Proof-system flexibility must not become arbitrary acceptance +Keep the implementation replaceable, but pin the permitted program identities, verifier versions and security parameters in the protocol. +My recommendation is one well-tested backend first, a clean replacement interface, and independent implementations where justified later—not several immature backends accepted interchangeably. +The Ethereum Foundation’s security work emphasises that proving speed is insufficient without soundness analysis and appropriate security margins. That is directly relevant to deciding which optimisations and versions Igneum can safely adopt. +Proving must not become the authority to control the chain +I would preserve your separation between winning the mining lottery and producing proofs. +But also test whether a concentrated proving provider could stall useful operation by withholding service. The design needs replacement operators, usable inputs, reassignment and explicit behaviour during proof delays. +Separate responsibilities on paper are not enough; they must remain separable during a failure. +7. What “zkEVM” should—and should not—mean in your positioning +I would not lead with: +“We are another zkEVM.” +I would lead with: +“A GPU-secured network for Ethereum-compatible applications and verifiable computation.” +Then explain the proof architecture underneath it. +Also keep three boundaries explicit: +Proven execution is not automatically finality. +EVM compatibility is not Ethereum security. +ZK technology does not automatically make transactions private. Ethereum’s rollup documentation explicitly notes that published state-reconstruction data is public; privacy requires additional application or protocol design. +And none of these choices, by itself, solves specialised-hardware competition. Your mining-resistance programme remains a separate obligation. +My judgement +Yes: stay with EVM-compatible, ZK-provable execution. I would not switch to a new application VM, develop a bespoke proof system, or convert Igneum into an Ethereum rollup just to follow a category label. +The strongest architecture for your stated purpose is: +A sovereign GPU-mined L1, familiar EVM applications, an established and versioned zkVM proving engine, and a proving service capable of serving customers beyond Igneum. +EVM is the right front door. Verifiable computation is the broader opportunity. Keeping ordinary operators competitive is the differentiator you still have to prove. \ No newline at end of file diff --git a/docs/plans/igneum-2.0.md b/docs/plans/igneum-2.0.md new file mode 100644 index 000000000..7a4bb1e72 --- /dev/null +++ b/docs/plans/igneum-2.0.md @@ -0,0 +1,146 @@ +# Igneum 2.0 + +Decided 8 October 2026, 17:45 BST. The testnet is held (go cut acaf08b0 never ran; the three seeds idle for D5). Devnet 3 is the network. The miner line restarts at v2.0.0. Everything below is a pin: a box, an owner, a pass condition. A pin closes only with a landed document and the pass condition met, never with a plan. + +## The objective + +Durable GPU competitiveness, not chip destruction. Four properties, all holding without assuming a future emergency algorithm change: + +1. A specialised miner cannot remove much cost without losing substantial performance. +2. Ordinary operators can obtain competitive hardware, software and access to rewards. +3. Mining and proving stay economically sustainable as the network grows and issuance falls. +4. The above hold with no rescue upgrade assumed. + +A manufacturer with a profitable product is not the failure. An exclusive, durable advantage large enough to displace the accessible GPU fleet is. The target is contestable mining. + +Positioning line (served text, every page): "A GPU-secured network for Ethereum-compatible applications and verifiable computation." Never "another zkEVM". Three boundaries stated wherever the proof architecture is explained: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. + +## Standing rules carried in (do not re-decide) + +- [ ] More layers is not more resistance. A smaller generator whose every accepted program is strong beats a larger one with occasional weak programs. +- [ ] Rejected knobs (long programs, select trees, W=8/W=32, SM count, memory clock) stay out and stay as regression controls. Never resurrected under new names. +- [ ] The adversary is re-optimised after every change. Synthesis k is never a lower bound; placed rows score. +- [ ] GPU-cost budget is set before results (10 percent at the lock). No ratio is bought with honest GPU energy. +- [ ] "Every chip dies within a family epoch" is out of the baseline economic model. Chip-arrival percentages are not published. +- [ ] No ASIC detection in consensus. No hardware whitelists, attestation, per-address quotas or self-reported GPU bonuses. +- [ ] Rotation is optional to the security argument. Seed delay is evaluated only as seed-selection protection. +- [ ] Energy advantage, economic advantage and response capability are reported separately. Cohort = the discrete-GPU population, used cards included. +- [ ] Mining resistance, proving competitiveness and system stability are three questions with three answers. + +## D1. A frozen, reproducible baseline + +Owner: coordinator (Counter ASIC 3.0) with the hash lane and the node lane. + +- [ ] One exact generator, verifier, dataset policy, compiler configuration and measurement harness, pinned by digest and served. +- [ ] Pending measurements closed: placed 64-register rows, PC 1 lock row, 5.5 GiB coexistence rows. +- [x] Mixed FP32 branch: KILL 8 Oct 16:3x. Deterministic FP32 costs the cards 15 to 26 percent energy per hash against a 10 percent budget (four fifths of it the integer masking that keeps the FP unit deterministic) and the chip's edge grows to 3.0x to 3.2x because that masking is ARX work it pays at the floor. Document: docs/analysis/class-v6/mixed-fp32.md. Regression control, never resurrected. +- [ ] Mining and proving measured together on the final configuration, not combined on paper. +- [ ] Wall power alongside device telemetry; accepted work, rejected work, compile time, memory use, sustained thermals. +- [ ] Reference GPU population published: several vendors, memory sizes, generations, used cards (5090, 5080, 4090, 3090, 9070 XT, RX 7600 8 GB, Arc, Apple). +- [ ] Two tests per class: existing owner (power, wear, fees, alternative use) and new entrant (purchase, operating, resale). +- [ ] Central measure served: cost per accepted unit of work = (annualised hardware + power + hosting, failures, fees) / annual accepted work. +- Pass: an independent operator reproduces the baseline within declared tolerances from the served kit alone. + +## D2. Two architectural experiments, not twenty knobs + +Owner: class v6 invention lane (a) and the multi-family adversary lane (b). + +- [x] (a) Reorganise existing work for unavoidable live state and resource coupling, counts held constant. RESULT 8 Oct 17:25: KILL as a class. Only the window width reaches the chip (+1.2 pJ per lane-op at N5); rearranging the dependency graph of the same ops moves neither side. Document: docs/analysis/class-v6/connected-state.md. The generator variant and liveness tool stay behind a flag. +- [ ] (b) Attack memory sharing, recomputation and data-local execution against v6 (ProgPoW review threat: dataset split across processors, compute moved to the data). Price the cheapest combination of moving state, moving data, recomputing and local resources, not the expected architecture. +- [ ] Cumulative memory complexity and bandwidth hardness mapped onto the actual evaluation across many hashes (shared datasets, partial caches, recomputation, multiple engines amortising setup). Which trade-offs are bounded, which rest on physical-design experiments. +- [ ] Selective participation: distribution of the specialist's advantage across programs and epochs, not the mean; downtime, difficulty adjustment, re-entry included. +- [ ] Cryptographic review of the template, nonce, expensive work and result binding: no expensive intermediate reused across cheap winning attempts. +- Pass: the candidate improves against re-optimised adversaries across the declared population within the preset cost and verification limits. Otherwise v6 stands and the experiment is published as a failure. + +## D3. A programmable adversary allowed to survive + +Owner: multi-family adversary lane with the k lane (shadow k from RTL). + +- [ ] Whole-system cost minimised across every published family, free to change lane count, register implementation, instruction storage, memory technology, scheduling and support hardware. +- [ ] Physical implementation (placed), not logic synthesis. Uncertainty published with every row. +- [ ] Three-year stress life for the programmable chip; survival across the family bank assumed. +- [ ] Next-generation opponents in the matrix: programmable compute without graphics (Vortex class), chiplets and 3D packaging (UCIe), denser external memory (24 Gb GDDR7 boards), data-local hybrids, proof accelerators (PipeZK class), an operator combining mining and proving devices. +- [ ] Dataset schedule (5.5 / 8.5 / 11.5 GiB) scored per step: adversary burden against commodity burden (cards excluded, mine-and-prove lost, replacement cost). A step that hurts ordinary operators more than an adaptable adversary is rejected. Default: epoch-defined bounded dataset with a conservative published support horizon. +- [ ] State coupling of the dataset justified or dropped after sync, recovery, storage and adversarial state-growth costs. +- Pass: the best supported cost and energy advantage sits inside the chosen competitiveness envelope, with uncertainty published. 1.5x energy is a research goal, not the pass criterion. + +## D4. A five-year coexistence model + +Owner: research lane (economics), with the k lane's rows as input. + +- [ ] Replaces the capex wall. Mandatory stress case: development already paid for; the opponent covers manufacturing, deployment and operation only. +- [ ] Growing and shrinking networks, reduced issuance, cheap and dear electricity, GPU replacement and resale on both sides, changing proving demand, private mining and hardware sales, several productive lifetimes, cheaper derivative chips. +- [ ] Miners react: no fixed market shares. +- [ ] Outputs: cost advantage, replacement economics, accessible supply, break-even electricity price per class, supplier and operator dependence. +- [ ] Tariff advantage shown separately from hardware advantage (the 6.25x illustration). +- [ ] Economics page: the tip-share discrepancy resolved; explicit user-funded proving payment with congestion pricing, burn treated separately; hard cap and no development tax kept. +- [ ] Profit-maximising operator simulation: mine, internal prove, external prove, off; under a proving demand spike, a token price fall, a major prover leaving, a specialised entrant in either market. Pass if pricing and capacity rules restore service without an administrator. +- Pass: the model names credible conditions for sustained commodity participation and names where it fails. A result needing a small network, token appreciation or scheduled ASIC death has not passed. + +## D5. A no-rescue network exercise + +Owner: node lane with the build-server lane (the three ex-testnet seeds are the start). + +- [ ] Prerequisite: proof verification enforced in consensus (verifier_in_consensus, proof_rule_active_from) live on the exercise network. +- [ ] No founder-operated mining, proving, aggregation or mandatory distribution infrastructure. +- [ ] Cross epoch boundaries, interrupt signing, partition the network, remove major operators, hostile proof submissions, independently written clients. +- [ ] A withholding concentrated prover: replacement operators, usable inputs, reassignment, explicit behaviour during proof delays. +- Pass: specified behaviour with no emergency algorithm change and no privileged intervention. + +## Pools, software and participation (launch requirements) + +Owner: pool lane. + +- [ ] Vote keys stay with the miner at protocol level: the member's retained voting key committed into its work, payment aggregation separate, verifiable, pool identity substitution resisted. +- [ ] Non-custodial payouts, practical minimum payouts, local work verification, low-bandwidth participation (P2Pool as precedent, not code). +- [ ] Accepted-work penalty measured for home internet against datacentre connections. +- [ ] Optimisation work, compiler settings and safe tuning logic published; Ember reaches good operating points without third-party software. + +## Architecture and product (review 2) + +Owner: node lane (protocol), reference-apps lane (compatibility), second-prover lane (backend policy), site lane (positioning). + +- [ ] EVM-compatible execution for developers (revm); SP1 as the one well-tested proving backend behind the versioned interface; sovereign GPU-mined consensus. Not an Ethereum L2. +- [ ] Program identities, verifier versions and security parameters pinned in the protocol. One backend first; a second only where justified, never interchangeable immature backends. +- [ ] Compatibility as a product deliverable: representative contracts, wallet fee estimation, indexing, failed transactions, receipts, application assumptions; the documented set of differences (block context, randomness, two-dimensional fees). +- [ ] Hardware language kept honest: NVIDIA proving against AMD and Apple mining; the full pipeline judged (inputs, proving, aggregation, verification, payment, memory, mining income forgone). +- [ ] Proving business ladder: own execution; one external customer's exact workload with repeat paid jobs; further workloads only where the fleet has a demonstrated edge. The external market stays out of revenue assumptions until built. +- [ ] Every served page carries the positioning line and the three boundaries; "zkEVM" appears only under the architecture explanation. + +## Versioning + +- [ ] Miner v2.0.0 cut from the 0.3.26 line with the audit's window rebuild, the 2.0 served text and the baseline kit digest. Three-part versions, canary gate, one-box rollout, commit-string read-back, as before. +- [ ] Node 2.0.0 follows once D5's prerequisite (enforced proving) is on Devnet 3. + +## Leadership tests (review 3) + +Owner: main. These are the tests the site may claim progress against, never completion without the evidence. + +- [ ] Benchmarks published against operating systems, not whitepapers: Ravencoin KAWPOW (same stated objective), Ergo (GPU memory-hard, live pooling and emission changes), Firo's reference miner (NVIDIA and AMD, no developer fee, within about 1 percent of closed miners: the bar Ember meets or beats). +- [ ] Miners stay through hard conditions (compatibility, operating cost, payouts, control), measured, not launched. +- [ ] Customers repeatedly pay for proofs at prices that carry reliable service and operator margin. Pilots and announcements do not count. +- [ ] The network runs without the founding team: independent clients, rule enforcement, failures survived, no emergency intervention (D5). +- [ ] Served ranking language: "serious contention for the top of the GPU-mining space on engineering and operator proposition" is the ceiling; no "number one" claim before comparative results and adoption exist. + +## Site reset + +Owner: site lane. + +- [ ] The served site starts at Igneum 2.0: no 0.x release history, no changelog before 2.0, no Counter ASIC 2.0 / 3.0 / 4.0 names, no testnet pages or links, no old-version evidence rows, no status-log history. +- [ ] The pre-reset site is tagged site-pre-2.0 on the box mirror; the repo keeps everything, the site serves none of it. +- [ ] Devnet 3, the explorer, the faucet and the reference apps stay: they are the network, not history. +- [ ] Every page carries the positioning line; the miner page serves v2.0.0 when it is cut and nothing older. +- [ ] The facts page is wiped: it restarts with only 2.0 facts, each traceable to a landed document. +- [ ] The FUD ledger is written fresh against this brief: every entry names the pin it answers; the old ledger and its decisions stay in the repo as history and are not served or linked. +- [ ] Copy sweep beyond the site: the litepaper and the apps (miner, wallet, Windows host, HiveOS card) are edited to the 2.0 reference where the text differs from it (positioning line, three boundaries, EVM + SP1 + sovereign consensus stated as three decisions, NVIDIA proving against AMD and Apple mining stated plainly, no rotation-as-defence claims, no chip percentages, no 0.x history, no testnet). Dataset state-coupling in the litepaper is marked "under evaluation (D3)" until justified or dropped. + +## The four deliverables the site may frame itself around + +| What we deliver | Why it matters | +|---|---| +| GPUs remain economically competitive against realistic specialised hardware | Miners invest without depending on emergency algorithm changes | +| A straightforward, efficient miner with reliable payouts and retained operator control | Ordinary owners participate successfully, not only mining businesses | +| Useful proofs that outside customers repeatedly purchase | Demand for a service, not enthusiasm for the coin | +| Secure execution, finality and independently operated infrastructure | Developers and customers trust the network with meaningful activity | + +Each row is served only with its evidence beside it. What stops number one: losing on customer acquisition, developer adoption, operator economics or reliability; and GPU competitiveness is a contested claim (Ravencoin states it already), so the site shows a better result, never a more ambitious description. diff --git a/docs/plans/paid-pilot.md b/docs/plans/paid-pilot.md new file mode 100644 index 000000000..fb28b43cf --- /dev/null +++ b/docs/plans/paid-pilot.md @@ -0,0 +1,90 @@ +# The paid pilot: one external customer's exact workload, with repeat paid jobs + +Pin: Igneum 2.0, "Architecture and product", the proving business ladder, step two. Written 8 October 2026, 16:5x BST, from the code and the landed measurements; nothing here assumes demand. The external proving market is unbuilt and stays out of every revenue assumption until a customer has paid for repeat jobs. Prices quoted from public sources carry their URL; where a market publishes no price the cell says "no public price". Chip percentages are not published. + +## 1. The customer profile that fits the fleet's demonstrated edge + +What the pipeline proves today, from the code: + +- One program only. The host embeds two guests and refuses to run with any other: the shard program (program id 0x2b1a81cb..., 2,832,504 bytes) and the aggregator (0x474678f3...), both pinned in `proving/igneum-prove/elf/manifest.json` (SP1 crate 6.8.1, circuit v6.1.0) and checked at every start (`proving/igneum-prove/host/src/pinned.rs`, `include_bytes!` of the committed ELFs and verifying keys). The shard program is the Igneum chain's own EVM block transition: a range of transactions over a state witness, with rewards, the proving-pool credit and payouts applied by shard 0 (`proving/igneum-prove/core/src/shard.rs`, `ShardInput`, `shard_statement`). There is no path for an outside program. +- Inputs are a block fixture cut from a node's `igneum_exportSegments` dump by `igneum-prove-export` (`proving/igneum-prove/export/src/main.rs`); the plan cuts shards at the consensus proving budget `S_p`. +- Proof stages: execute, core, compressed; the aggregator folds shard proofs by recursion into one block proof and chains it to the previous segment's (`proving/igneum-prove/core/src/agg.rs`; `--mode chain`, `aggregate`, `verify-segment` in the host). The on-chain wrap (Groth16 or Plonk over bn254) is a trait method that returns an error and is not run (`proving/igneum-prove/host/src/proof_system.rs`). +- Verification: SP1's light verifier with the pinned verifying key (`--mode verify`); the node re-executes every carried record natively and drops a record whose result differs (litepaper, "How a block gets proven"). +- The job loop is the chain's own: every 10 s the app asks its node for shards assigned to its vote keys (`igneum_getAssignedShards`), exports, cuts, proves `--mode compressed`, signs and submits (`igneum_submitProofRecord`) (`app/igneum-app/src/prover.rs`). No job enters from outside. +- Hardware, measured: NVIDIA only; the tier that serves the pilot is 16 GB and up (section 3) (SP1's CUDA prover is Linux x86_64; Windows runs it in WSL2). The fixed 4,717,439-cycle shard (`proving/fixtures/fees-v1-shards2.json`, shard 0) proves compressed on the patched server at threshold 2^26 in 13.2 s on an RTX 3060 12 GB (7,525 MiB peak) and 8.2 s on an RTX 4060 8 GB (7,532 MiB), 6.3 s on an RTX 4090 and a 5090 (8.0 GB) (`docs/analysis/prover-tiers-real-cards.md`, 6 October; the 8 and 12 GB rows re-measured 8 October, v6-coexist). At the 5.5 GiB dataset floor an 8 GB or 12 GB card cannot hold the miner and the prover at once (13.6 GB together) and time-shares them; 24 GB and 32 GB cards hold both. +- Proof delivery on the devnet today: shards assigned by sortition to eight provers for a 10 s exclusive window, then open to anyone; no bond, no deadline beyond the record window of 600 chain blocks (`docs/spec/07-execution.md` 7.2, 7.7). + +The profile that fits that edge, stated as constraints rather than a market claim: + +1. The workload is an SP1 program (the one well-tested backend; a second backend only where justified, never interchangeable). Programs for other zkVMs are out of the pilot. +2. The job is sized in the fleet's proven range: shards of a few million cycles each, proved compressed in seconds to tens of seconds on one consumer card, and aggregated by recursion. A job that needs one proof of hundreds of millions of cycles on one card inside a wall-clock bound of seconds does not fit a consumer fleet. +3. Delivery is minutes, not seconds. A customer whose product needs a proof under 10 s of a large block (Ethereum real-time proving) needs a cluster; the fleet's edge is many independent cards on domestic power, so the fit is throughput with latency in minutes. +4. The customer verifies the proof on its own chain with its own verifier, under a program id it pins. Igneum delivers a compressed proof (or the customer's own aggregation of ours); the final wrap for an EVM verifier is either run by the customer's existing pipeline or is the first item the pilot builds (section 4). +5. The customer pays on its own chain in its own currency (the launch rule of `docs/spec/05-fees-and-economics.md` 5.4; route 4 of `docs/commercial/prover-customer-brief.md`). Settlement in IGN waits for the proof bridge. +6. Repeat is intrinsic: the customer has a steady stream of the same program with new inputs (blocks, batches, light-client updates), so "repeat paid jobs" is the normal shape of their demand, not a favour. + +## 2. Three candidate customer classes, ranked + +The founder's word on who is "no idea who". These are classes with one named example each, chosen for fit to the constraints above, not for known interest. Every example is from public sources as of 8 October 2026 and has not been contacted. Nothing here claims demand. + +| Rank | Class | Named example | Why they would pay | What they pay today | +|---|---|---|---|---| +| 1 | OP Stack rollups proving with OP Succinct (SP1 range proofs of their own blocks, aggregated and wrapped for L1) | Celo mainnet (OP Succinct Lite on SP1 Hypercube since 26 May 2026, per the Celo forum: https://forum.celo.org/t/op-succinct-sp1-hypercube-upgrade-live-on-celo-mainnet/13349); Mantle is the other named production user (https://blog.succinct.xyz/succinct-2025-recap/) | Their workload is the closest thing to ours that exists: SP1, EVM block execution, shard-sized range proofs, compressed then aggregated, with latency in minutes. A second supplier is a liveness and price story for a chain that depends on one prover network. | No fixed public price. Succinct's network sells by reverse auction in PROVE per PGU plus a dynamic base fee, no published rate (https://docs.succinct.xyz/docs/protocol/spn/auction). Succinct's own figure for OP Succinct: average proving cost 0.5 to 1 cent per transaction (https://blog.succinct.xyz/op-succinct/). A community estimate used for budgeting is USD 1.50 per billion PGU (https://hackmd.io/@damian666/rkqyehOOge); treat as an assumption, not a rate. | +| 2 | SP1 light-client bridges (sync-committee and storage proofs on a fixed program, one job per update, on a timetable) | Gnosis OmniBridge on SP1 Helios (Succinct reports more than USD 40 million TVL and USD 1.5 billion of stablecoin flow verified by its consensus proofs: https://blog.succinct.xyz/succinct-2025-recap/); IBC Eureka connects 120 Cosmos chains the same way | A fixed program, small inputs, a clock (every sync period or every update), tolerance for delivery in minutes: the exact "repeat paid jobs" shape, and a customer that cares more about a proof arriving every period from independent operators than about raw speed. | No public price per update. Paid through the Succinct network's auction (above); no per-proof rate is published. | +| 3 | Ethereum L1 block proving for the Ethereum Foundation's zkEVM programme (optional execution proofs today, mandatory later) | The ethproofs.org provers: ZisK on 8 x RTX 5090 and Axiom OpenVM 2.1 on 16 x 5090 (https://ethproofs.org/) | The programme is the largest standing demand for SP1-class proofs and it is public and measured. The buyer class (staking operators, client teams, the Foundation) would pay for proofs from independent operators once proofs are mandatory. | Cost, not price: USD 0.0057 (ZisK, 8 x 5090) and USD 0.0068 (Axiom, 16 x 5090) per block on ethproofs.org; no one pays per proof today (provers are funded, not paid per block). Ranked third because the real-time target (10 s per block on a rig under USD 100,000) is a cluster workload, not a consumer-card one; the fleet fits only the non-real-time tier. | + +Taiko, the first proving customer named in `CLAUDE.md` (a based rollup whose multi-proof design accepts SP1 proofs, per `docs/commercial/prover-customer-brief.md`, approximate), belongs to class 1 and stays a candidate inside it; Celo is the named example because its OP Succinct deployment is the exact SP1 range-program shape the pilot pins, on the public record. + +Not ranked, noted for the record: Kaspa's EVM layers (Igra, Kasplex) share the node lineage and a miner community (`docs/commercial/prover-customer-brief.md`), but neither publishes an SP1 workload today, so there is no exact workload to pin. + +## 3. The pilot shape + +One workload, one program id, one price, one clock. Everything below is the proposal the outreach brief carries; the numbers are ours to change before signature and are not a market claim. + +| Item | The pilot | +|---|---| +| Workload | The customer's SP1 range program as deployed (rank 1: the OP Succinct range program; rank 2: the SP1 Helios update program). One program, one version, for the whole pilot. | +| Program identity | The customer's verifying key hash (the SP1 `vk` hash their on-chain verifier pins), recorded in the job and checked by the prover before any work (the same rule as `pinned.rs`: setup must derive the pinned id or the job is refused). A version change is a new pilot. | +| Inputs | The customer supplies the SP1 stdin blob per job (for a range proof: the L1 head, the L2 block range and the witness their own tooling produces); Igneum does not reconstruct inputs for a foreign chain. Inputs are content-addressed (sha256 in the job) so a re-run is reproducible. | +| Output | A compressed SP1 proof of that program over those inputs, plus the public values, returned to the address and endpoint the customer names. The customer's own pipeline aggregates and wraps for L1 as it does today; a wrap by Igneum is a phase-two item (section 4). | +| Verification rule | The customer verifies every proof with SP1's verifier against the pinned vk before it is counted; a proof that fails verification is not a delivered job and is not paid. Igneum keeps the same check on its side before sending (`--mode verify` generalised to the customer's vk). | +| Delivery time | 30 minutes from job receipt to proof returned, measured on the customer's clock, served by the 16 GB and larger tiers only. Restated against the day's measured pipeline (`docs/analysis/proving-pipeline-2026-10-08.md`, Devnet 3, 8 October, every paid shard): inputs 2.4 s median; proving 27 s median and 216 s at the slowest 5 percent; aggregation 23 s median (75 s on a 3090, memory-bound); verification and submission under 2 s; claim to submitted end to end 75 s median, 230 s at the slowest 5 percent, 302 s at the slowest 1 percent, 497 s at the maximum. Payment landed 171 s after submission at the median and 543 s at the slowest 5 percent, but payment is the customer's step and sits outside the delivery clock. The 30-minute bound is 3.6x the slowest segment observed, 6x the slowest 1 percent and 24x the median: the margin is there to absorb one failed attempt and a reassignment, not because a proof takes that long. The 12 GB tier is excluded by measurement: 313 claims, 0 paid, 6,765 card-seconds wasted (a 4090 claimant finishes the same segment first), and at the 5.5 GiB floor 8 GB and 12 GB cards cannot hold the miner beside the prover (`docs/analysis/class-v6/coexist-rows.md`). | +| Price per job | Cost-based, quoted per billion cycles of the program's execution, with a floor per job. From the measured rows: a 4060 proves 4.7 M cycles in 8.2 s at 115 W, so one billion cycles is about 29 minutes of card time, about 0.06 kWh (USD 0.01 at USD 0.15 per kWh) plus about USD 0.005 of card amortisation (USD 300 over three years); a 5090 does the same in about 22 minutes at 330 W (USD 0.018 of power, USD 0.035 of amortisation). Pilot quote: USD 0.25 per billion cycles, minimum USD 2 per job, so the operator's margin is several times its cost on every card tier and the quote sits well under the USD 1.50 per billion PGU budgeting figure the SP1 community uses. Priced in dollars, paid on the customer's chain (route 4), never a fixed number after the pilot: the launch rule prices a job at or above the subsidy the card forgoes, which moves with network hash. | +| Repeat cadence | One job per hour for rank 1 (a range proof an hour is a small slice of a chain's stream and leaves their existing supplier in place); one job per update for rank 2 (about one per sync period). | +| Pass condition | 500 paid jobs over 4 weeks, at least 99 percent delivered inside 30 minutes and every one verified by the customer, paid at the quoted rate with no job disputed. Reasoning: four weeks crosses more than 600 hourly program epochs and the operators' own churn, so a pass is not one good week; 500 jobs resolve the on-time rate to a fifth of a percent and are enough for the per-card cost table to be read back against real power bills; "paid" means money moved on the customer's chain for every counted job, so a subsidised or waived job does not count. Fewer than 500 paid jobs, or any week under 99 percent, is a fail, published either way. Against the measured day the time bound is not the risk: every segment that reached submission did so inside 497 s. The risk is completion: 30.8 percent of claims failed or were refused on 8 October (900 chain failures, 629 of them the sm_89 floor-link class since fixed; 153 refusals), and with that class out 13 percent of claims were still lost to steals (4.0 percent of claims paid to a faster claimant) and late chains (54 "carried after the segment's deadline"), with no retry in the prover (it drops the export and claims afresh). A pipeline that loses 13 percent of first attempts and never retries delivers about 87 percent on time; 99 percent needs the two fixes in section 4 (a claim honoured for its window, a tier that claims only what it can finish) plus one retry on a second operator inside the 30 minutes, which the measured times allow four times over. The pass condition therefore gates on those fixes being live before the first counted job. | + +## 4. What the pipeline is missing to serve it + +Checklist from the code, each item with the file or crate it touches. Nothing below is built; the first three are the gate for accepting a single job. + +- [ ] External program identity. The host accepts only the embedded guests (`proving/igneum-prove/host/src/pinned.rs`; `proving/igneum-prove/elf/manifest.json`). Needed: a permitted-programs registry (program id, vk hash, SP1 circuit version) that the host loads for a job, with the same "setup must derive the pinned id" refusal; the protocol pins the list (Igneum 2.0 pin: program identities and verifier versions pinned in the protocol). +- [ ] Generic inputs. The fixture path is Igneum's block fixture (`proving/igneum-prove/export/src/main.rs`, `proving/igneum-prove/core/src/fixture.rs`). Needed: a job input blob (SP1 stdin bytes, content-addressed) fed to `prove_shard` in `proving/igneum-prove/host/src/proof_system.rs` without the shard statement wrapper. +- [ ] Verification against the customer's vk. `--mode verify` uses the pinned key (`host/src/main.rs`). Needed: verify with the job's vk before sending. +- [ ] Job intake. The only job source is the chain's shard assignment (`igneum_getAssignedShards`, `igneum_exportSegments`, `igneum_submitProofRecord`, consumed by `app/igneum-app/src/prover.rs`). Needed: a job object (program id, input hash, deadline, price, payout address, customer endpoint), an intake endpoint in the node's proof pool (the node repository, `igneum-node`), and a second branch in the app's prover loop that takes a customer job when no chain shard is assigned (spec 7.2's sortition stays untouched: external jobs never pre-empt the chain's own proofs). +- [ ] Aggregation and wrap. The aggregator guest is Igneum's segment statement (`proving/igneum-prove/core/src/agg.rs`, `aggregator/src/main.rs`); `wrap` is unimplemented (`proof_system.rs`). For the pilot the customer aggregates and wraps; phase two is a generic aggregation program and the bn254 wrap, so Igneum can deliver an on-chain-verifiable proof. +- [ ] Payment. Route 4 (customer chain, payout contract keyed by miner address) is "Designed" with no code (`docs/spec/05-fees-and-economics.md` 5.4; `docs/commercial/prover-customer-brief.md` route 4); `pool/src/payout.rs` pays IGN inside Igneum's pool only. Needed: the payout contract on the customer's chain, the job-to-payout record, and a receipt the app shows; settlement in IGN waits for the proof bridge (spec 7.3) and is out of the pilot. +- [ ] SLA. The chain has a 10 s exclusive window and open claiming with no bond and no job deadline (`docs/spec/07-execution.md` 7.2, items 3 and 4); the brief's bond and timeout are open (O-5.6). Needed for a customer: a deadline on the job, a reassignment rule when the first operator misses it, a retry budget, and a delivered-on-time log that produces the pass condition's numbers (the app's `/api/state` tile and the node's `igneum_getProvingStatus` are where the counters live today). +- [ ] A claim honoured for its window. Measured 8 October: 137 segments (4.0 percent of claims) that one box had claimed were paid to another key; the 10 DAA-second exclusive window (`docs/spec/07-execution.md` 7.2, item 3) does not hold a slow claimant's segment for it, and 35 refusals read "segment already paid". Fix: the node's proof pool refuses a record for a segment inside another assignee's granted window until the window lapses, and the window is the claim's, not the assignment's (the node repository, the proof pool and `igneum_getAssignedShards`; the app's pick in `app/igneum-app/src/prover.rs` and the fleet agent `tools/fleet/box-prover.py` read the window back before they start). For an external job the same rule is the SLA's first half: the operator that took the job keeps it for the window, and reassignment happens only when the window lapses. +- [ ] A tier claims only what it can finish. Measured 8 October: the RTX 3060 12 GB tier claimed 313 segments and completed none (6,765 card-seconds wasted; 4 OutOfMemory failures), because its chain time exceeds the window a 4090 claimant closes first, and at the 5.5 GiB floor it cannot hold the miner beside the prover. Fix: the claimant gates on `memory.total` and its own measured chain time before claiming (the pick logic in `app/igneum-app/src/prover.rs`, the claim loop in `tools/fleet/box-prover.py`, the tier profile in `tools/fleet/box-prover.sh` where THRESHOLD and MINER are already chosen from the card's memory): 12 GB and under mine at the floor and claim nothing; 16 GB and up prove. For the pilot the same gate decides which operators are offered a job: 16 GB and up only. +- [ ] Memory profile shipped. The patched `sp1-gpu-server` that fits 8 and 12 GB cards (threshold 2^26) is a served artefact, not in the shipped app (litepaper, "Proving"); the served sm_89 tarball still carries the stock server in `home/.sp1/bin` (found 8 October, with the floor lane). Needed: the patched server in the app payload for every tier, and the time-sharing rule for 8 and 12 GB cards (mine or prove, never both at the dataset floor). +- [ ] Reporting. A per-job record (program id, input hash, cycles, card, seconds, verified, paid) kept by the operator and summarised for the customer; today's RESULT lines go to a log only (`host/src/main.rs`). + +## 5. Outreach brief (one page, served text rules: no founder name, UK English) + +**Igneum proving pilot** + +A GPU-secured network for Ethereum-compatible applications and verifiable computation. + +Igneum is a proof-of-work network mined on consumer graphics cards, where the NVIDIA cards that secure the chain also prove its blocks with SP1 and can prove yours. We are looking for one customer with one exact workload for a paid pilot. + +What we have measured. The chain's own block shards (about 4.7 million cycles each) prove compressed in 8 to 13 seconds on 8 GB and 12 GB cards and in 6 seconds on 24 GB and 32 GB cards, on rented hardware from eleven card models, with every proof verified. Shard proofs are aggregated by recursion into one proof per block. Proving runs on NVIDIA cards; AMD and Apple cards mine. Proven execution is not finality, EVM compatibility is not Ethereum security, and zero-knowledge proofs are not privacy. + +What the pilot is. One SP1 program of yours, one version, pinned by its verifying key. You send inputs per job; we return a compressed proof you verify with SP1's verifier against that key before it counts. Delivery inside 30 minutes of receipt. One job an hour, or one per update, for four weeks. A proof that fails your verifier is not a delivered job and is not paid. + +What it costs. A pilot quote of USD 0.25 per billion cycles of your program, minimum USD 2 per job, paid in your currency on your chain to a payout contract keyed by the operator who delivered. The quote is built from measured power and card cost on the fleet and is stated plainly so you can compare it with what you pay now. + +What we ask of you. The program and verifying key as deployed; at least 100 historical inputs with expected public values so our provers and your verifier agree before any job carries value; the deadline and the maximum cycles per job; the address that receives proofs; and a published pass or fail at the end: 500 paid jobs over four weeks, 99 percent inside the deadline. + +What we do not claim. The external proving market is not yet built and is not in our revenue assumptions. Your pilot would be the first external workload on the network; the job intake, payment contract and delivery log are built for it and published with their measurements. Nothing in this brief is an offer to sell a token. + +Contact: through the repository and the site's team page. diff --git a/docs/plans/testnet-go.md b/docs/plans/testnet-go.md index e08a2c4dd..40de99fc1 100644 --- a/docs/plans/testnet-go.md +++ b/docs/plans/testnet-go.md @@ -3,6 +3,13 @@ Prepared 5 October 2026 by the infrastructure and consensus engineer for the 19:00 BST (18:00 UTC) opening. State of every line as of 16:05 UTC. Nothing mines until the owner says go; the seeds hold the chain at height 0. +RE-CUT 7 October 2026 (the testnet genesis lane, on the founder's approvals of 09:3x UK, `docs/plans/ledger-decisions.md` +"Decisions (7 October 2026, 09:3x UK)" row 5, and his words of the same morning on the two exec-side findings): the +genesis is re-cut on the 18-decimal layout with `EmissionSchedule::TESTNET_1` and every switch on from genesis; section +"The genesis, re-cut" below is the object, "The seeds' cut-over" the runbook. The three seeds still hold the 5 October +chain (genesis `87617621...`, digest `b7d8c915...`) at height 0 and move only on the founder's go. The hash and digest are +FINAL as of 18:4x UK: mission item 8 (the genesis forward-compatibility fields, lane `genesis-forward`, daa61847 to f95178a1 and ff06c05c) is in the object. + ## What runs now | Piece | Where | State at 16:05 UTC | @@ -28,23 +35,128 @@ igneumd/2.1.0 `health.sh` shows `synced=False` on all three: that is the no-blocks state (a node is synced once it has blocks past genesis), not a fault. The check: `cd infra/seed-nodes && NET=testnet ./health.sh`. -## The genesis, final +## HELD: superseded by Igneum 2.0 on Devnet 3, 8 October 2026 (the founder's word, 17:4x UK) + +igneum-testnet-1 does not go. The founder scrapped the testnet at 17:4x UK on 8 October 2026: no step 10, nothing mines; +Igneum 2.0 on Devnet 3 supersedes it. The go line had run on main's order of 16:2x UK (the founder's word to main), one seed +at a time: seed1 195.201.35.33 at 16:22:00 UK, seed2 5.161.232.205 at 16:23:00, seed3 5.223.52.210 at 16:23:36, each reading +back the binary cb35df68 (acaf08b0) at /opt/igneum/bin, the old data directory moved aside (.prev-20261008T1522xxZ), and in +each journal the digest `1da30c10...`, "stamps object version 6 into its headers (block version 1538)", `Base unit: 10^18`, +"[igneum-exec] genesis 01294fd3... executed: chain id 4462", "class v5: the state stream after genesis ... is published", +0 "waiting for consensus" lines; no miner, no block; the mesh and the getBlockDagInfo read not taken before the stop (0 peers at +16:24:45 with the digests still crossing). On the founder's STOP through main, igneumd was stopped through its unit on seed1 +16:25:10 UK, seed2 16:25:14, seed3 16:25:19: 0 processes, the binaries, the genesis data directory and the kept pre-go data +directories all in place, nothing else touched. The seeds idle and are repurposed later for the no-rescue exercise (Deliverable 5 +of the 2.0 plan). For the record, the state at the +hold, every line of it below in this file and in `docs/bench-log.md`: + +| Item | State at the hold | +|---|---| +| The go cut | `release-0.3.25-node` acaf08b0 (both box mirrors) = c9ad753a + f8da7515 (cold restart) + f41f48a7 (the miner's exec-port default follows the network) + ba294c98 (the testnet object: class v5 from genesis, 18 decimals, TESTNET_1, every switch from genesis) + 6e04f7fc (the genesis state stream published) + acaf08b0 (the executor starts on a genesis sink whatever its age) | +| The object | genesis `01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac` (the FINAL 5 October message on the 16-byte subsidy payload), merkle `bcd0e8fb...`, consensus digest `1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f`, byte 6, chain id 4462, `infra/seed-nodes/testnet-object.json` | +| The gates, all green on acaf08b0 | the node lane's six suites at gate priority (exec 57, consensus 134, consensus-core 177, miner 30, p2p-flows 38, pow 19, 0 failed, three known-failed tests asserted wrong first) and both canaries (15:59 UK); the pod's two-node 18-decimal gate PASS with block one mined 70 s after start on a fresh class v5 testnet chain (327 chain blocks, 16:00 UK); the 8-decimal known-failed form FAIL by design (16:08 UK); the byte 6 fast-time line PASS 16 of 16 at class 5 (16:18 UK); the seeds' third dry run rc 0 on all three (16:03 UK) | +| The pairs | gate `/srv/artefacts/0325-acaf08b0/node-lane` (igneumd `9e4217f3...`, igneum-miner `bbabfa91...`); seed-class `/srv/artefacts/0325-acaf08b0/seed` (igneumd `cb35df68...`, igneum-miner `0b7e9d73...`); the fallback `/srv/artefacts/0324-tn-0d05e795/seed`; pairing igneum-pow 1c420786 | +| What the day found and fixed on the line | the miner's class v5 state lookup wired to the devnet exec port on every network (row 9t); no state stream after the genesis seed block (row 9v, 6e04f7fc); the executor's sync wait that no fresh chain could satisfy (row 9v, acaf08b0, one rule with the cold-start deadlock: no guard waits on what only a block can produce); the fast-time line's class v4 gap (row 9u, c5fe28e4); the gate script's exec port, block-one lines and timeout (b38f1ad3) | +| The first miner's key | held on the Mac, `~/.config/igneum/testnet-first-miner.json`, address `0x216fee62...` (row 9o); never used; the pod for step 10 destroyed unstarted | +| Not done, by the hold | the seeds' mesh on the go object (stopped at 16:25 UK before the three saw each other), step 10, the block-one read on the public RPC, the announcement; the named item for the next node line (the "unsynced mining enabled" half of the executor ruling) stays open for Devnet 3 | + +The sections below are the record as they stood at the hold. + +## The go object (ruling of 7 October 2026, 19:2x UK): the 0.3.24 testnet object, re-cut with class v5 from genesis (0d05e795, 8 October) + +By the coordinator's ruling of the evening of 7 October 2026, igneum-testnet-1 goes on the 0.3.23 testnet object (the Devnet 3 shape: +byte 7 from genesis, every Devnet 3 activation at 0, the era VDF at 0, class v5 at 0 if its Devnet 3 crossing reads clean, the heights, +the bonus's switch field) AT 18 DECIMALS (the founder's word, 21:35 BST: the decimals lane's code merged, the schedule at 18, the 16-byte +genesis payload on the final message, the scale factor tested known-failed first), cut and re-armed on the seeds by the build-server lane, which owns them; the interim re-arm is the +release-0.3.22-node object (34a2dbaa, digest `87d103b6...`, genesis `52a3e6a9...`). Two orders ride with it: the testnet genesis carries +the FINAL message (the 5 October payload that `87617621...` carried, never the 4 October "proposed, not final" text that `52a3e6a9...` +hashes: a public node never starts on a proposal; the digest moves and the re-arm absorbs it), and the base unit is 18 by the founder's word of 21:35 BST (the +8-decimal scratch form is no longer needed); nothing on a seed before the node lane names the cut and the build-server lane's dry run reads clean. The carry (22:1x UK): this lane's re-cut merged onto the 0.3.24 line as fork branch `testnet-genesis-3-node` 34892a36; LANDED 23:01 UK as the +0.3.24 node pin 47b9b229 (= the Devnet 3 object commit 774f16c9 + 34892a36); the pin moved at 23:39 UK to c9e385eb (Devnet 3's class v5 floor +28,800 to 32,400) at 00:54 UK on 8 October to dfbd1e10 (the floor at 39,600) and at 09:33 UK to 5b673577 (the floor at 68,400 from main's move minute +10:45 UK; nothing on the testnet side changed at any move), `release-0.3.24-node` at 5b673577 on both box mirrors, every gate green at 09:39 UK, +the Devnet 3 canary set clean on its own binary. THE POST-CROSSING RE-CUT (row 9n) LANDED: Devnet 3 crossed its class v5 floor clean at 12:57 UK on 8 October (the first epoch-19 block on the v5 seed, 341 blocks in four minutes, seven stale-pack attempts refused, no state-wait or catch-up fault on build-1's three nodes), and the node lane cut 0d05e795 on `release-0.3.24-node` (13:32 UK, on both mirrors 13:48 UK): `program_class_v5_activation_daa` 0 and `program_class_signal` CLASS_SIGNAL_V5 (byte 6 from genesis), the identity test re-pinned, nothing else in the object (18 decimals, TESTNET_1, chain id 4462, every other switch from genesis as before). The digest is `1da30c10...` (from `b2e856ed...`); the genesis hash is unchanged (the digest is not in the header). The node lane's gates on 0d05e795, all green by 14:04 UK: pow 19, exec 47, miner 28, consensus 134, p2p-flows 38, core 175; its testnet canary (13:50 to 13:51 UK): the digest `1da30c10...` with no file, "stamps object version 6", the override refused, two empty nodes handshaking, the live old-object seeds refused; the Devnet 3 canary on that line unchanged (cc902690). This is the object the go uses. + +| Field | Value of the go object (cut as 0d05e795 on the 0.3.24 line, carried to the 0.3.25 line as ba294c98 and fixed node-side to acaf08b0; read from the binaries by the node lane's testnet canaries, 13:50, 15:31 and 15:48 UK, 8 October 2026) | +|---|---| +| Network | `igneum-testnet-1`, chain id 4462 (never moves), address prefix `igneumtest`, ports 26810 / 26811 / 28810 / 26890 | +| Genesis | hash `01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac`, merkle `bcd0e8fb1099aeb3cc1370b50e6dec9f615e204374b2097f25b2438e7d22f49f`: the FINAL 5 October message on the 16-byte subsidy payload of 18 decimals, timestamp 2026-10-05T00:00:00Z, bits `0x1d100000` | +| Consensus digest | `1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f` (pinned by `igneum_testnet_identity` at 0d05e795, `consensus/core/src/config/params.rs`; read from the 0d05e795 binary by the node lane's testnet canary, 13:50 to 13:51 UK, 8 October: the override refused, two empty nodes handshaking on it, the live seeds refused on their 5 October digest). The 5b673577 digest `b2e856ed...` (class v5 at never) is void, as are `b7d8c915...` (5 October), `87d103b6...` (the 0.3.22 interim) and every earlier interim | +| Base unit, emission | 18 decimals (the founder, 21:35 BST); `EmissionSchedule::TESTNET_1` at the unit | +| From genesis | difficulty v2 and v3, proving v0, finality v3, the DAA-second rule, the leave item (delay 3,600), the signing bonus 0 at 1,000 bps (no burn), the per-block subsidy, class v3 and v4 under the Devnet 3 shape's one-day signal window (byte 6 stamped from genesis: class v5's signal; class v5 itself from DAA 0 by the post-crossing re-cut 0d05e795), the ladder at rung 0 (window 86,400; 27/35/53 admissible, 88/173/267 not), the era VDF (scheme 0, the reference T), proving v1 with the fresh rule (the Devnet 3 shape), fees v1, consensus proof verification under the manifest's ids (shard `0x2b1a81cb...`, aggregator `0x474678f3...`), `sig_scheme` 0 with its switch, the W5 succession, the cache rung (512 MiB inadmissible) behind its switch | +| Held at never | the fork gate (window 600), the peer directory, the pool split, exec restart | +| Pairing | igneum-pow at the class v5 freeze commit 1c420786 | +| Where | the go pin `release-0.3.25-node` acaf08b0 (both box mirrors; = c9ad753a + f8da7515 cold restart + f41f48a7 the miner's exec-port default + ba294c98 the 0d05e795 params change + 6e04f7fc the genesis state stream + acaf08b0 the executor starting on a genesis sink; ba294c98 and 6e04f7fc are the known-failed bases; the 0.3.24-line pins 0d05e795 and 5b673577 carry the same object: 0d05e795's pair is the FALLBACK, 5b673577 void as a pin): the gate artefact `/srv/artefacts/0325-acaf08b0/node-lane/igneumd` sha256 `9e4217f3129f70bae03783c1a1c3acd1c238a02a1d669ba5e3c64d2b3ffef0fb` (commit string acaf08b05b7d8dee73ebba7e6cf000f4e914f53c), igneum-miner `bbabfa910441a85895e4dd9ddf5e7f06aaded57749b1d7234238323d473e31f8` (unchanged since ba294c98), both IGNEUM_POW_FINGERPRINT `cbc5bd0aa10585c8...`; the seed-class pair in row 9q; pairing igneum-pow at the freeze 1c420786; the node lane's suites on acaf08b0 at gate priority, green by 15:59 UK: exec 57 (the three known-failed tests ok: the genesis-sink start, the genesis stream, the cold-restart replay), consensus 134, consensus-core 177, miner 30 (the exec-rpc default test ok), p2p-flows 38, pow 19, 0 failed; the testnet canary on this pair (15:48 UK): two empty `--testnet --netsuffix=1` nodes print the digest `1da30c10...` and "stamps object version 6", the override file refused, the cross-network dial refused; the Devnet 3 canary on the same binary: digest 2066aa57 unchanged, the mixed-version handshake with 6e04f7fc | + +Suites on 34892a36 (bounded, build-2 and build-1): consensus-core 168, exec 47, p2p-flows 38, pow 19, kaspad 2; consensus 134 one test at a +time with the pre-existing m20 red (9f); the parallel lib run aborts in the test-order race class the node lane owns, noted, not chased +tonight. On the staging 47b9b229 (the node lane, 22:35 to 22:43 UK, against the freeze pairing): consensus 134, core 175, exec 47, miner 28, +p2p-flows 38, pow 19, the build rc 0; the testnet canary on build-1: digest `b2e856ed...` on igneum-testnet-1, the genesis as cut, 18 decimals +in the fee floors, object version 7 stamped, the override file refused (rc 1), two empty nodes handshaking on `b2e856ed...`, a Devnet 3 +node reading its own digest beside it. During the handshake step seed 2 (5.161.232.205) dialled the canary and was refused on the digest; the gate pod +of 8 October (09:49 UK) read the seeds' own answer: all three refuse on `b7d8c915...`, the 5 October object of 1c19441d, so the seeds carry +the 5 October chain at height 0 until the founder's go (no 0.3.22 binary reached them); the runbook's wipe stands. The digest lineage: `b7d8c915...` (1c19441d) to `87d103b6...` (the 0.3.22 interim re-arm) to `b2e856ed...` (5b673577, class v5 at never) to `1da30c10...` (0d05e795, class v5 at 0: THE GO DIGEST). The runbook's +values: `--genesis 01294fd3...`, `--digest 1da30c10...`, `--commit acaf08b0` (the go pair on `release-0.3.25-node`: ba294c98 plus row 9v's two fixes 6e04f7fc and acaf08b0, by the coordinator's rulings of 14:2x, 15:1x and 15:3x UK on 8 October; its gates and the block-one line pending at 15:4x UK; ba294c98 and 6e04f7fc are the known-failed bases and `--commit 0d05e795` the FALLBACK pair on the 0.3.24 line, none of them the go pair), the seed-class GO pair from acaf08b0: `/srv/artefacts/0325-acaf08b0/seed/igneumd` sha256 `cb35df68997f407c3c371617384b038dadd3213b00cb590db7f542dc77c6e5c4`, `igneum-miner` sha256 `0b7e9d73cecc5a4441fba421105d1e62efd51ebd46f57ce7f50aa18b243b231a` (row 9q; the 0d05e795 FALLBACK pair, built and dry-run clean 14:26 UK, is `/srv/artefacts/0324-tn-0d05e795/seed/igneumd` `9b464158...`, `igneum-miner` `d5a5bc9e...`); the re-arm is the go pair's pull-path dry run on the three seeds. The go pair's read-back adds two required lines beside the digest, byte 6 and 10^18: "[igneum-exec] genesis 01294fd3... executed" and "[igneum-exec] class v5: the state stream after genesis 01294fd3... (epoch 0's reference) is published", and must show no "waiting for consensus to sync" line. The go line: `infra/build-server/wave1-0320.sh seeds --igneumd /srv/artefacts/0325-acaf08b0/seed/igneumd --sha256 cb35df68997f407c3c371617384b038dadd3213b00cb590db7f542dc77c6e5c4 --miner /srv/artefacts/0325-acaf08b0/seed/igneum-miner --digest 1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f --commit acaf08b0 --wipe-genesis --genesis 01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac`, no override; `--go` only on the founder's word. The record of the first dry run, on 5b673577's pair, stands below and is NOT the go pair: the seed-class pair the +build-server lane built from 5b673577 at 09:43 UK on build-1: `/srv/artefacts/0324-5b673577/seed/igneumd` sha256 +`3a204fd9d3a4840dcef430e73cbfa986881db915d5459533d395dc0563a597a8` (glibc 2.34, the commit string twice, igneum-pow 1c420786) and +`igneum-miner` sha256 `464dca078db54434b2ce4cdf8b5975a614141d20907a9d941cc88667b85144ba`, `--commit 5b673577`, no override, `--wipe-genesis`; +the read-back includes `Base unit: 10^18`. DRY RUN DONE 10:23 UK, 8 October 2026: rc 0 on seed1, seed2 and seed3 ("DRY RUN, nothing +touched; the box answers as seedN, active a9ea25f8ada2", the 5 October binary still running), the pair's shas asserted; the same binary +started bare on build-1 with `--testnet` prints `igneumd/2.1.0-5b673577`, the digest `b2e856ed...`, `Base unit: 10^18`, fees v1 from DAA 0, +proving v0 from DAA 0, the follower at genesis (height 0). One hazard the read exposed: the `[igneum-exec] genesis executed` line is +not a start line in this build (it was in the 5 October one), so the seeds mode's `--genesis` read-back must take the hash from +`getBlockDagInfo` after the start (at height 0 the pruning point and the sink ARE the genesis, `01294fd3...`), not from the journal, or it +reads "not seen in 60 s" and the go run reports a false MISMATCH; the build-server lane adds that read before `--go`. Nothing mines. The gate rows 9g, 9h and 9j re-run on it; row 9c reads "re-arms on each +cut". Everything below this paragraph in this section is the 7 October RE-CUT of this lane on the 0.3.18 line, the source of the carry, +kept as the record of what was built and gated. + +### The 7 October re-cut (void by the ruling; the record) | Field | Value | |---|---| | Network | `igneum-testnet-1`, chain id 4462, address prefix `igneumtest`, ports 26810 (gRPC), 26811 (p2p), 28810 (wRPC JSON), 26890 (EVM JSON-RPC) | -| Coinbase message | `igneum-testnet-1 \| 2026-10-05 \| coins here have no value \| resets are announced` ("proposed, not final" dropped before the first public node) | -| Timestamp | 1,791,158,400,000 ms = 2026-10-05T00:00:00Z | -| Bits | `0x1d100000` | -| Hash | `87617621714af1bf33bd17f291f90a7e0bff760a669bba53083ea8c0f7cbd840` | -| Merkle root | `44acfc40b1c6647011510f3c39ddb7606f979df92ad26a2914de56e44610efad` | -| Consensus digest | `b7d8c915f20f5af261e69e7f4aa9c3d03a9c4a462174776502b63fa1e9ec8447` | +| Coinbase message | `igneum-testnet-1 \| 2026-10-05 \| coins here have no value \| resets are announced` (unchanged from 5 October) | +| Coinbase subsidy field | 16 little-endian bytes, one IGN = 10^18 base units (the 18-decimal layout, O-2.6) | +| Timestamp | 1,791,158,400,000 ms = 2026-10-05T00:00:00Z (unchanged) | +| Bits | `0x1d100000` (unchanged) | +| Hash | `01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac` | +| Merkle root | `bcd0e8fb1099aeb3cc1370b50e6dec9f615e204374b2097f25b2438e7d22f49f` | +| Consensus digest | `63faee44f50eccd3d68c970efbc39edee2977a4f0fbf4baa833aa5ef5de3577a` (18:4x UK, with the cache rung behind its own switch, the genesis-forward lane's ff06c05c after the Devnet 3 digest finding; `4fbb2152...` at 15:0x UK with the genesis forward-compatibility fields under the ladder's arm, `80af8aa1...` before them with `subsidy_per_block_activation_daa` 0, `9390d235...` before that field) | +| Base unit | 18 decimals (`base_unit_decimals` 18): one IGN is 10^18 base units, the EVM's wei; the bridge is the identity | +| Emission | `EmissionSchedule::TESTNET_1` at the unit: 100 IGN a block at 1 bps, a monthly glide with a two-year half-life, a 90-day ramp from 10 percent, a 1 percent of supply a year tail from the month the glide first pays under it; no hard cap | +| Switches on from genesis | `difficulty_v2_activation_daa` 0, `difficulty_v3_activation_daa` 0, `proving_v0_activation_daa` 0, `finality_v3_activation_daa` 0, `finality_daa_rule_activation_daa` 0, `finality_leave_activation_daa` 0 (`finality.leave_delay` 3,600), `signing_bonus_activation_daa` 0 with `signing_bonus_bps` 1,000 (no burn; vote-or-burn is out of the tree, 420f9305), `program_class_v3_activation_daa` 0, `program_class_v4_activation_daa` 0 with signal window 0 (v4 unconditional), `latency_ladder_activation_daa` 0 at rung 0 with `latency_ladder_window_daa` 86,400 and the six rungs 27 (admissible), 35 (admissible), 53 (admissible), 88 (inadmissible: quiet-core re-measure 08:46 UK, 10.85 ms cold with the sibling loaded, over the 10 ms gate), 173 and 267 (inadmissible), `fees_v1_activation_daa` 0 (`FeeParams::CALIBRATED_V1`), `proving_consensus_verify_daa` 0 under shard program id `0x2b1a81cb413236cf063077b46ed3111628f6c41036bcf6e23ee4cbbf5679ef7a` and aggregator id `0x474678f35f7545db28055d5e5bbc308231d84a5a072202087a2a8d5b09123896` (`proving/igneum-prove/elf/manifest.json`, pinned 2026-10-05T16:20:38Z), `subsidy_per_block_activation_daa` 0 (each merged block credited the subsidy of its own DAA on the EVM side, as the UTXO coinbase pays it), and mission item 8 (the founder's order, 10:1x UK; `docs/design/genesis-forward.md`): `sig_scheme` 0 (BLS12-381) with `sig_scheme_activation_daa` 0 (every vote item and key reveal carries the scheme byte on the wire; any other scheme is refused by every node until a program class the 95 percent signal moves to names it), `finality_succession_activation_daa` 0 (the W5 item: a vote key hands its window weight and its forfeit term to a successor once), `latency_ladder_cache_rung` {mib 512, admissible false} beside the six N rungs with `latency_ladder_cache_rung_activation_daa` 0 (inadmissible until measured; its own digest arm after the ladder's, ff06c05c) | +| Left at never, by design | `fork_gate_activation_daa` (window 600), `proving_v1_activation_daa` and `proving_v1_fresh_rule_daa`, `exec_restart_*` | +| Finality object | `FinalityParams::MAINNET`: interval 30, depth 60, window 2,592,000 DAA, dust 100, presence 240, 8 aggregators, ban 2,592,000, min DAA 2,592,000, fold 6, leave delay 3,600 | | Fees | `CALIBRATED_V1` from DAA 0 | | DNS seeders in `TESTNET_PARAMS` | `seed1.testnet.igneum.network`, `seed2.testnet.igneum.network`, `seed3.testnet.igneum.network` | | `--netsuffix` | defaults to 1 under `--testnet` | +| Override file | refused on the testnet (as on mainnet): the object above is compiled into `TESTNET_PARAMS`; `infra/seed-nodes/testnet-object.json` is the same object as override-file JSON (`print_testnet_object`), for reading and diffing against the daemon's start-up lines, never loaded | +| Where it lives | node fork branch `testnet-genesis-2-node` on the box mirror (`release-0.3.18-node` e69e8a39, the decimals branch df2fbd03 merged, the vote-or-burn removal 420f9305, the exec-side fixes c7ea1e21 and d840537b, the carried-proof gating dc141409, the proof archive aea0ca5c, the proof-hold fix 70e4601e, the genesis-forward commits daa61847 to f95178a1 and ff06c05c, the re-cut); repository branch `testnet-genesis-2` | -The proposal's hash `52a3e6a9...` is void: it hashed the old message. Any node built from a fork commit before 1c19441d -has the old genesis and never completes a handshake with the seeds (different genesis, different digest). +Void: the 5 October genesis `87617621...` (8-byte subsidy layout; the chain the seeds hold until the cut-over), its digest `b7d8c915...`, the proposals `52a3e6a9...` and `494fc9a3...`, and the interim digests `9390d235...`, `80af8aa1...` and `4fbb2152...`. Any node built before the re-cut never completes a handshake with a re-cut node (different genesis, different digest; seen 7 October 2026, 08:05 UK: a box node on the re-cut tree dialled the three live seeds and each side refused the other on the digest). + +What a node prints at start on this object (igneum-build-1, 7 October 2026, 08:05 UK, the two-node gate's node A): + +``` +Latency ladder active: rungs 27, 35, 53, [88], [173], [267] shadow passes, this node signals none (header version bits 15 and 14) +Fees on igneum-testnet-1: pgas table v1, B_p 120000 pgas, S_p 30000 pgas, floors 100000000000 wei per gas and 10000000000000 wei per pgas; calibrated v1 from DAA score 0 +Base unit: 10^18 base units per IGN (wei, the EVM's unit); one base unit is 1 wei on the execution layer +Consensus params digest: (exchanged in the p2p handshake; a peer with another digest is refused) +Finality v2 (igneum-testnet-1): interval 30 depth 60 window 2592000 DAA dust 100 presence 240 aggregators 8 ban 2592000 fold 6; rule v3 (frozen table, certificate fold) from checkpoint DAA 0; ... C1 in DAA seconds +Proving: consensus proof verification from DAA score 0 (shard program id 0x2b1a81cb..., aggregator id 0x474678f3...); a carried record whose proof fails invalidates its block +``` + +## Consequences of the object, per tier (the standing rule of 5 October 2026) + +| Number | What it means | Who it touches | +|---|---|---| +| 18 decimals, 16-byte amounts | a node holds about 8 percent more UTXO bytes on disk and 11 percent more in memory than at 8 (docs/design/base-unit.md section 5: +80 MB disk, +170 MB memory at 10,000,000 UTXOs); no tier changes class on 8 GB to 32 GB cards, Windows, Linux or macOS; wallets and exchanges see Ethereum's unit | every node; nothing for hash rate, power or a miner's deadline | +| 100 IGN a block, a 90-day ramp from 10 percent | day-0 block pays 10 IGN (8 to the producer, 2 to the proving pool); the first full-rate block is above u64::MAX in base units, which is why every amount is u128 | every miner's expectation of the first month | +| the signing bonus at 1,000 bps from genesis | a vote key that stops signing while in the weight table earns 72 percent of the subsidy instead of 80; a home miner on one card who runs the app as shipped signs every checkpoint and is untouched; a pool user's key is the pool's | silent keys only; both ledgers agree after c7ea1e21 | +| `proving_consensus_verify_daa` 0 | every node verifies carried proof records from block one; a Windows node verifies through the installed `igneum-prove-host` and refuses to start without it (the in-process SP1 verifier is Unix-only); the seeds are Linux and verify in process; PC 1 and every Windows miner need the host beside the node (the app ships it) | Windows nodes; the go list below | +| the latency ladder from genesis at rung 0 | the shadow block costs 27 passes as class v4 ships; a step to rung 1 needs 90 percent in each of seven day-long windows, so nothing moves in the first week; rungs 4 and 5 can never be entered | every miner's hash rate is the class v4 rate; verifiers under 10 ms cold at rungs 0 to 2 | +| the leave item from genesis, delay 3,600 | a miner that stops cleanly sends a leave and is out of every denominator an hour later; one that stops without a word holds its weight in the table for the 30-day window | pool operators and rigs that restart; the app sends the leave on a clean stop | +| `FinalityParams::MAINNET` | the first lock needs 30 days of weight, so the testnet shows no lock in its first month and the exec-side identity under the bonus can only be read after it; the devnet-suffix fast-time line is the proof of that identity before go | everyone reading the finality page in the first month | ## Branches and commits (nothing pushed, nothing merged) @@ -53,6 +165,8 @@ has the old genesis and never completes a handshake with the seeds (different ge | node fork (`vendor/igneum-node-testnet-infra`, from `release-0.3.6` 2b6d23ef) | `testnet-infra` | 1c19441d | final genesis message, hash and merkle root; `--netsuffix` default 1; the three DNS seeders; `igneum_testnet_identity` and `test_genesis_hashes` updated | | app repository (`igneum-wt-testnet-infra`, from master 23d11d5) | `testnet-infra` | 358e565 | `infra/seed-nodes`: `NET=testnet` profile, `seeds-testnet.tsv`, `dns.sh`, `rpc/` (filter, unit, nginx site), `node/install-rpc.sh`, `install-rpc-from-mac.sh`, ports from `seed.env`, glibc check, debian-13 images, quoted env values; `tools/build-job.mjs` forwards `--node-tests`/`--app-tests` and its watcher reads the SUMMARY wherever it sits; `docs/testnet/README.md` final genesis; this file | | app repository (`igneum-wt-testnet-app`, from `testnet-infra` 9fa2bb3) | `testnet-app` | c00df85 | the app's network setting: `Packaged.network/peers/public_rpc`, `Network` enum with the testnet's ports, seeds and node directory, `Runtime::from_env_and_packaged`, the dashboard's chain label `testnet-1` with the public RPC on its tooltip, the testnet node keeps its DNS seeders; `packaged-config.sh` `IGNEUM_PACKAGE_NETWORK` (default testnet; the fleet's devnet builds pass `devnet`) | +| node fork (`vendor/igneum-node-testnet-genesis` in `igneum-wt-testnet-genesis`, from `release-0.3.18-node` e69e8a39; on the box mirror) | `testnet-genesis-2-node` | see the branch | the re-cut genesis and object (section "The genesis, re-cut"), the decimals branch df2fbd03 merged, 420f9305 (vote-or-burn out), c7ea1e21 and d840537b (the exec-side identity under the bonus and the per-block subsidy) carried in Amount, `igneum_testnet_identity` pins the hash and the digest, `print_testnet_object` prints the object | +| app repository (`igneum-wt-testnet-genesis`, from master ab99e5e3) | `testnet-genesis-2` | see the branch | `infra/seed-nodes/testnet-object.json`, `tools/fleet/base-unit-gate.sh` (from the decimals branch), `infra/fast-time/testnet-object.mjs` (the object at fast time: class v4, the ladder at rung 0, the first lock, the bonus split on both ledgers, a signed leave), `igneum-pow` at the 0.3.18 release line, `docs/testnet/README.md`, this file | | app repository (`igneum-wt-testnet-wallet`, from `wallet-v1` a238781) | `testnet-wallet` | fe6e5e8 | `igneum-common`: `Packaged.network`, `TESTNET_PUBLIC_RPC`, `chain_id`, `effective_public_rpc`; the wallet engine reads the effective URL; the wallet's packaged config follows `IGNEUM_PACKAGE_NETWORK` | Tests: `kaspa-consensus-core` and `igneum-app` suites on PC 2, build job `build-20261005-155547`, both exit 0 @@ -65,7 +179,7 @@ Mac: 27 passed (the crate is not in the PC build inputs). The packager's self-te | # | Step | Who presses | State at 16:05 UTC | |---|---|---|---| | 1 | Seeds up at height 0, peered, the public RPC answering | nobody (done) | DONE: three seeds, 2 peers each, RPC live | -| 2 | Merge `testnet-infra` and `testnet-app` to master; the fork's `testnet-infra` into `release-0.3.6` (or the release branch the 0.4.0 cut uses) | the release engineer, on the founder's word | NOT DONE: branches ready, nothing merged | +| 2 | Merge `testnet-genesis-2` (the repository branch: the object record, the gate, the fast-time harness, these docs) and `testnet-app` to master; the fork's `testnet-genesis-2-node` into the release branch the 0.4.0 cut uses (0.3.19 or later; `testnet-infra` on the fork is superseded by it) | the release engineer, on the founder's word | NOT DONE: branches ready (7 October 2026), nothing merged; waits for mission item 8 (the forward-compatibility fields) | | 3 | Cut 0.4.0 from `testnet-app` (`tools/ship-app.mjs 0.4.0 --node vendor/igneum-node-testnet-infra ...`); the Mac DMG, the Windows installer through the PC build job; the packaged file must say `"network": "testnet"` (the default) | the release engineer | NOT DONE: the packager writes the testnet by default; the fleet's devnet update, if any, needs `IGNEUM_PACKAGE_NETWORK=devnet` | | 4 | The prover's fee-table mirror at `CALIBRATED_V1` (`proving/igneum-prove/core/src/config.rs`, `pgas.rs`; `docs/plans/release-0.3.6.md` section 5 step 6): on the testnet fees are v1 from genesis, so a prover with the prototype table produces shard statements the node refuses. Needed before the first testnet proof, not before the first block | the execution engineer | NOT DONE | | 5 | History rewrite (`docs/plans/history-rewrite.md`, G14: the 40 commits with a personal name) | the founder, then the repository goes public | NOT DONE | @@ -73,11 +187,82 @@ Mac: 27 passed (the crate is not in the PC build inputs). The packager's self-te | 7 | Downloads public: the 0.4.0 manifest in the downloads folder, `publish-manifest.sh --deploy` | the release engineer | NOT DONE | | 8 | The site's buttons: the download section points at 0.4.0, `site/wallet.html` carries `https://rpc.testnet.igneum.network` and chain id 4462 in place of the placeholder, the terms card (`#testnet-terms`) stays; `node site/build.mjs`, push to master (Vercel deploys) | the site agent | NOT DONE: the placeholder is still in `site/wallet.html` | | 9 | Announcement text | the founder | PLACEHOLDER: "Igneum testnet-1 is open. Coins here have no value. Resets are announced seven days ahead. Download: igneum.network. RPC: rpc.testnet.igneum.network, chain id 4462." (the founder's words replace this) | -| 10 | The first miner: one app on the testnet (PC 1 or PC 2 with the 0.4.0 build, or `igneumd --testnet` plus `igneum-miner --network testnet` by hand) produces block 1; the seeds relay it, `health.sh` shows blocks=1 on all three, `synced=True` | the founder says go, the miner-community lead starts it | NOT DONE: nothing mines until the word | +| 9a | The seeds' cut-over to the go object (the runbook below): the go pair (acaf08b0's seed-class binaries, row 9q) on the three seeds, each data directory wiped (the 5 October chain at height 0 has nothing to keep), the digest line, byte 6, 10^18 and the two genesis lines read back on each, the mesh re-formed; ARMED 16:03 UK, 8 October (the third dry run clean on all three seeds) | the build-server lane runs the runbook's `--go` line, on the founder's word through main | NOT DONE: binaries built, nothing deployed; the seeds hold the 5 October chain | +| 9b | Proof retention: every node keeps proofs for the pruning window and the carried-proof rule applies only above the pruning point, so a node joining after the pool's horizon syncs from the pruning point (the coordinator's direction, 7 October 2026, 10:0x UK). Node side done: dc141409 (the rule, the IBD fetch and the relay retry apply from `proving_consensus_verify_daa` only) and aea0ca5c (`ProofArchive`: one file per proof under the exec db's `proofs/`, kept for the pruning window, served when the pool no longer holds the entry), both on `testnet-genesis-2-node`. The gate: `infra/fast-time/tn-late-join.mjs --join-after 700 --prover "node infra/fast-time/tn-prover-loop.mjs ..."` (a fresh node joins after the pool's 600-block window has passed, every proof it asks for from A's archive; the known-failed side is a binary before aea0ca5c, which stalls on "proofs this peer did not deliver in 20 s") | the node lane (done), then this lane | PASS at 14:36 UK, 7 October 2026 (pod os-latejoin-ylp1, RunPod 3070): node A on the archive binary 57ad7dc2... (fork 5c25c1fb) mined to DAA 6,297 at fast time (pruning 4,600, window 150) with a CPU prover beside it (igneum-prove-host, 37 records accepted and verified by A's pool in under 2 s each, 34 proofs in A's archive, one file per carrying DAA, the pool's 600-block window long past); A's miner and prover stopped; B fresh on the fixed binary fbed53cd... (fork 26e648ff, the node lane's 70e4601e: a served proof is held by hash before the native checks) joined through the headers proof and reached A's sink in 35 s, 4,618 blocks and headers, IBD completed, sink version 1026, 0 errors. Known-failed first, the same chain at 14:02 to 14:12 UK with B on the pre-fix binary 57ad7dc2...: B stalled at chain block f4f918f7 (DAA 1,828, above the pruning point at 1,679) six times on "carries 1 proof records whose proofs this peer did not deliver in 20 s" while A's archive held the file 00000000000000001828-6e3461a3...; the cause was B's fetch side (the served record refused against B's trailing exec state before the proof was held), not A's serve. Pod facts: a RunPod 3070 community pod gives about 19 vCPU and 24 GB; two CPU SP1 provers beside two nodes do not fit (every compressed proof killed at the cap), one does (7 of 36 proofs still died at the cap as the exporter's input grew with the chain); the harness's join-after target is in DAA (the unpruned block count plateaus once the pruning point moves) and a `--resume` mode attaches to a live A | +| 9e | The proving pin: `TESTNET_PARAMS` pins the shard and aggregator ids of `proving/igneum-prove/elf/manifest.json` as master holds it (shard `0x2b1a81cb...`, pinned 2026-10-05T16:20:38Z). The fin-proof lane's worktree carries a re-pin (shard `0x39db9d96...`, pinned 2026-10-07T08:03:43Z, not on master). If that re-pin merges before the go, the two ids and the digest move once more (one `print_testnet_object` run, this lane's) | whoever merges the re-pin tells this lane | OPEN | +| 9i | The suites on the final tree (fork bfcaf6a2, 15:1x UK, bounded on build-2): consensus-core 144, consensus 123 (plus the one pre-existing red of 9f), exec 31, mining 52, p2p-flows 37, pow 16, rpc-core 134, txscript 158, kaspad 2; the five gate tests (the identity test, the genesis hashes, the print, the genesis-forward digest test, the silent-split equality) 5 passed at the gate class on build-1, digest `4fbb2152...`. Earlier in the day on the interim trees: grpc-core 14, p2p 23, miner 19, utxoindex 9, index-core 9, database 22, pskt 5 | this lane | GREEN | +| 9f | A pre-existing red, not the object's: `processes::pruning_proof::igneum_m20_tests::witnesses_are_checked_in_epoch_order_under_their_own_seeds` fails under `--features igneum-pow` on the untouched `release-0.3.18-node` e69e8a39 (08:52 UK, box load under 10) and on the decimals base eec34ac3 (that lane's record); no lane's suite compiles the feature-gated test. Owner: the m20 tests' lane | the consensus engineer | OPEN, recorded | +| 9c | Mission item 8: the genesis forward-compatibility fields (the sig_scheme byte, the W5 key-succession item, the cache rung on the ladder behind its own switch), lane `genesis-forward` (daa61847 to f95178a1 and ff06c05c on the fork; its gates: consensus-core 124, consensus 114 twice on build-2, the fast-time harness's known-failed FAIL and pass PASS on build-1). The testnet object RE-ARMS ON EACH CUT (the ruling of 19:2x UK): whatever the 0.3.23 object compiles for these four is what the seeds take | lane `genesis-forward`, the build-server lane re-arms | re-arms on each cut (this lane's re-cut had the four at 0, digest `63faee44...`) | +| 9k | The genesis message: the go object's genesis carries the FINAL 5 October message, never the 4 October proposal's text (the coordinator's order, 19:2x UK, to the node lane through the build-server lane); the hash and the digest follow it | the node lane, the build-server lane re-arms | ORDERED 19:2x UK, not yet read back | +| 9l | The base unit on the testnet: 18 decimals, the founder's word at 21:35 BST 7 October 2026 (through main). The go object is re-cut on the 0.3.23 line (7c7489ac's node pin 2720d8d2, or the 0.3.24 line if the v5 object lands first; the shipper names which) at 18: the decimals lane's code merged, the EmissionSchedule and every per-tier row at 18, the UTXO/EVM scale factor fixed and tested known-failed first on an 8-decimal fixture, the FINAL 5 October genesis message, the cache-rung field at 0, class v5 at 0 if its Devnet 3 crossing reads clean, chain id 4462. This lane's 7 October re-cut (fork testnet-genesis-2-node 59d05bf2) is that work on the 0.3.18 line and was handed to the node lane for the cherry-pick; its gates (9g, 9h, 9j) are the 18-decimal record until the re-runs on the go object | the founder (decided), the node lane re-cuts, the build-server lane re-arms | DECIDED 21:35 BST: 18 | +| 9m | GitHub: the organisation's owner account is suspended since 18:02 BST 7 October 2026 (pushes 403, "Your account is suspended"); the founder's ticket is open; every lane lands on the box mirror (`build`) with the box gate as the verdict until it lifts; this file's branch is on the mirror and the Mac, GitHub at 1f4793c1 | the founder | OPEN | +| 9d | Windows: `igneum-prove-host` beside every Windows node (verification from genesis); PC 1's node refuses to start without it | the release engineer (the 0.4.0 package) | NOT DONE: to check in the 0.4.0 Windows installer | +| 9j | The two-node 18-decimal gate on the FINAL binaries (fork e6dd3afd, igneumd 58f96049..., igneum-miner 5625caee...; `tools/fleet/base-unit-gate.sh` 72b02b48, the GPU form on a RunPod RTX A5000 rented and run by the fleet lane): PASS at 15:19 UK, 7 October 2026: 322 chain blocks in 600 s, both nodes on one sink and one exec tip (0x142), the 30 inspected payloads all the 18-decimal schedule, 491 segment rewards against the schedule at each blue block's own DAA with 0 wrong, eth_getBalance 3,929.11134259 IGN (3,929,111,342,592,592,592,602 wei) equal on both nodes and to the sum of the rewards; both node heads print `Base unit: 10^18`, the digest `4fbb2152...` and `igneumd/2.1.0-e6dd3afd`, node B's exec line the genesis `01294fd3...`. The known-failed form (the 8-decimal schedule, 420 s) FAILED as it must at 15:27 UK: payloads wrong 30 of 30, rewards wrong 305 of 305. The logs: ~/igneum-fleet/tn-gate/out/ on the Mac | the fleet lane ran it, this lane reads it | PASS (the cut's closing gate) ON THE 7 OCTOBER RE-CUT; RE-RUN ON THE GO OBJECT 5b673577 ON 8 OCTOBER, GREEN (row 9p) | +| 9h | The two-node 18-decimal gate on the re-cut binaries (`tools/fleet/base-unit-gate.sh` 72b02b48, the GPU form: RunPod RTX 3090, driver 580.65.06, the hive CUDA worker, rented and run by the fleet lane): PASS at 10:08 UK, 7 October 2026, on igneumd 8a6f1f56... and igneum-miner 726cf290... (fork commit f1717419): 577 blocks in 600 s, 421 chain blocks, both nodes on one sink and one exec tip (0x1a5), the 30 inspected coinbase payloads all the 18-decimal schedule (day-0 block 10 IGN = 10^19 base units), 80/20 exact on 18 of 18 single-payee coinbases, 577 segment rewards checked against the schedule at each blue block's own DAA with 0 wrong, eth_getBalance 4,617.53654629 IGN (4,617,536,546,296,296,296,298 wei) equal on both nodes and to the sum of the rewards; both node heads carry `Base unit: 10^18`, the digest `80af8aa1...`, the ladder active at rung 0, fees v1 from DAA 0 and proof verification from DAA 0 under the pinned ids. The first run of the same form (09:4x UK) read 165 of 561 rewards one ramp step low: the gate's check 5 still priced every reward at the chain block's DAA, fixed in 72b02b48 (each blue block its own DAA, the per-block rule). On the testnet object itself no voter exists inside a run (the 30-day window), so this line shows the layout, the switches and the identity without the bonus; the devnet-suffix line (9g) is the proof of the identity under the bonus | the fleet lane ran it, this lane reads it | PASS; the known-failed form (GATE_EXPECT_DECIMALS=8, the 8-decimal schedule against the same chain, 420 s) FAILED as it must at 10:15 UK: payload subsidies wrong 30 of 30, every segment reward wrong; the pod destroyed on this lane's done line ON THE 7 OCTOBER RE-CUT; RE-RUN ON THE GO OBJECT 5b673577 ON 8 OCTOBER, GREEN (row 9p) | +| 9p | The pin's first pod run (8 October 2026, 09:45 to 10:00 UK, RunPod 3090 2rls7gfwii2d3g, the fleet hand): the fast-time line on 5b673577's pair read 14 of 16 checks true (start lines, one digest, class v4 at rung 0 ten epochs, 0 rejected, one sink on five nodes, the first lock at DAA 144, the silent key paid 72/28 on 127 blocks and the voters 80/20 on 318, the bridge identity exact for all five, a leave accepted and effective within the delay, no pause after it) and two false that were the harness's: the object-byte check expected 0 where the pin stamps byte 7 from genesis (the Devnet 3 shape), and "finality active at the end" sat on scenario arithmetic (one silent key of five at a quarter of the window held over a third of a 120-block window on a shared pod CPU, and the rule paused as designed); fixed at testnet-genesis-2 940d91de (the stamped byte read from the node's line; six keys). The two-node gate was void on that pod (its GPU dead for CUDA, cuInit 999: a host fault, the pod retired), and it showed base-unit-gate.sh dialling the public seeds (refused on the digest, harmless), fixed at 940d91de with `--nodnsseed`. Both gates re-run on pod 2 (tn-gate-0324b, RunPod A5000 secure yiu8x5dnh01g2y, driver 580.173.02, rented 10:29 UK after four 3090 hosts failed cuInit at rent; the hive 0.3.24 CUDA worker at 41.65 MH/s), the tree at 940d91de: the two-node 18-decimal gate form 1 PASS at 10:43 UK (340 chain blocks, 30 payloads at the 18-decimal schedule, 80/20 exact on 20 of 20, 512 rewards against the schedule at each blue block's own DAA with 0 wrong, eth_getBalance 4,097.20887963 IGN = 4,097,208,879,629,629,629,622 wei equal on both nodes and to the rewards' sum, both heads on `b2e856ed...`, no seed dialled); the fast-time line 15 of 16 true (six keys: the stamped byte 7 on 587 blocks and no ladder bits, class v4 at rung 0 ten epochs, 0 rejected, one sink on six nodes, the first lock at DAA 142 and lock 19 at the run's end, the silent key paid 72/28 on 91 blocks and the voters 80/20 on 352, the bridge identity exact for all six, a leave accepted and effective, no pause after it) with the one false check the harness's own stop order (its final read came after the voters had exited with the run; fixed at b8074151: the miners outlive the run and the read is taken as it ends); form 2 (the 8-decimal known-failed form, 420 s, 10:44 to 10:51 UK) FAILED as it must: 286 blocks, the sinks, the exec tips (0xbb) and the balances equal on both nodes, 30 of 30 payloads and 285 of 285 rewards wrong by exactly 10^10 (the 18-decimal chain read against the 8-decimal schedule), both heads on `b2e856ed...`; form 1's remaining lines: 513 blocks, exec tips 0x154 on both, exit 0. The object line's re-run on b8074151 (10:47 to 10:57 UK): SUMMARY PASS, every check true (eleven epochs at class v4 rung 0, the stamped byte 7, the first lock at DAA 141, the silent key 72/28 on 89 blocks and the voters 80/20 on 377, the bridge identity exact for all six keys, a leave accepted and effective, 0 rejected, one sink on six nodes at 613 blocks) | the fleet hand ran, this lane read | ON THE PIN 5b673577: form 1 PASS, form 2 FAIL as it must, the fast-time line PASS (rows 9g, 9h and 9j re-run and green on the go object as landed) | +| 9g | The fast-time line of the object (`infra/fast-time/testnet-object.mjs`, a devnet-suffix network on igneum-build-1 at the 60x profile: 5 nodes, four voting keys and one `--no-vote` key, every switch of `testnet-object.json` from genesis, the fast-time finality profile with leave delay 60, the testnet schedule at the devnet's unit): PASS at 11:12 UK, 7 October 2026, run 10 on the archive binaries (igneumd 57ad7dc2..., fork 5c25c1fb): the start-up lines and one digest on every node; class v4 at rung 0 (27 passes) through ten epochs, no ladder bits, the object byte 0 on 551 blocks; 0 rejected, one sink on five nodes; the first lock at DAA 142 (172 s); the silent key's 87 blocks paid the bonus split on the UTXO side (72 percent of the subsidy at each block's own DAA, 720,118,333 sompi at DAA 142 against 800,131,481 for a voter) and the voters' 320 blocks the plain split; the bridge identity exact for all five miners over the chain (UTXO payments x 10^10 = execution credits less the tip's own: 96,832,949,992 sompi against 968,329,499,920,000,000,000 wei for voter a, and so on); a signed leave accepted at DAA 212, its key out of the voter count (5 to 4) at DAA 351, no pause longer than one second after it, finality active at the end at lock 18. The road to it: run 1 (pre-fix binaries) showed the executor crediting 80 percent to the silent key while the coinbase paid 72 (the N7 finding), run 7 the side blues credited one ramp step high when the per-block switch was left out of the profile (the N8 shape), run 9 every check green but the harness's own pause reading (one-second reason flickers at each new lock, corrected to consecutive seconds). On the testnet object itself the weight window is 30 days, so this line is the proof of the bonus and the identity before the go | this lane | PASS; the known-failed forms are on record from the same morning: run 1 on the pre-fix binaries (the silent key credited 80 percent on the EVM side against 72 on the UTXO side, every other check green) and run 7 on the fixed binaries with the per-block switch left out of the profile (every miner's credit above its payments by the side-blue steps). A binary that carries the per-block field without the bonus fix does not exist (the pre-fix binaries refuse an override naming the field), so no third form runs ON THE 7 OCTOBER RE-CUT; RE-RUN ON THE GO OBJECT 5b673577 ON 8 OCTOBER, GREEN (row 9p) | +| 9n | THE LAST STEP BEFORE THE GO (the coordinator's planned step, 22:4x UK, 7 October 2026): the object above holds the class v5 floor at never because Devnet 3's v5 crossing has not happened; the ruling is class v5 at 0 on the testnet IF that crossing reads clean (at DAA 68,400, about 12:54 BST on 8 October after the floor's last re-cut; the go not before the evening of 8 October). After the crossing's read the node lane re-cuts the testnet object once more with `program_class_v5_activation_daa` 0 (a new digest, the genesis unchanged), this table's digest row and the runbook's `--digest` are updated from the new binary's print, and the build-server lane re-arms the seeds on the pull-path dry run with the new binaries and sha. That re-cut object is the one the go uses; the object above is not placed on a seed if the crossing reads clean. If the crossing does not read clean, the object above stands and the v5 floor stays at never | the node lane re-cuts, this lane the table, the build-server lane re-arms | DONE 8 October 2026: the crossing read clean at 12:57 UK; the re-cut 0d05e795 landed 13:48 UK (digest `1da30c10...`, byte 6, genesis unchanged, the node lane's six suites green by 14:04 UK, its canary clean); this table and the runbook updated 14:10 UK; the seeds' re-arm on the pull-path dry run of 0d05e795's seed-class pair is the build-server lane's next step (row 9q) | +| 9o | Keyed payout addresses (the fleet lane's defect line of 8 October 2026, 09:4x UK, from Devnet 3: `tools/fleet/fleet.py` line 83 wrote a random payout address with no key for every rented box, so 578,000 IGN of Devnet 3 rewards by 22:28 UK sat on addresses nobody can spend from, and the load generator ran on the 432 IGN dev-fee key; the fleet's keyed-throwaway fix lands 8 October): before the go, every payout address in the testnet object and in anything the seeds or the first miner run has a key held by a named holder (the seeds mine nothing and name no payout; the first miner of step 10 pays the app's own keyed wallet or a named key; the dev-fee address is the app's). The faucet: the testnet genesis carries one IGN to OP_FALSE (unspendable) and no allocation, so a faucet is funded by the first keyed miner's blocks, never at genesis; a genesis allocation would be the founder's word and a re-cut of the hash; the chain-side faucet or a funded key for load tests is logged for the 0.3.25 line (the node lane, 09:4x UK) | the fleet lane (its fix), this lane (the first miner's key), the founder (any allocation) | THE FIRST MINER'S KEY HELD 16:22 UK, 8 October: generated by `igneum-miner keygen` (the 0.3.25 miner, acaf08b0's) on build-1 straight into a file, moved to the Mac at `~/.config/igneum/testnet-first-miner.json` (0600, the founder's), deleted on the box; payout address `0x216fee620b752b73163eb8c6501afbdb4f19f80b`; only the address goes to the miner pod. VOID and never to be used: the pair that `keygen --help` printed to a transcript at 16:21 UK (address `0xd682efb0...`); no payout address goes in any object without a key behind it (the node lane's line); the testnet genesis carries no allocation | +| 9q | The seeds' re-arm on the go object: the build-server lane builds the seed-class pair from 0d05e795 (glibc 2.34, the commit string twice, igneum-pow 1c420786) on build-1, runs the runbook's dry run on seed1, seed2 and seed3 with `--digest 1da30c10...`, `--commit 0d05e795`, `--genesis 01294fd3...`, the pair's shas asserted, the genesis read-back from `getBlockDagInfo`; `--go` only on the founder's word | the build-server lane | FALLBACK PAIR DONE 14:26 UK, 8 October: the seed-class pair from 0d05e795 (zig glibc 2.35 ceiling, GLIBC_2.34, built on build-2 while build-1 holds quiet for Devnet 3's move; igneum-pow/src only, the freeze 1c420786's content) staged at `/srv/artefacts/0324-tn-0d05e795/seed/`: igneumd sha256 `9b4641585e2caa5da4f81ee42ef624f826f70373922005a4efc44a41d63b7f19` (56,890,448 B, the commit string twice), igneum-miner `d5a5bc9edee54c5b01b769985c42c407ee6c4d4cdd9f1b24cde7b642c7bf92dc` (12,270,136 B); the bare start prints "stamps object version 6 into its headers (block version 1538)", `Base unit: 10^18`, the digest `1da30c10...`, the follower at genesis; the dry run (`--wipe-genesis --genesis 01294fd3... --commit 0d05e795`, no override, nothing `--go`): seed1 195.201.35.33 rc 0, seed2 5.161.232.205 rc 0, seed3 5.223.52.210 rc 0, "DRY RUN, nothing touched", each box answering as its seed, active a9ea25f8ada2 (the `getBlockDagInfo` genesis read-back runs at the real pass). This pair is the FALLBACK by row 9r's ruling. THE GO PAIR, from acaf08b0 (built on build-1 15:46 UK, staged and read 15:50 UK): `/srv/artefacts/0325-acaf08b0/seed/igneumd` sha256 `cb35df68997f407c3c371617384b038dadd3213b00cb590db7f542dc77c6e5c4` (56,942,544 B, the commit string twice, zig glibc 2.35 ceiling, GLIBC_2.34), `igneum-miner` sha256 `0b7e9d73cecc5a4441fba421105d1e62efd51ebd46f57ce7f50aa18b243b231a` (12,408,968 B), IGNEUM_POW_FINGERPRINT `cbc5bd0aa10585c8...` in both (the freeze 1c420786). The bare start on build-1 on an empty data directory (`--testnet`, loopback ports), in order: "stamps object version 6 into its headers (block version 1538)", `Base unit: 10^18`, the digest `1da30c10...`, `igneumd/2.1.0-acaf08b0`, "[igneum-exec] exec sync: no snapshot to resume from ...; the follower starts at genesis", "[igneum-exec] genesis 01294fd3... executed: chain id 4462, registry at 0x...0210, state root 0x7...", "[igneum-exec] class v5: the state stream after genesis 01294fd3... (epoch 0's reference) is published"; no "waiting for consensus to sync" line in 40 s. The 6e04f7fc pair void and unstaged; ba294c98's stands only as the known-failed base. THE THIRD DRY RUN DONE 16:03 UK, 8 October, on the go pair after both gates (the node lane's set green 15:59 UK, block one mined 16:00 UK), the binary read back `cb35df68997f407c` before the run, the runbook's line exactly, no override, NO `--go`: seed1 195.201.35.33 rc 0 after 1 s, seed2 5.161.232.205 rc 0 after 1 s, seed3 5.223.52.210 rc 0 after 2 s, each "DRY RUN, nothing touched; box answers as seedN active a9ea25f8ada2", exit 0 (log: the build-server lane's `testnet0325d/dryrun-acaf08b0.log`). THE SEEDS ARE ARMED ON THE GO PAIR and move only on the founder's word through main | +| 9r | The go seeds' node code: `release-0.3.24-node` at 0d05e795 carries none of the 0.3.25 node fixes (the ring check, the snapshot stamp, the proof-map window, the chain-id admission, rule 19's fingerprint). The node lane's line (14:0x UK): the go seeds should run the 0.3.25 pin's node code with this object, which is 0d05e795's one params change merged onto c9ad753a as one commit on `release-0.3.25-node` plus its gates (about 25 minutes), first thing after Devnet 3's move read-backs. The object does not change (TESTNET_PARAMS identical; the digest must read back `1da30c10...` from that binary or the row moves); the seeds then take that pair, and rows 9g/9h/9j re-run on it. RULED by the coordinator (14:2x UK, 8 October): the go seeds run the 0.3.25 pin's node code, after Devnet 3's move read-backs; a seed without the chain-id admission, the ring check and the proof-map window is today's fault class and does not go out; 0d05e795's own pair stays armed as the fallback only. So the go pair is the build-server lane's seed-class build of that one commit on `release-0.3.25-node`, its dry run on the three seeds (the third dry run of this runbook), and rows 9g/9h/9j on it from a pod; the runbook's `--commit` becomes that commit when it lands, `--digest` stays `1da30c10...` | the node lane cuts, this lane reads the digest back and moves the rows, the build-server lane builds and dry-runs, the fleet hand gates | THE CUT LANDED 15:0x UK, 8 October: `release-0.3.25-node` ba294c98 on both mirrors = c9ad753a + f8da7515 (the cold-restart fix, the Devnet 3 hotfix, its gates green 14:50 UK) + f41f48a7 (row 9t's miner fix: the state provider's default follows the node's network read over gRPC, 26790 devnet and simnet, 26890 testnet, 8545 mainnet; the refusal names the address and `--exec-rpc`; `mine --help` names the flag; the known-failed test `exec_rpc_default_tests::the_state_provider_default_follows_the_nodes_network`, the old devnet default on the testnet asserted wrong first; miner suite 30 on build-2 at 15:03 UK) + ba294c98 (0d05e795's params change cherry-picked with -x: class v5 at 0, CLASS_SIGNAL_V5, the digest constant 1da30c10...). Read back from the mirror by this lane: the pinned digest and genesis constants unchanged from 0d05e795, TESTNET_PARAMS class v5 at 0 with the v5 signal. Its gates dispatched 15:04 UK at gate priority (the artefact to `/srv/artefacts/0325-ba294c98/node-lane`, six suites, the Devnet 3 canary with the mixed-version step against f8da7515, the testnet canary reading 1da30c10... and byte 6), due by about 15:45 UK; the go pair is not shipped before they are green | +| 9s | The gates on the go object's pair (0d05e795: igneumd `b76d8671...`, igneum-miner `0e67237f...`): the two-node 18-decimal gate (GPU form, `tools/fleet/base-unit-gate.sh` 940d91de, plus the known-failed 8-decimal form) and the fast-time line (`infra/fast-time/testnet-object.mjs`, `--testnet-params` as on 9p) on a fresh pod, the fleet hand; the node lane's six suites already green on it | the fleet hand runs, this lane records | RUN on 0d05e795's pair (pod 3, tn-gate-0324c, RunPod 7e2jbcma9apjne, RTX A5000, driver 570.211.01, USD 0.27/h, rented 14:50 UK): the two-node gate VOID on both forms (0 blocks: row 9v, the class v5 genesis bootstrap; the relay 26790 to 28190 of row 9t proven, both nodes printing byte 6 and the digest `1da30c10...`); the object's fast-time line at b5925261 (the harness's class v4 network, row 9u) PASS 16 of 16 at 15:02 UK: epochs e0 to e10 v4 rung 0, first lock index 5 at DAA 144, silent rows 88 and voting rows 367 priced right, six bridges true, leave accepted 6 to 5 voters, blocks 605 chain 494, rejected 0 on six nodes, one sink at 604 on all six. The byte 6 run (c5fe28e4) on the same pod reproduced row 9v with no relay. ON THE GO PAIR acaf08b0 (pod 3, run 3, 15:50 to 16:00 UK, gate script b38f1ad3, no relay): form 1 PASS: both nodes agree (sink identical, 502 blocks), exec tips A and B 0x147, 30 of 30 coinbase subsidies right at one IGN = 10^18 (day-0 block 10 IGN), 80/20 exact on 16 of 16 single-payee coinbases, 502 rewards on the execution layer with 0 wrong, eth_getBalance equal to the sum (4017.16194444 IGN) on both nodes, votes sent 15 accepted 15, both nodes on the digest `1da30c10...` stamping byte 6, 3.07 MH/s wall on the A5000. Form 2, the 8-decimal known-failed form (GATE_EXPECT_DECIMALS=8, 420 s, 16:00 to 16:08 UK): FAIL as it must: block one mined (the genesis stream published at 15:00:53Z, exec tip 183, no refusal), both nodes agree at 287 blocks, checks 3 and 5 wrong by exactly 10^10 on every row (payload subsidy 10003310185185185185 against the 8-decimal schedule's 1000331018; segment rewards 8 IGN at 10^18 against 800000000; 30 of 30 and 287 of 287 wrong), 80/20 exact on 15 of 15, both nodes on `1da30c10...` stamping 6, "FAIL (see above)". The script's exit on that path is 1 (`exit 1` after the FAIL line; the EXIT trap `stop_all` calls no exit, so bash keeps it); the hand's runner read 0 from its own pipeline, so a caller reads the script's status direct or its FAIL lines, never a pipeline's. The byte 6 fast-time line (c5fe28e4, six one-box nodes, class v5 from genesis, 16:08 to 16:18 UK): SUMMARY PASS 16 of 16: epochs e0 to e9 class 5 at rung 0, first lock index 5 at DAA 143, silent rows 60 and voting rows 354 priced right, six bridges true, leave accepted 6 to 5 voters, blocks 580 chain 452, rejected 0 on six nodes, one sink 7300ce9f at 579 on all six, object_bytes {6: 574}, every node stamping 6 with the genesis stream published, refusals 0. EVERY ROW ON acaf08b0 GREEN; GATES CLEAN sent to main 16:2x UK | +| 9t | The miner's class v5 state lookup (found by the pod gate on 0d05e795's pair, 14:52 UK, 8 October): `RpcStateProvider::new` defaults to `http://:26790`, the DEVNET exec port, on every network (`igneum/miner/src/main.rs` 981-985 at 0d05e795), while the testnet node's exec RPC defaults to 26890 (`igneum/exec/src/config.rs` 86-91); the `--exec-rpc` override exists (main.rs 3226) but is absent from `mine --help`. On the pod (node A's eth_ RPC on 28190) the miner logged "class v5 needs the execution state after the epoch's seed block 01294fd3... (day 20734): connect 127.0.0.1:26790: Connection refused (os error 111) ... asking again every 2 s" and the worker never got a job; the hand ran the gate through a loopback forwarder 26790 to 28190, so the gate lines on this pair stand for the object. Impact: the seeds mine nothing, the cut-over is unchanged; a first testnet miner on a default node (step 10) cannot mine class v5 blocks at all, the plug-tune-play class. The call put to the node lane and main: the default follows the network (`default_evm_rpc_port` of the node's network), `--exec-rpc` documented, the refusal names the address and the flag, in the 0.3.25 go cut | the node lane fixes in the 0.3.25-line go cut | RULED by the coordinator (15:0x UK, 8 October): the go WAITS for the fix in the 0.3.25-line go cut: the default follows the network's exec port (26890 on the testnet), `--exec-rpc` documented in `mine --help`, a known-failed test on the default per network; a first miner that cannot mine on a default node does not ship. The cut not yet landed at 15:0x UK | +| 9u | The fast-time line does not exercise class v5: `infra/fast-time/testnet-object.mjs` copies only `program_class_v4_activation_daa` and the v4 window from the object onto the 60x profile (lines 89-90), so its network stamps 7 and runs class v4 while the go object stamps 6 (the pod's object run of 14:5x UK read "stamps object version 7" on every node and passed its 16 checks as a class v4 run). To close: carry `program_class_v5_activation_daa` from the object, read the stamped byte 6, and run the five one-box nodes' miners against their own exec RPC ports, which needs row 9t's miner default or the `--exec-rpc` flag per miner. Until then the two-node gate (through the forwarder) is the proof of class v5 mining on the pair, and the fast-time line proves the object minus byte 6 | this lane (the harness), on the same cut as 9t by the ruling | RULED 15:0x UK: closed on the same cut; the harness change (the v5 keys carried, `--exec-rpc` per one-box miner) landed at c5fe28e4 on this branch; its first run on the warm pod (15:05 to 15:08 UK, 0d05e795's pair) reached the object's class and reproduced row 9v with no relay; its run on acaf08b0's pair (16:08 to 16:18 UK) PASS 16 of 16 at class 5, byte 6 on every node (row 9s). CLOSED | +| 9v | GO BLOCKER (found 15:04 UK, 8 October, by the two-node gate on 0d05e795's pair with row 9t's relay in place): a chain with class v5 from genesis cannot mine its first block. The miner's class v5 path asks the node's exec RPC for the state after the epoch's seed block, which for epoch 0 is genesis, and a fresh chain's executor has published no stream after it; verbatim: "class v5 needs the execution state after the epoch's seed block 01294fd3... (day 20734): exec RPC http://127.0.0.1:26790 gave no stream for block 01294fd3...: no published state stream after chain block 01294fd3... (the executor has not passed that epoch's cut, or the block is not on its chain) (the node's exec RPC); this node cannot validate or mine class v5 blocks until its executor holds it; asking again every 2 s". Why no gate caught it: Devnet 3 crossed to v5 at 68,400 with state behind it; the 5b673577 object's green gates ran class v4 from genesis; the canaries handshake and do not mine; so byte 6 at DAA 0 had never been mined by anything. A pointer: the 5 October binary printed `[igneum-exec] genesis executed` at start and this build does not (the build-server lane's read of 10:2x UK). Routes put to the node lane and main: (a) the node publishes the genesis execution state as the stream after the genesis seed block on start-up (object and digest unchanged; a fix on the ba294c98 line plus a gate that mines block one on a fresh v5 chain); (b) class v5 from the first epoch boundary with class v4 for epoch 0 (a new digest, a re-cut, the seeds re-armed again). The go pair is nobody's until block one mines on a fresh v5 chain; the earliest-go time moves by the fix | the node lane (the fix), this lane (the pod re-run), main (the route) | RULED by the coordinator (15:1x UK, 8 October): ROUTE (a): the node publishes the genesis execution state as the stream after the genesis seed block at start-up, object and digest unchanged, on the ba294c98 line, with a gate that mines block one on a fresh class v5 chain (the test that was missing) and its known-failed run first; route (b) only if the node lane says (a) is not a same-day fix by 16:00 UK; the go pair is whichever mines block one on a fresh v5 chain; nothing mines until the founder's word. Reproduced with no relay by the byte 6 fast-time line at 15:05 UK (six one-box nodes on a devnet-suffix genesis `234e082d...`, each miner with `--exec-rpc`, the same refusal on each, the template class 5 at DAA 0, no block in two minutes): the refusal is the node's on any port and any genesis. THE FIX LANDED 15:19 UK: `release-0.3.25-node` 6e04f7fc (both mirrors) = ba294c98 + one commit in `igneum/exec/src/service.rs`: `ExecState::capture_genesis_state` records genesis as epoch 0's capture and publishes its IGSD1 stream under the genesis hash the moment `execute_genesis` finishes (final by construction; the node prints "[igneum-exec] class v5: the state stream after genesis (epoch 0's reference) is published"), the capture under the same retention as every other; no params, object or digest change (1da30c10..., byte 6). The known-failed test `service::class_v5_tests::the_state_after_genesis_is_published_at_once_for_class_v5_from_genesis` (nothing served after genesis before the fix, asserted first); exec suite 56 on build-2 at 15:17 UK. Its artefact and gate set (six suites, both canaries) dispatched 15:19 UK, the pair at `/srv/artefacts/0325-6e04f7fc/node-lane` by about 15:32 UK. The block-one gate: `tools/fleet/base-unit-gate.sh` now passes the miner `--exec-rpc` for node A's own exec port and prints the node's genesis-stream line, the miner's first block and node A's exec tip after mining, failing on tip 0; the known-failed run is the same script on ba294c98's pair (`/srv/artefacts/0325-ba294c98/node-lane`: igneumd `74ae96c6...`, igneum-miner `bbabfa91...`, the 0.3.25 miner's network default, refusing at genesis), then 6e04f7fc's pair for block one, both on the warm pod. THE KNOWN-FAILED RUN READ AS DESIGNED (pod 3, 15:24 to 15:32 UK, ba294c98's pair, the gate script e88aa875, GPU form, the relay down and 26790 confirmed closed): the miner reached 28190 by the script's own `--exec-rpc` and refused at genesis ("exec RPC http://127.0.0.1:28190 gave no stream for block 01294fd3...: no published state stream after chain block 01294fd3... ... asking again every 2 s"), node A printed no genesis-stream line, exec tip 0, "FAIL: block one was never mined on a fresh class v5 chain (exec tip 0)", 0 chain blocks; both nodes on the digest `1da30c10...` and byte 6; the miner stopped by pid after eight minutes in the refusal loop (its window counts mining, not waiting). Two script defects it showed, fixed in the next commit of this branch: the exit code read 0 after the FAIL lines (set -e aborted check 3 at zero blocks before the final FAIL line; now a tip of 0 exits 1 at once) and the miner line needed a wall-clock timeout (now SECS + 180). Run 2, block one on 6e04f7fc's pair (15:32 to 15:35 UK): NO BLOCK ONE EITHER. Node A's executor never starts on a fresh chain: "[igneum-exec] exec sync: sink 01294fd3... is chain block 0; pruning point ... Some(0) (DAA 0)", "no snapshot to resume from ... the follower starts at genesis", "waiting for consensus to sync before the executor starts (the sink is 311555 s old)" repeated each minute; no "genesis ... executed", no "state stream after genesis ... is published" (the string is in the binary, never reached); the miner's refusal unchanged; GPU 0 percent, 0 blocks; stopped by pid. The read: the executor's start waits for consensus to be synced; a fresh chain whose sink is the genesis (3.6 days old today, older at the go) is never synced until a block comes, and no block comes without the stream: a loop with no exit, and the publish-at-start fix sits behind the wait. The seeds at the go are fresh chains, so route (b) alone would not help either (class v4's first epoch only differs by never asking for state). Needed, sent to the node lane and main 15:3x UK: the executor starts (or executes genesis and publishes its stream) when the sink is the genesis or when unsynced mining is enabled, regardless of the sink's age, the known-failed test asserting the wait first; then the pod's block-one line (everything staged on the warm pod, hold to 17:50 UK). RULED by the coordinator (15:3x UK): route (a) stays and the fix is as stated: the executor executes genesis and publishes its stream when the sink is the genesis, and starts whenever unsynced mining is enabled, regardless of the sink's age; the sync wait applies only to a node that has synced something; the known-failed test asserts the wait first. The same class as the afternoon's cold-start deadlock (f8da7515: a guard keyed on sink age that no fresh or paused chain can satisfy), so both are fixed under one rule: NO GUARD MAY WAIT ON A CONDITION THAT ONLY A BLOCK CAN PRODUCE. Same day; the go moves by the fix plus one pod run (about 35 minutes after the binaries); nothing mines until the founder's word. THE FIX LANDED 15:43 UK: `release-0.3.25-node` acaf08b0 (both mirrors) = 6e04f7fc + one commit in `igneum/exec/src/service.rs`: `cold_start_replays` takes `sink_is_genesis`, so a node whose sink IS the genesis executes genesis (and, through 6e04f7fc, publishes the stream after it) whatever the genesis's age; the wait stays only for a node that synced a chain it does not hold from genesis; the known-failed test `cold_restart_tests::a_fresh_chain_whose_sink_is_the_genesis_starts_the_executor_whatever_the_genesis_age` ("the sink is 311555 s old" refused first); the same commit carries the Devnet 3 snapshot fix (every capture from the current epoch's reference up); node-side only, no params, object or digest change. Exec suite 57 on build-2 at 15:42 UK; the artefact and the full gate set with both canaries dispatched 15:43 UK, the pair at `/srv/artefacts/0325-acaf08b0/node-lane` by about 15:58 UK. NOT in this cut (the node lane's call, put to main 15:4x UK): the "starts whenever unsynced mining is enabled" half of the ruling, since the exec service holds no such flag today and a genesis sink starts the go seeds without it; CONFIRMED by the coordinator (15:4x UK): acaf08b0 is the go cut; the "unsynced mining enabled" half goes on the next node line as a named item. BLOCK ONE MINED (pod 3, RTX A5000, the gate script b38f1ad3, no relay, 15:50 to 16:00 UK, acaf08b0's pair igneumd `9e4217f3...` and igneum-miner `bbabfa91...`): node A "genesis 01294fd3... executed: chain id 4462, registry at 0x...0210, state root 0x7e37a9fb..." then "[igneum-exec] class v5: the state stream after genesis 01294fd3... (epoch 0's reference) is published" in its first follower pass (14:50:11Z), zero "waiting for consensus to sync" lines; the miner "1791471081.393 ACCEPTED block nonce=0x46956ab5003f48ed (gpu worker, cpu re-check ok, identity gate)" 70 s after start, no refusal line; node A's exec tip 327 after 600 s; the 18-decimal gate PASS at 327 chain blocks (row 9s). The missing test now exists and passes on a fresh class v5 testnet chain | +| 10 | The first miner: one app on the testnet (PC 1 or PC 2 with the 0.4.0 build, or `igneumd --testnet` plus `igneum-miner --network testnet` by hand) produces block 1; the seeds relay it, `health.sh` shows blocks=1 on all three, `synced=True`; note the young-window join fault: a node that joins a chain younger than its finality window sees `synced=False` until blocks pass genesis, which is the no-blocks state, not a fault | the founder says go, the miner-community lead starts it | NOT DONE: nothing mines until the word | | 11 | Watch: `NET=testnet ./health.sh --watch`, the RPC's `eth_blockNumber`, the DAA after 600 blocks (the launch difficulty `0x1d100000` is sized for a few hundred MH/s) | the infrastructure engineer | ready | Legal is out of scope here (the founder: "all but legal"). +## The seeds' cut-over to the re-cut genesis (prepared 7 October 2026; runs only on the founder's go) + +Nothing below has been run against a seed. The seeds take no override file, so the cut-over is one binary and one +wipe per seed. Order: seed 1 last (it serves the public RPC), the other two first, an hour between is not needed (the +chain is at height 0 and no miner exists). + +| # | Step | Command (from `infra/seed-nodes`, `NET=testnet`) | Read back | +|---|---|---|---| +| 1 | Build the seed binary from the fork branch `testnet-genesis-2-node` on the box for Debian 13 (glibc 2.41 on the seeds; a native 2.39 build also runs there, the 5 October seeds took a PC build at 2.39) | `cd vendor/igneum-node-testnet-genesis && ../../tools/build-remote.sh --ship seed` (artefacts in `target-remote/`), copy `igneumd` and `igneum-miner` into `infra/cross/out/` | `igneumd --version` names the commit; `sha256sum` recorded in this file at the go | +| 2 | Stop the unit and wipe the data directory on seed 2 and seed 3 (the 5 October chain is genesis alone) | `ssh root@ 'systemctl stop igneumd && rm -rf /var/lib/igneum/igneum-testnet-1'` (the directory name is the network id under APPDIR; check with `ls /var/lib/igneum` first; wipe only that directory) | the directory is gone | +| 3 | Install the binary and start | `NET=testnet BUILD_WHERE=cross ./provision-seed.sh seed2.testnet`, then `seed3.testnet` (it uploads `infra/cross/out/igneumd`, refuses a glibc the seed cannot run, writes the unit and starts it) | the unit's log: `Base unit: 10^18`, `Consensus params digest: `, `genesis 01294fd3...` in the `[igneum-exec]` line, `Proving: consensus proof verification from DAA score 0`, `Latency ladder active` | +| 4 | Seed 1: the same two steps, then the public RPC check | `NET=testnet ./health.sh`; `curl https://rpc.testnet.igneum.network -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'` reads `0x0`; `eth_chainId` reads `0x116e` | three seeds, 2 peers each, height 0, every digest line equal | +| 5 | The cross-check that the old chain is gone | a 5 October binary (`igneumd 1c19441d`) pointed at a seed is refused at the handshake on the digest | one refusal line in the seed's log | +| 6 | Record | the digest, the genesis hash and the three sha256 lines in this file and in `docs/testnet/README.md`; the announcement text carries the genesis hash | | + +Steps 2 to 5 as one staged command (the build-server lane, 15:1x UK; `infra/build-server/wave1-0320.sh` on branch `build-server`, +mode `seeds`, on master at 84155005; dry run by default, nothing touched; `--go` only on the founder's word): + +``` +# from the build-server worktree; the seed-class binary from this lane's fork: cd vendor/igneum-node-testnet-genesis && tools/build-remote.sh --ship seed +infra/build-server/wave1-0320.sh seeds --igneumd --sha256 \ + --miner --digest --wipe-genesis --genesis 01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac +infra/build-server/wave1-0320.sh seeds ... --go # the same line with --go, on the founder's word +``` + +What it does with `--go`, on seed1, seed2 and seed3 in parallel: the binary put as `/opt/igneum/bin/igneumd.new` with the sha asserted on +the box, the unit stopped, `/var/lib/igneum/igneum-testnet-1` moved aside as `igneum-testnet-1.prev-` (kept), the binary swapped +(the old kept as `igneumd.prev`), the unit started, then one RESULT line per seed: unit state and downtime, `genesis MATCH` from the +`[igneum-exec] genesis ... executed` line against `--genesis`, the commit string count in the installed binary, the digest line against +`--digest`, `eth_syncing` and `net_peerCount` over the loopback RPC, the first journal line, and "base unit 10^18 line seen" (the 5 October binary never prints it, the re-cut always does). No `--override`: the testnet takes none. The +dry run of 15:1x UK read all three seeds on 1c19441d at height 0 (`active a9ea25f8ada2`). The digest passed as `--digest` is the one the +final object prints (`63faee44...`), never a value from memory. + +The route the shipper staged (0.3.20 cut, main's ruling (b), 14:4x UK, `docs/plans/release-0.3.20.md` 5e74fa2f): the three seeds stay +on 1c19441d (digest `b7d8c915...`) through the 0.3.20 sweep and the public RPC filter's BLOCKED_UNTIL_FIXED_NODE set stays; at the go the +build-server lane's `wave1-0320.sh` seeds mode puts the re-cut binary on the three seeds in parallel (the sha asserted, the commit string +and the digest read back) and its lift-rpc-filter mode opens the RPC; steps 2 to 4 above are what that mode does, step 2's wipe included. + +The digest lineage, so the move is read right at the go: 1c19441d `b7d8c915...` (5 October); the 0.3.20 pin c4459193 `9537868d...`, the +whole move being five additions (`finality_leave_activation_daa` 0 with `finality.leave_delay` 3,600, `program_class_v3_activation_daa` 0, +`program_class_v4_activation_daa` 0 with the signal window 0 left out, `pow_genesis_dataset_log2` 28, `EmissionSchedule::TESTNET_1`), the +genesis, base params, finality table, fee table and pow schedule unchanged; this re-cut `80af8aa1...` on top of those: `base_unit_decimals` +18 (and the genesis itself, re-laid), `difficulty_v3_activation_daa` 0, `finality_daa_rule_activation_daa` 0, the signing bonus 0 at 1,000 bps, +`latency_ladder_activation_daa` 0 with the window and the six rungs, `proving_consensus_verify_daa` 0 with the two program ids, +`subsidy_per_block_activation_daa` 0; then `4fbb2152...` with the genesis-forward fields (`sig_scheme_activation_daa` 0 with `sig_scheme` 0, `finality_succession_activation_daa` 0, the cache rung in the ladder arm); then `63faee44...` with the cache rung behind its own switch (`latency_ladder_cache_rung_activation_daa` 0, a fourth arm), the final object. No override pins any old value, so every testnet node +swaps together or not at all; the digest is re-read on the re-cut's own binary at the go. + +What the founder's go needs from him, in order: (a) nothing on item 8 any more (it is in); (b) "cut the seeds over" (this runbook, about 20 minutes for the three); (c) the 0.4.0 cut from the merged branches (step 3 of the go table); (d) the first miner. Until (b) the seeds keep the 5 October chain and refuse every re-cut node, which is harmless: nothing mines on either. + ## Cost | Item | USD per month, net (Hetzner API, 5 October 2026) | diff --git a/docs/spec/05-fees-and-economics.md b/docs/spec/05-fees-and-economics.md index eb39181d3..8848d84b2 100644 --- a/docs/spec/05-fees-and-economics.md +++ b/docs/spec/05-fees-and-economics.md @@ -13,7 +13,7 @@ Designed. Every transaction pays a base fee in both gas dimensions: | Execution gas | EVM execution, Ethereum's rule | Ethereum's EIP-1559-style base fee over the ordered sequence | | Proving-cost gas | Proving cycles the transaction will cost the provers | A second base fee `f_p`, adjusted per chain block by the same EIP-1559 step as `f_e`: toward a target of `B_p / 2` of proving gas used, denominator 8, never below the floor of section 5.11 (one definition, 5 October 2026, ledger P14; `next_base_fee` in `igneum/exec/src/executor.rs`, applied per chain block in `service.rs`). The unproven backlog does not move `f_p`; it halves `B_p` (design 4.3, the backlog rule), which raises `f_p` through the step. No smoothing over the difficulty window is implemented or specified: the two-dimension step is per chain block | -The base fee in both dimensions is **burned in full**. A miner cannot stuff blocks with its own transactions for free; wash gas loses its whole base fee (ledger E3). The proving-cost budget per block is a consensus constant set from measured prover throughput (phase 2 gate: one shard on a 12 GB card in about 20 s, Target, unmeasured, ledger P1), so a transaction that is cheap to run and brutal to prove cannot stall the provers for everyone. How the node folds the proving-cost dimension into the quoted gas price so `eth_estimateGas` keeps working is fixed in section 7.1 (ledger P5, closed 3 October 2026). +The execution base fee is **burned in full**; the proving base fee is the provers' payment from 8 October 2026 (90% to the block's proving pool, 10% burned; `docs/design/proving-payment.md`, Igneum 2.0 D4), which keeps the anti-stuffing property below through the burn and the pool's sortition. A miner cannot stuff blocks with its own transactions for free; wash gas loses its whole base fee (ledger E3). The proving-cost budget per block is a consensus constant set from measured prover throughput (phase 2 gate: one shard on a 12 GB card in about 20 s, Target, unmeasured, ledger P1), so a transaction that is cheap to run and brutal to prove cannot stall the provers for everyone. How the node folds the proving-cost dimension into the quoted gas price so `eth_estimateGas` keeps working is fixed in section 7.1 (ledger P5, closed 3 October 2026). ## 5.2 Priority fee split @@ -21,7 +21,7 @@ Designed. The priority fee (tip) of every executed transaction splits: | Share | Recipient | Rule | |---|---|---| -| 80% | Block producer and provers | The producer of the block in which the first copy executed (section 2.6) and the provers of that block, in the proportion the proving protocol defines (forward reference) | +| 80% | Block producer | The producer of the block in which the first copy executed (section 2.6). No part of the tip reaches the provers: O-5.7 is closed at zero (8 October 2026, `docs/design/proving-payment.md`); the provers' user-funded payment is the proving base fee (5.1, 5.3) | | 20% | Developer | Attributed per call frame by gas consumed, to the developer address registered for the called contract at deployment. A frame in an unregistered contract sends its share to the burn | No part of the tip is burned by rule; the burn is the base fee (5.1) and the unregistered developer share. @@ -34,7 +34,7 @@ Self-dealing: a developer who also mines the including block collects 80% plus 2 ## 5.3 Proving pool -Designed. The 20% emission share (section 2.5) and the provers' part of the 80% tip share are paid per block as a fixed amount for that block, divided among the block's shards by consensus proving cost, so a stuffed block earns no more than an honest one. Shards are not claimed first-come and carry no bond: each shard is assigned by sortition to 8 eligible provers for a 10-s exclusive window, then open to anyone, and the first valid proof included in a block is paid (section 7.2, decided 3 October 2026, ledger P8, C9). The parameters 8 and 10 s are set on the phase 4 devnet (O-5.1). A withheld shard costs nothing to bond against because nothing waits on an assigned prover: an unproven block delays only its proof; execution and the 30-s lock do not wait for it (ledger P9). The bond, slashed on a bad or late proof, remains in the external job market (5.4), where a customer does wait; its size and timeout are Open (O-5.6). +Designed. The 20% emission share (section 2.5) and 90% of the block's proving payment (`pgas used x f_p`, the congestion-priced proving base fee of 5.1; 8 October 2026, `docs/design/proving-payment.md`, the code pinned) are paid per block, the emission share as a fixed amount for that block and the proving payment as the block's own, divided among the block's shards by consensus proving cost, so a stuffed block earns no more than an honest one. Shards are not claimed first-come and carry no bond: each shard is assigned by sortition to 8 eligible provers for a 10-s exclusive window, then open to anyone, and the first valid proof included in a block is paid (section 7.2, decided 3 October 2026, ledger P8, C9). The parameters 8 and 10 s are set on the phase 4 devnet (O-5.1). A withheld shard costs nothing to bond against because nothing waits on an assigned prover: an unproven block delays only its proof; execution and the 30-s lock do not wait for it (ledger P9). The bond, slashed on a bad or late proof, remains in the external job market (5.4), where a customer does wait; its size and timeout are Open (O-5.6). Proving v1 (section 7.8, 5 October 2026, Implemented behind `proving_v1_activation_daa`): from the switch, `proving_v1_aggregator_share_bps` of a block's fixed amount (a tenth, the founder's decision at 0.3.11) goes to the aggregator whose segment record attests the block, the rest to the shards as before; a block in a segment that stays unproven past `proving_v1_unproven_daa` pays no aggregator share. diff --git a/docs/spec/06-open-items.md b/docs/spec/06-open-items.md index 1b6c0c127..45662f0ab 100644 --- a/docs/spec/06-open-items.md +++ b/docs/spec/06-open-items.md @@ -93,7 +93,7 @@ An item closes when its measurement is in `docs/bench-log.md` or its decision is | O-5.4 | Every genesis contract's upgrade and key policy (ledger G4); the development fund contract is gone (fund removed 3 October 2026) | Publish before launch | 4 | | O-5.5 | The proving-cost gas dimension: the metering table per opcode and precompile, and the per-block budget from the phase 2 measurement | Phase 2 benchmark; execution-layer specification | phase 2 | | O-5.6 | External job bond size and claim timeout (ledger P9); shards carry no bond since the sortition rule of section 7.2 | Set on the phase 4 devnet | 4 | -| O-5.7 | The provers' proportion of the 80% tip share (section 5.2) | Defined by the chunked proving protocol | phase 2 | +| O-5.7 | The provers' proportion of the 80% tip share (section 5.2) | Closed 8 October 2026: zero; the provers are paid by the proving base fee, 90% to the block's pool and 10% burned (`docs/design/proving-payment.md`, Igneum 2.0 D4) | decided | | O-5.8 | Developer registration format at deployment and the re-registration transaction (section 5.2) | Execution-layer specification | decision, execution engineer | | O-5.9 | Mining against proving under shocks: external proving pays 10x, the IGN price falls, a large operator leaves, assignments go unfulfilled, clients maximise profit (ledger E12); design R8 covers the fee switch only and has not run | R8 simulation extended with the five shocks, then the phase 4 devnet with profit-only prover clients: backlog depth, time to clear, `f_p` and `B_p` paths, income per card. Sweep 5 October 2026: the simulation half ran in `sim/economy` (scenarios b, d, e: external 10x with a 70% price fall, the 20% operator leaving, a 30% operator never fulfilling; no backlog, every block proven within 60 s, hash trough 82% and 75%); the devnet half with profit-only clients is fud-fixes row 126 | 4 | | O-5.10 | No single figure shows every payment route (emission, base fee, priority fee, external jobs at launch and after the bridge, the client dev fee) with currency, recipient, fee and burn (ledger E13) | Draw it, one route per row, in the litepaper Economics section and the customer brief; operator revenue never summed with protocol revenue | decision, execution engineer; before public repo | diff --git a/docs/spec/proving-enforcement.md b/docs/spec/proving-enforcement.md new file mode 100644 index 000000000..bd0382681 --- /dev/null +++ b/docs/spec/proving-enforcement.md @@ -0,0 +1,101 @@ +# Enforced proving: a valid proof as a condition of payment in consensus + +8 October 2026, the enforced-proving lane, branch `enforced-proving` (main repository) and `enforced-proving-node` (the fork, on the 0.3.25 node line at acaf08b0, which carries the hotfix pair f8da7515). Ordered after an external review the founder accepted (16:1x UK): ledger P21 says consensus validates a proof record's statement against native execution but does not require the SP1 proof itself to verify, so a modified producer can include an unverified record and cause a proving payout without the proof work. This document is the rule, the switch, the tests, the cost, the activation plan and the P22 staging statement. Every figure carries its label: measured (a box run with its RESULT line), stated (code read), or owed (with the clock time it is due). + +## 1. The rule + +A carried proof record pays only when the paying node has verified the record's SP1 proof itself. Two places hold it, the same floor for both: + +1. **The body rule** (`consensus/src/pipeline/body_processor/body_validation_in_context.rs`, `check_carried_proofs`, the 0.3.16 rule): from the floor, every shard record (`IGNP`) and segment record (`IGNS`) a block's coinbase carries must come with proof bytes the node holds that verify for the record's statement under the pinned program id. A proof that does not verify, or that names another guest, makes the block invalid (`IgneumInvalidProofRecord`); proof bytes not held are `IgneumProofMissing`, retried once after a 20-second fetch from the sending peer and then dropped unmarked (`protocol/flows/src/v10/blockrelay/flow.rs`), so the block never enters the DAG. +2. **The payment rule** (`igneum/exec/src/proving.rs`, `carried_payouts` and `carried_segment_payouts`): from the floor, a record passes every check of spec 07 7.7 item 3 as before (chain block, window, plan, signature under the network name, assignee, the native-execution veto, first per shard) and then one more: this node's verifier holds a VERIFIED verdict for its proof (`ProofPool::verified_for_payment`: the cached verdict of the body rule or of the relay-time verifier, else a verify now when the bytes are held and the keys exist). Without it the record is carried with `rejected = "proof not verified by this node (enforced proving): no payment"` and pays nothing, and nothing is marked paid, so the honest proof of the same shard can still pay. + +Why both: the body rule stops a block carrying a bad proof from entering any honest node's DAG; the payment rule makes the money condition explicit on the node that computes the state, so a node whose body rule is off (the harness attacker, `IGNEUM_TEST_SKIP_PROOF_RULE=1`) still never pays an unverified record. The native-execution veto stays underneath: no record moves state or pays for a wrong claim whatever its proof. + +Stated, not new: the verifier (`igneum/exec/src/nativeverify.rs`) is SP1's light verifier in-process on Unix (the shard and aggregator verifying keys embedded from `proving/igneum-prove/elf`), through the installed `igneum-prove-host` on Windows. Its verdicts are cached by proof hash, so a proof verified at relay time costs the body rule nothing, and the payment rule nothing again. + +## 2. The switch + +`Params::verifier_in_consensus: bool` (`consensus/core/src/config/params.rs`), with `OverrideParams::verifier_in_consensus: Option` for the override file (`infra/fast-time/override-60x.json` lists it, `false`). The one accessor every reader uses is `Params::proof_rule_active_from()`: + +| Object | `verifier_in_consensus` | `proving_consensus_verify_daa` | `proof_rule_active_from()` | Meaning | +|---|---|---|---|---| +| Devnet 3 (the live object, compiled, no file) | false | never | never | the finding's shape: v0, every producer verifies off the consensus path; unchanged by this rollout | +| igneum-testnet-1 (the 0.3.25 object) | false | 0 | 0 | the rule has held from the testnet's block zero under the two pinned program ids (stated, `TESTNET_PARAMS`); the switch adds nothing there | +| mainnet, simnet, devnet defaults | false | never | never | off | +| the class v6 object (section 5) | true | never | 0 | on from block zero under the ids the object pins, or the binary's embedded ids when it pins none | +| the tests | true (or a floor) | as the test says | 0 or the floor | on | + +What the switch changes, exactly: the body processor reads `proof_rule_active_from()` instead of the DAA field; the daemon installs the proof oracle with that floor and refuses to start with the rule set when the binary's embedded keys are not the object's pinned ids (an object that sets the switch and pins no ids pins the ids its release embeds, and the start line says so); the executor's `ProvingConfig::verified_payout_from` takes the same floor for the payment rule. In the digest once set (one field, the 0.3.15 rule for new fields), so no live digest moves on the rollout and a node with the switch on never peers with one that lets an unverified record pay. Unit test: `kaspa_consensus_core::config::params::tests::the_verifier_switch_is_off_on_every_compiled_object_and_on_from_genesis_when_set`. + +## 3. The tests, known-failed first + +The harness producer is a modified producer: it signs the CORRECT native statement for the shard and payout every time (the shape the veto cannot catch) and tries the seven refusals. The validator is an ordinary unmodified node. Each refusal is a named test with its assertion. + +Consensus side (`consensus/src/pipeline/body_processor/proving_enforcement_tests.rs`, a `TestConsensus` on the devnet object with the switch on, a test oracle standing in for the executor's verifier, one verdict per proof hash): + +| Refusal | Test | Assertion | +|---|---|---| +| (a) no proof | `enforced_a_record_with_no_proof_held_is_missing_and_the_block_is_not_inserted` | `Err(IgneumProofMissing)`: the block is never inserted; the relay drops it after the 20-s fetch | +| (b) a wrong proof | `enforced_a_record_whose_proof_fails_to_verify_invalidates_the_block` | `Err(IgneumInvalidProofRecord)` carrying "does not verify" | +| (c) a proof for another program id | `enforced_a_proof_for_another_program_id_invalidates_the_block` | `Err(IgneumInvalidProofRecord)` carrying "pinned id" | +| honest | `enforced_a_verified_record_is_accepted_by_the_body_rule` | `Ok`; the payment (once) is the executor's test below | +| the finding | `enforced_without_the_switch_and_with_the_floor_at_never_the_fake_record_is_accepted_the_p21_finding` | the live object's shape: the wrong proof passes the body rule. Kept as the named known-failed shape | +| the boundary | `enforced_the_floor_is_a_boundary_below_it_the_fake_record_passes_at_it_the_block_is_invalid` | a floor of 1,000 lets the genesis child (DAA 1) pass with a wrong proof; a floor of 0 refuses it | + +Execution side (`igneum/exec/src/proving.rs`, `tests::enforced_*`, the 30-block chain of the existing proving tests, block 21 one shard, the carrier at DAA 105 past the activation at 100, `verified_payout_from` 0): + +| Refusal | Test | Assertion | +|---|---|---| +| (a) no proof, (b) a wrong proof, at payment | `enforced_an_unverified_proof_pays_nothing_and_the_verified_honest_record_pays_once` | with the verifier answering false: no payout, `rejected` says "proof not verified", nothing marked paid; with the verifier answering true for the honest proof hash and statement: the shard's 1,000,000 wei paid once, the same record carried again is "shard already paid" | +| (d) a replayed record | `enforced_a_replayed_record_pays_nothing_the_second_time` | paid once at carrier 25; carried again at carrier 26: no payout, "shard already paid", one entry in the paid map | +| (e) a wrong network id | `enforced_a_record_signed_for_another_network_pays_nothing` | signed under `igneum-devnet-951`: "bad signature", no payout | +| (f) an altered payout address | `enforced_an_altered_payout_address_pays_nothing` | the address changed after signing: "bad signature"; re-signed for another address: the native-execution veto (the statement binds the payout); no payout either way | +| (g) a duplicate of a paid record | `enforced_a_duplicate_of_a_paid_record_by_another_key_pays_nothing` | prover-b's own valid record for the shard prover-a was paid for: "shard already paid", one payout | +| the finding, the floor | `enforced_below_the_floor_an_unverified_record_still_pays_the_v0_shape` | floor never: paid without a verified proof (the finding); one below the floor: paid; at the floor: no payment | +| the verdict source | `enforced_the_pool_answers_verified_only_for_a_cached_ok_verdict` | no verdict: false; a refused verdict: false; a VERIFIED verdict: true | + +Known-failed first: the two tests that encode the new condition (the "pays nothing without a verified proof" test and the floor test) fail on the tree before the `verified_payout_from` condition, and the consensus tests under `verifier_in_consensus = true` do not compile before the switch exists. The refusals (d), (e), (f) and (g) were already held by the signature (domain-separated with the network name and binding the payout address), the native veto and the paid map; their tests pass on the old tree too, which is stated here so nobody reads them as new protection. What is new is (a), (b) and (c) at payment on every object, and the named switch. + +Results: section 6. + +## 4. The cost + +The verifier's time per record on the node, measured on build-2 under the lease tool (section 6 carries the RESULT lines). The budget per block: at most 8 shard records and 2 segment records per block (`MAX_RECORDS_PER_BLOCK`, `MAX_SEGMENT_RECORDS_PER_BLOCK`), verified in parallel on the body processor's thread pool, each verdict cached by proof hash, so a proof verified at relay time costs the block nothing. Measured (section 6, build-2, one EPYC 9454P core at nice 19 under the lease tool, the box loaded): 0.668 to 0.710 s per record and about 30 MB per concurrent verify. What the switch costs a block, from those figures: nothing for a block that carries no records; nothing for a proof the relay verified before its block (the cached verdict); the worst case is a block whose ten proofs all arrive cold with it, about 0.7 s wall on ten cores of the body processor's pool (7 s of CPU) and about 300 MB peak. At the hold's rate of one block a second, a producer that fills every block with cold proofs costs a validator 0.7 s of wall per block on ten cores, which the pool absorbs; a validator with fewer cores serialises the ten verifies (7 s a block) and falls behind, which is why the relay-time verify is the design's budget and the block-time verify its backstop. Per tier: every node class holds the 300 MB (8 GB rig, 12 and 16 GB card nodes, pool nodes); a Windows node verifies through `igneum-prove-host` and the daemon refuses to start with the rule set and no host. The 10 ms gate of the overview is the hash's per-warp CPU-verify gate, not this check's: an SP1 compressed proof verify is 70x it, a different class of check, and the cache above is what keeps it off the block's critical path. + +## 5. Activation + +1. The live Devnet 3 object does not move: the switch is false, the floor never, the digest unchanged, and the tests say so. +2. igneum-testnet-1 already runs the body rule from block zero under its two pinned ids; this rollout adds the payment rule on the same floor (0), which changes nothing a testnet node pays (every carried record on the testnet has passed the body rule), and is the first live network under the full condition. +3. The class v6 object (`docs/design/class-v6-rotating-family.md`, no consensus code yet) carries `verifier_in_consensus: true`: on from its block zero. Until that object exists, a network that wants the rule before class v6 sets its own floor through `proving_consensus_verify_daa` in the override file, the way the 0.3.16 rule was designed to land, one weight window above the rollout so every node runs the binary first. +4. Every node must run a binary whose embedded keys are the object's pinned ids before the floor; the daemon refuses to start otherwise. +5. Shipping: consensus code on the release line the shipper names (release-0.3.26 is the hotfix pair; the next node line opens as release-0.3.27); the main-repository branch lands on the box mirror master through the gate on the coordinator's word. + +## 6. Results and measurements + +Filled from the box runs as they land; each line names the box, the command class and the time. + +| Time (UK) | Box | What | Result | +|---|---|---|---| +| 16:08 | build-2, suite class, 12 threads, nice 10 (the bounded pool held 13 free cores; the 24-thread ask waited) | `cargo test --release -p igneum-exec --lib enforced_` | 7 passed, 0 failed (the seven executor tests of section 3), 229 s wall with the compile | +| 16:11 | build-2, same class | `cargo test --release -p kaspa-consensus-core --lib the_verifier_switch` | 1 passed (the switch is off on every compiled object; Devnet 3 at never; the testnet floor 0; the digest moves once set; a file that omits it changes nothing) | +| 16:15 | build-2, suite class, 12 threads | `cargo test --release -p kaspa-consensus-core -p igneum-exec -p kaspa-consensus --lib` (the full lib suites on the branch; the first consensus build stopped on a missing `ConsensusApi` import at 16:11, fixed at 16:12) | igneum-exec 64 passed 0 failed; kaspa-consensus 138 passed 0 failed, 3 ignored (the six `proving_enforcement_tests::enforced_*` among them); kaspa-consensus-core 171 passed 0 failed, 4 ignored; 172 s wall with the compile | +| 16:34 | build-2 (AMD EPYC 9454P, 96 threads, 125 GB), `lease pool 1 --nice 19`, one core, the box at load 85 to 95 | the verify cost per record: `nativeverify::tests::a_real_proof_verifies_and_a_wrong_statement_is_refused` on a real compressed shard proof of the testnet join pass (build-1 `/srv/builds/tn-join-pass/prover/block-763-shard-0-compressed.bin`, 1,272,897 bytes), seven runs; `/usr/bin/time -v` for the memory | measured: 0.710, 0.683, 0.701, 0.671, 0.700, 0.687, 0.668 s one core (0.668 to 0.710 s, a loaded-box figure); peak resident 34.6 MB with the verify against 4.6 MB for the same binary without it, so about 30 MB per concurrent verify | + +## 7. The staging statement for P22 + +P22: the rewards and the prover payouts are inputs to the shard proof, not outputs. The shard guest takes the segment's rewards and payouts as data and commits the post-root after them; a host can feed any list and the proof still verifies. Today the node's own derivation is the check: the statement must equal the node's native statement for that shard and payout, which used the rewards and payouts consensus derived, so a proof over another list matches no node's statement and pays nothing. + +The closure is staged. Each stage is a claim about one input and the check that holds it; no stage claims a self-contained proof of the whole state. + +| Stage | What becomes an output of a proof | What checks it until then | Status | +|---|---|---|---| +| 0 (today) | nothing: rewards and payouts are data in the shard statement (`BlockFixture.rewards`, `payouts`) | every node's native execution derives both and vetoes a statement that differs; enforced proving (this document) adds that the record's proof must verify for that statement | implemented | +| 1 | the shard proof's rewards list is checked against a commitment the aggregator carries in its public values (the mergeset's blue blocks and their subsidies, hashed) | the aggregator's commitment is itself data; every node recomputes it from the mergeset it holds and vetoes a segment statement whose commitment differs (spec 7.8 item 5, the native block statement) | next: the consensus-proof work of design 7, phase 2 | +| 2 | the payouts list is derived inside the aggregator guest from the carried records it verifies (the first valid record per shard, the pool credit split) | the node's `carried_payouts` is the native check of the same derivation; a segment statement whose payouts differ is vetoed | phase 2, after stage 1 | +| 3 | the rewards are derived inside the aggregator guest from consensus data it verifies (headers, blue sets) | the node's own derivation vetoes; this is the consensus proof proper, and only here do rewards stop being an input anywhere | phase 2, the last step | + +Until stage 3 lands, every stage's output is checked natively by every node, and the statement "the rewards and payouts are proven" is not made in any served text. The ledger entry P22 carries this table. + +## 8. The fast-time harness case + +`infra/fast-time/proving-enforcement.mjs` (section 6 says whether it ran): three nodes on one fast-time network, two honest under the floor set a few epochs ahead (`proving_consensus_verify_daa` in the override, the boundary), one attacker with the body rule off and the verifier in trust mode. The attacker reads each shard's native statement for its own payout address from its node (`igneum_getShardPlan(block, payout)`), signs it (`igneum-miner sign-record`) and submits it with proof bytes of the seven shapes through `igneum_submitProofRecord`; its templates carry the records. Below the boundary the honest nodes accept the attacker's blocks and the v0 rule pays (the finding, observed); from the boundary every honest node refuses the carrying block (`IgneumInvalidProofRecord` or the 20-s drop) and `igneum_getProofRecords` shows no paid entry for any of the seven. The honest-pays-once case needs a real shard proof of the harness's own chain, which a CPU prover makes in minutes; the unit tests hold it meanwhile and the testnet holds it live. diff --git a/docs/testnet/README.md b/docs/testnet/README.md index ff1651daf..ecefbf1a7 100644 --- a/docs/testnet/README.md +++ b/docs/testnet/README.md @@ -1,4 +1,4 @@ -# Igneum public testnet: identity, parameters and reset policy (ADOPTED 5 October 2026) +# Igneum public testnet: identity, parameters and reset policy (ADOPTED 5 October 2026; genesis RE-CUT 7 October 2026; the GO object re-cut on the 0.3.23 line at 18 decimals by the founder's word of 21:35 BST) Every value in this file was proposed on the night of 4 October 2026 and ADOPTED by the owner on 5 October 2026, as proposed (sign-off recorded in `docs/plans/release-0.3.6.md`). The genesis below is the one the proposal @@ -8,7 +8,15 @@ merged on 5 October 2026 into the fork's `release-0.3.6` (worktree `vendor/igneu sign-off added: the devnet and the simnet keep the prototype fee set until a height switch (`fees_v1_activation_daa`) or a `fees` object in the override file moves them; the testnet and the mainnet carry calibrated v1 from genesis (section 3). The devnet's switch is DAA score 210,000 (5 October 2026, -`docs/plans/fee-switch-devnet.md`). The three seed nodes went up on 5 October 2026 from the final genesis below (`docs/plans/testnet-go.md`); nothing mines until the owner's go. +`docs/plans/fee-switch-devnet.md`). The three seed nodes went up on 5 October 2026 from the 5 October genesis (`docs/plans/testnet-go.md`); nothing mines until the owner's go. + +RE-CUT 7 October 2026 (the founder's approvals of 09:3x UK, `docs/plans/ledger-decisions.md` "Decisions (7 October 2026, 09:3x UK)"): +one cut with 18 decimals (O-2.6, the 16-byte coinbase subsidy), `EmissionSchedule::TESTNET_1`, and every switch on from +genesis. The genesis hash and the consensus digest below are the re-cut's; the seeds still hold the 5 October chain at +height 0 and move to the re-cut binary only on the founder's go (`docs/plans/testnet-go.md`, the cut-over runbook). Fork branch +`testnet-genesis-2-node` (release-0.3.18-node e69e8a39, the decimals branch df2fbd03, the vote-or-burn removal 420f9305), carried onto +the 0.3.24 line as `testnet-genesis-3-node` and landed in `release-0.3.24-node`; the go object is 0d05e795 (8 October 2026: class v5 from +genesis after Devnet 3's clean crossing, digest `1da30c10...`, the genesis hash unchanged). ## 1. Identity @@ -40,22 +48,33 @@ read methods plus `eth_sendRawTransaction`; `infra/seed-nodes/rpc/`). | Nonce, DAA score | 0, 0 | | | UTXO commitment | empty | | | Coinbase payload message | `igneum-testnet-1 \| 2026-10-05 \| coins here have no value \| resets are announced` | after the OP-FALSE script, as the devnet's `igneum-devnet`. FINAL 5 October 2026 (fork branch `testnet-infra`, 1c19441d): the proposal's "proposed, not final" was dropped before the first public node started, as `docs/plans/release-0.3.6.md` section 6 required. The message never changes again on `igneum-testnet-1` | -| Hash | `87617621714af1bf33bd17f291f90a7e0bff760a669bba53083ea8c0f7cbd840` | computed 5 October 2026 by `print_genesis_hashes` (two runs: the merkle root first, then the header hash over it), pinned by `test_genesis_hashes` and `igneum_testnet_identity`; the three seeds started from it at height 0 the same day. The proposal's hash `52a3e6a9...` is void | -| Merkle root | `44acfc40b1c6647011510f3c39ddb7606f979df92ad26a2914de56e44610efad` | same | +| Coinbase payload subsidy field | 16 little-endian bytes, one IGN = 10^18 base units | the 18-decimal layout (O-2.6, `docs/design/base-unit.md` section 3); block 1 merges the genesis and reads this field at the network's unit | +| Hash | `01294fd322704dc28fbef0e7a5ef86d6ee260ac5efaf88891cdba661b5fd58ac` | RE-CUT 7 October 2026, computed on igneum-build-1 by `print_genesis_hashes` (two runs: the merkle root first, then the header hash over it), pinned by `test_genesis_hashes` and `igneum_testnet_identity`. The 5 October hash `87617621...` (8-byte subsidy layout, the chain the seeds hold at height 0 until the cut-over) and the proposals `52a3e6a9...` and `494fc9a3...` are void | +| Merkle root | `bcd0e8fb1099aeb3cc1370b50e6dec9f615e204374b2097f25b2438e7d22f49f` | same (5 October: `44acfc40...`) | +| Consensus digest | `1da30c10e164784ffbf5bf216ef3bf84a2d5da212317b1e535c9850fe14aba2f` (the post-crossing re-cut 0d05e795 on `release-0.3.24-node`, 8 October 2026: class v5 from genesis at byte 6; the 0.3.18-line re-cut's `63faee44...` and the 0.3.24 pin's `b2e856ed...` are void) | exchanged in the p2p handshake; a peer with another digest is refused. Pinned by `igneum_testnet_identity`; the whole object as override-file JSON is `infra/seed-nodes/testnet-object.json` (`print_testnet_object`). The 5 October digest `b7d8c915...` and the re-cut's interim digests `9390d235...`, `80af8aa1...` and `4fbb2152...` are void. The devnet's `c562d70e...` is unchanged | ## 3. Consensus parameters | Parameter | Testnet (adopted) | Devnet today | Why | |---|---|---|---| | Block rate | 1 per second | 1 per second | spec 02 | -| Difficulty rule | Igneum dual-lane, v2 from genesis | dual-lane, v2 from DAA 33,000 | a fresh chain has no pre-switch history | -| Finality parameters | `FinalityParams::MAINNET`: 30-day weight window (2,592,000 DAA), dust 100, presence 240, 8 aggregators, 30-day equivocation ban, min DAA 2,592,000, certificate fold 6 | `DEVNET`: 2-hour window, dust 5, presence 20, fold 3 | the testnet runs the rule the mainnet will run; the first lock needs 30 days of weight, which is the point of a testnet | +| Difficulty rule | Igneum dual-lane, v2 and v3 from genesis (`difficulty_v3_activation_daa` 0) | dual-lane, v2 from DAA 33,000, v3 by the override file | a fresh chain has no pre-switch history | +| Finality parameters | `FinalityParams::MAINNET`: 30-day weight window (2,592,000 DAA), dust 100, presence 240, 8 aggregators, 30-day equivocation ban, min DAA 2,592,000, certificate fold 6, leave delay 3,600 | `DEVNET`: 2-hour window, dust 5, presence 20, fold 3 | the testnet runs the rule the mainnet will run; the first lock needs 30 days of weight, which is the point of a testnet | | Finality rule v3 | from genesis | from the override file | fresh chain | +| The DAA-second finality rule (C1) | from genesis (`finality_daa_rule_activation_daa` 0): a checkpoint every 30 s of chain time at any block rate | by the override file | re-cut 7 October 2026 | +| The signed leave item (W7) | from genesis (`finality_leave_activation_daa` 0, delay 3,600 DAA s): a key that announces its departure is in no denominator an hour later | never until the 95 percent signal | the founder, 6 October 2026, question 4 | +| The signing bonus, no burn | from genesis (`signing_bonus_activation_daa` 0, `signing_bonus_bps` 1,000): a tenth of a silent producer's subsidy share moves to the proving pool; nothing is ever destroyed; vote-or-burn is out of the tree (420f9305) | never | the founder, 7 October 2026, row 2 | +| Consensus proof verification | from genesis (`proving_consensus_verify_daa` 0) under the shard program id `0x2b1a81cb...ef7a` and the aggregator id `0x474678f3...3896` of `proving/igneum-prove/elf/manifest.json` (pinned 2026-10-05T16:20:38Z); a node whose embedded keys differ refuses to start; a Windows node verifies through the installed `igneum-prove-host` and refuses to start without it | off | the founder, 6 October 2026, question 3 | +| Program class | v4 from genesis, unconditional (`program_class_v4_activation_daa` 0, signal window 0) | v4 by miner signal | fresh chain | +| The latency ladder | active from genesis at rung 0 (`latency_ladder_activation_daa` 0, window 86,400 DAA, seven windows at 90 percent to step): rungs 27, 35, 53 passes admissible; 88 inadmissible (quiet-core re-measure 7 October 2026, 08:46 UK: 10.85 ms cold with the SMT sibling loaded, over the 10 ms gate); 173 and 267 inadmissible | never | the founder, 7 October 2026, row 3 | +| Base unit | 18 decimals (`base_unit_decimals` 18): one IGN is 10^18 base units, the EVM's wei, the bridge is the identity | 8 (sompi) | the founder, 6 October 2026, question 5, CONFIRMED 7 October 2026, 21:35 BST for the go object on the 0.3.23 line; `docs/design/base-unit.md` | +| Per-block subsidy on the EVM side | from genesis (`subsidy_per_block_activation_daa` 0): each merged block credited the subsidy of its own DAA, as the UTXO coinbase pays it | at an upgrade height with 0.3.19 | the founder, 7 October 2026, 09:5x UK | +| Genesis forward-compatibility (mission item 8) | from genesis: `sig_scheme` 0 (BLS12-381) with `sig_scheme_activation_daa` 0 (every vote item and key reveal carries the scheme byte; any other scheme refused until a program class the 95 percent signal moves to names it), `finality_succession_activation_daa` 0 (W5: a vote key hands its window weight and forfeit term to a successor once), the ladder's cache rung 512 MiB inadmissible until measured, behind its own switch (`latency_ladder_cache_rung_activation_daa` 0) | never | the founder, 7 October 2026, 10:1x UK; `docs/design/genesis-forward.md` | | Proving v0 payouts | from genesis | from the override file | fresh chain | | PoW schedule | epoch 3,600 DAA, lead 600, day 86,400,000 ms (the defaults) | same | | | Coinbase payload limit | 16,384 (the finality section) | same | | | Fees | `FeeParams::CALIBRATED_V1` from genesis (`fees_v1_activation_daa` 0; `docs/analysis/base-fee-floor.md`): `B_p` 120,000 pgas, `S_p` 30,000, intrinsic 300, modexp 10 + 1 per 10 bytes, floors 100 gwei per gas and 10,000 gwei per pgas | `FeeParams::PROTOTYPE` (`B_p` 30 M, 1 gwei), kept on the 0.3.6 node so the live chain does not change rules between builds; moves to v1 by the `fees_v1_activation_daa` height switch in the override file (`docs/plans/release-0.3.6.md`, section 5) | spec 05 section 5.10 | -| Emission | the mainnet schedule: 31.69 IGN per block in year one, halving every two years, cap 4 billion | same | the testnet coins have no value whatever the schedule says | +| Emission | `EmissionSchedule::TESTNET_1` at 18 decimals: 100 IGN a block at 1 bps, a monthly glide with a two-year half-life, a 90-day ramp from 10 percent, a tail of 1 percent of supply a year from the month the glide first pays under it (about year 11.4), no hard cap (`docs/analysis/tail-emission.md`) | `CURRENT`: 31.69 IGN per block in year one, halving every two years, cap 4 billion | the founder, 7 October 2026, row 1; the testnet coins have no value whatever the schedule says | Everything else (mass limits, GHOSTDAG k, merge depth, pruning) is the devnet's set, unchanged. @@ -81,5 +100,6 @@ Everything else (mass limits, GHOSTDAG k, merge depth, pruning) is the devnet's | The public RPC and explorer | the RPC is `https://rpc.testnet.igneum.network` (5 October 2026); the explorer is not built | | The prover's table mirror and fixtures | `docs/analysis/base-fee-floor.md` section 4 | | The app's testnet build | branch `testnet-app` (5 October 2026): the packaged file's `network`, `peers`, `public_rpc`; the testnet's ports, seeds and node directory in `app/igneum-app/src/config.rs`; the release engineer cuts 0.4.0 from it at go | -| The params digest in the handshake (X18) | separate work, before the testnet | +| The params digest in the handshake (X18) | done: `1da30c10...` for the go object (0d05e795) | +| The seeds on the re-cut genesis | NOT DONE: the three seeds hold the 5 October chain at height 0; the cut-over (new binary, wiped data directory, the digest line read back on each) runs on the founder's go, `docs/plans/testnet-go.md` | | Terms on the download page | `site/index.html#testnet-terms`, on branch `testnet-prep` with this file | diff --git a/igneum-pow/src/blake2b.rs b/igneum-pow/src/blake2b.rs new file mode 100644 index 000000000..4b04cc622 --- /dev/null +++ b/igneum-pow/src/blake2b.rs @@ -0,0 +1,152 @@ +//! BLAKE2b (RFC 7693), the chain's own hash family (spec 01 section 0.6), written out here so the crate keeps its +//! rule of no dependency outside the standard library. Used by class v5's state leaves (`crate::state`): +//! `blake2b_512` for a leaf digest, `blake2b_256` for the sample order. Unkeyed, no salt, no personalisation. +//! Checked against the RFC's "abc" vector and the empty-input vector in the tests. + +const IV: [u64; 8] = [ + 0x6a09e667f3bcc908, + 0xbb67ae8584caa73b, + 0x3c6ef372fe94f82b, + 0xa54ff53a5f1d36f1, + 0x510e527fade682d1, + 0x9b05688c2b3e6c1f, + 0x1f83d9abfb41bd6b, + 0x5be0cd19137e2179, +]; + +const SIGMA: [[usize; 16]; 12] = [ + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], + [11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4], + [7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8], + [9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13], + [2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9], + [12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11], + [13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10], + [6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5], + [10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0], + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + [14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3], +]; + +#[inline(always)] +fn g(v: &mut [u64; 16], a: usize, b: usize, c: usize, d: usize, x: u64, y: u64) { + v[a] = v[a].wrapping_add(v[b]).wrapping_add(x); + v[d] = (v[d] ^ v[a]).rotate_right(32); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(24); + v[a] = v[a].wrapping_add(v[b]).wrapping_add(y); + v[d] = (v[d] ^ v[a]).rotate_right(16); + v[c] = v[c].wrapping_add(v[d]); + v[b] = (v[b] ^ v[c]).rotate_right(63); +} + +fn compress(h: &mut [u64; 8], block: &[u8; 128], t: u128, last: bool) { + let mut m = [0u64; 16]; + for (i, w) in m.iter_mut().enumerate() { + *w = u64::from_le_bytes(block[i * 8..i * 8 + 8].try_into().unwrap()); + } + let mut v = [0u64; 16]; + v[..8].copy_from_slice(h); + v[8..].copy_from_slice(&IV); + v[12] ^= t as u64; + v[13] ^= (t >> 64) as u64; + if last { + v[14] = !v[14]; + } + for s in SIGMA.iter() { + g(&mut v, 0, 4, 8, 12, m[s[0]], m[s[1]]); + g(&mut v, 1, 5, 9, 13, m[s[2]], m[s[3]]); + g(&mut v, 2, 6, 10, 14, m[s[4]], m[s[5]]); + g(&mut v, 3, 7, 11, 15, m[s[6]], m[s[7]]); + g(&mut v, 0, 5, 10, 15, m[s[8]], m[s[9]]); + g(&mut v, 1, 6, 11, 12, m[s[10]], m[s[11]]); + g(&mut v, 2, 7, 8, 13, m[s[12]], m[s[13]]); + g(&mut v, 3, 4, 9, 14, m[s[14]], m[s[15]]); + } + for i in 0..8 { + h[i] ^= v[i] ^ v[i + 8]; + } +} + +/// Unkeyed BLAKE2b of `data` with an output of `out_len` bytes (1..=64), written into `out[..out_len]`. +pub fn blake2b(out: &mut [u8], out_len: usize, data: &[u8]) { + assert!((1..=64).contains(&out_len) && out.len() >= out_len); + let mut h = IV; + h[0] ^= 0x0101_0000 ^ out_len as u64; + let mut t: u128 = 0; + let n = data.len(); + // every full block but the last; the last block (possibly empty) is compressed with the final flag + let full = if n == 0 { 0 } else { (n - 1) / 128 }; + for i in 0..full { + let block: &[u8; 128] = data[i * 128..i * 128 + 128].try_into().unwrap(); + t += 128; + compress(&mut h, block, t, false); + } + let mut last = [0u8; 128]; + let rest = &data[full * 128..]; + last[..rest.len()].copy_from_slice(rest); + t += rest.len() as u128; + compress(&mut h, &last, t, true); + let mut bytes = [0u8; 64]; + for (i, w) in h.iter().enumerate() { + bytes[i * 8..i * 8 + 8].copy_from_slice(&w.to_le_bytes()); + } + out[..out_len].copy_from_slice(&bytes[..out_len]); +} + +/// BLAKE2b-512 of the concatenation of `parts`. +pub fn blake2b_512(parts: &[&[u8]]) -> [u8; 64] { + let mut data = Vec::with_capacity(parts.iter().map(|p| p.len()).sum()); + for p in parts { + data.extend_from_slice(p); + } + let mut out = [0u8; 64]; + blake2b(&mut out, 64, &data); + out +} + +/// BLAKE2b-256 of the concatenation of `parts`. +pub fn blake2b_256(parts: &[&[u8]]) -> [u8; 32] { + let mut data = Vec::with_capacity(parts.iter().map(|p| p.len()).sum()); + for p in parts { + data.extend_from_slice(p); + } + let mut out = [0u8; 32]; + blake2b(&mut out, 32, &data); + out +} + +#[cfg(test)] +mod tests { + use super::*; + + fn hex(b: &[u8]) -> String { + b.iter().map(|x| format!("{x:02x}")).collect() + } + + /// RFC 7693 appendix A ("abc"), the empty input, and a two-block input against the reference implementation's + /// known values (the three-block "The quick brown fox" vector of the BLAKE2 test suite). + #[test] + fn rfc_7693_vectors() { + assert_eq!( + hex(&blake2b_512(&[b"abc"])), + "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923" + ); + assert_eq!( + hex(&blake2b_512(&[b""])), + "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce" + ); + assert_eq!(hex(&blake2b_256(&[b"abc"])), "bddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319"); + assert_eq!(hex(&blake2b_256(&[b""])), "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"); + // a 128-byte input is exactly one full block compressed as the last; 129 bytes takes two + let one = [0x61u8; 128]; + let two = [0x61u8; 129]; + assert_ne!(blake2b_512(&[&one]), blake2b_512(&[&two])); + assert_eq!(blake2b_512(&[&one[..64], &one[64..]]), blake2b_512(&[&one]), "parts concatenate"); + assert_eq!( + hex(&blake2b_512(&[b"The quick brown fox jumps over the lazy dog"])), + "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918" + ); + } +} diff --git a/igneum-pow/src/emit.rs b/igneum-pow/src/emit.rs index 376fd4bb0..50d870216 100644 --- a/igneum-pow/src/emit.rs +++ b/igneum-pow/src/emit.rs @@ -164,7 +164,11 @@ fn program_class_header_lines(p: &Program) -> String { return String::new(); } let mut s = String::new(); - if p.program_class() == ProgramClass::V4 { + if p.program_class() == ProgramClass::V5 { + s.push_str("// Program class v5 (proof of stored state and of following, docs/design/class-v5-stored-state.md): generator version 5,\n"); + s.push_str("// class v4 over a dataset whose every item is keyed by the window's execution state (IGNEUM_STATE_* below, leaves.bin);\n"); + s.push_str("// a worker that runs another class refuses this pack, and a job line names the class it wants (class=v5 era=).\n"); + } else if p.program_class() == ProgramClass::V4 { s.push_str("// Program class v4 (Counter ASIC 3.0, docs/plans/counter-asic-3-node.md): generator version 4, class v3 plus the\n"); s.push_str("// latency-shadow block (IGNEUM_SHADOW_INSTRS x IGNEUM_SHADOW_REPS per iteration); a worker that runs another class\n"); s.push_str("// refuses this pack, and a job line names the class it wants (class=v4 era=).\n"); @@ -183,6 +187,24 @@ fn program_class_header_lines(p: &Program) -> String { s } +/// The state lines of program.h (class v5): the window's reference block and state root, the leaf count, the FNV of +/// `leaves.bin` and the file's name. Empty for every dataset without leaves, so no pinned pack changes. +fn state_header_lines(ds: &DatasetSource) -> String { + let Some(l) = ds.leaves() else { return String::new() }; + let mut s = String::new(); + s.push_str("// Class v5 state (docs/design/class-v5-stored-state.md): the window's reference chain block and the state root after it;\n"); + s.push_str("// leaves.bin holds IGNEUM_STATE_LEAVES leaves of 16 little-endian words, leaf(t) = leaves[t mod IGNEUM_STATE_LEAVES].\n"); + s.push_str(&format!("#define IGNEUM_STATE_BLOCK_HEX {}\n", jstr(&hex_bytes(&l.block)))); + s.push_str(&format!("#define IGNEUM_STATE_BLOCK_NUMBER {}\n", l.number)); + s.push_str(&format!("#define IGNEUM_STATE_ROOT_HEX {}\n", jstr(&hex_bytes(&l.root)))); + s.push_str(&format!("#define IGNEUM_STATE_LEAVES {}\n", l.n())); + s.push_str(&format!("#define IGNEUM_STATE_RECORDS {}\n", l.records_total)); + s.push_str(&format!("#define IGNEUM_STATE_SAMPLED {}\n", l.sampled as u8)); + s.push_str(&format!("#define IGNEUM_STATE_LEAVES_FNV64 {}\n", hex64(l.fnv1a64()))); + s.push_str("#define IGNEUM_STATE_LEAVES_FILE \"leaves.bin\"\n"); + s +} + /// The load class lines of program.h (empty for the lottery hash, so the pinned packs do not change). fn class_header_lines(p: &Program) -> String { if p.class.is_v2() { @@ -758,28 +780,35 @@ pub fn emit_memhard_core_layout(mp: &MixParams, dialect: CoreDialect, layout: La s.push_str("}\n"); } s.push_str(&format!("// Item t: 16 words. s = (K, t * MUL[i] + RC[i]); {ITEM_ROUNDS} rounds of (round program r, cache line s[0] & mask); round program {ITEM_ROUNDS}.\n")); - s.push_str(&format!("{fn_} void mh_item({cptr} cache, {u} t, {lptr} s) {{\n")); + s.push_str(&item_signature(shape.state, fn_, cptr, u, lptr)); for i in 0..8 { s.push_str(&format!(" s[{i}] = {};\n", hex(k[i]))); } for i in 0..8 { s.push_str(&format!(" s[{}] = t * {} + {};\n", 8 + i, hex(mul[i]), hex(c[i]))); } + if shape.state { + s.push_str(&format!(" for ({u} i = 0u; i < 16u; ++i) s[i] ^= leaf[i];\n")); + } for r in 0..ITEM_ROUNDS { s.push_str(&format!(" mh_round_{r}(s);\n")); s.push_str(&format!(" {{ {cptr} line = cache + ((s[0] & MH_CACHE_LINE_MASK) * 16u); for ({u} i = 0u; i < 16u; ++i) s[i] ^= line[i]; }}\n")); } s.push_str(&format!(" mh_round_{ITEM_ROUNDS}(s);\n")); s.push_str("}\n"); - return finish_memhard_core(s, layout, u, fn_, cptr); + return finish_memhard_core(s, layout, u, fn_, cptr, shape.state); } - s.push_str(&format!("{fn_} void mh_item({cptr} cache, {u} t, {lptr} s) {{\n")); + s.push_str(&item_signature(shape.state, fn_, cptr, u, lptr)); for i in 0..8 { s.push_str(&format!(" s[{i}] = {};\n", hex(k[i]))); } for i in 0..8 { s.push_str(&format!(" s[{}] = t * {} + {};\n", 8 + i, hex(mul[i]), hex(c[i]))); } + if shape.state { + // class v5: the window's state leaf of item t, before the first mixer (docs/design/class-v5-stored-state.md) + s.push_str(&format!(" for ({u} i = 0u; i < 16u; ++i) s[i] ^= leaf[i];\n")); + } s.push_str(&format!(" for ({u} r = 0u; r < {ITEM_ROUNDS}u; ++r) {{\n")); if m == 1 { s.push_str(" mh_mixer(s, 0x9E3779B9u * (r + 1u));\n"); @@ -798,22 +827,48 @@ pub fn emit_memhard_core_layout(mp: &MixParams, dialect: CoreDialect, layout: La )); } s.push_str("}\n"); - finish_memhard_core(s, layout, u, fn_, cptr) + finish_memhard_core(s, layout, u, fn_, cptr, shape.state) } -/// The tail of the memhard core: `mh_word` (and the era layout helpers) after `mh_item`. -fn finish_memhard_core(mut s: String, layout: Layout, u: &str, fn_: &str, cptr: &str) -> String { +/// The `mh_item` signature: under a state shape (class v5) the item takes its 16-word leaf (`leaves + 16 (t mod n)`). +fn item_signature(state: bool, fn_: &str, cptr: &str, u: &str, lptr: &str) -> String { + if state { + format!("{fn_} void mh_item({cptr} cache, {cptr} leaf, {u} t, {lptr} s) {{\n") + } else { + format!("{fn_} void mh_item({cptr} cache, {u} t, {lptr} s) {{\n") + } +} + +/// The tail of the memhard core: `mh_word` (and the era layout helpers) after `mh_item`. Under a state shape +/// `mh_word` takes the leaves and their count and derives item t's leaf as `leaves + 16 (t mod nLeaves)`. +fn finish_memhard_core(mut s: String, layout: Layout, u: &str, fn_: &str, cptr: &str, state: bool) -> String { + if state { + s.push_str("// Class v5 (docs/design/class-v5-stored-state.md): leaf(t) = leaves[t mod nLeaves], 16 words per leaf (leaves.bin).\n"); + s.push_str(&format!("{fn_} {cptr} mh_leaf({cptr} leaves, {u} nLeaves, {u} t) {{ return leaves + ((t % nLeaves) * 16u); }}\n")); + } if layout.is_linear() { s.push_str("// dataset[w] without the dataset: derive item w >> 4 and take word w & 15.\n"); - s.push_str(&format!( - "{fn_} {u} mh_word({cptr} cache, {u} w) {{ {u} s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; }}\n" - )); + if state { + s.push_str(&format!( + "{fn_} {u} mh_word({cptr} cache, {cptr} leaves, {u} nLeaves, {u} w) {{ {u} s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, w >> 4u), w >> 4u, s); return s[w & 15u]; }}\n" + )); + } else { + s.push_str(&format!( + "{fn_} {u} mh_word({cptr} cache, {u} w) {{ {u} s[16]; mh_item(cache, w >> 4u, s); return s[w & 15u]; }}\n" + )); + } } else { s.push_str(&layout_helpers(layout, u, fn_)); s.push_str("// dataset[w] without the dataset: derive item mh_t(w) and take word mh_j(w).\n"); - s.push_str(&format!( - "{fn_} {u} mh_word({cptr} cache, {u} w) {{ {u} s[16]; mh_item(cache, mh_t(w), s); return s[mh_j(w)]; }}\n" - )); + if state { + s.push_str(&format!( + "{fn_} {u} mh_word({cptr} cache, {cptr} leaves, {u} nLeaves, {u} w) {{ {u} s[16]; mh_item(cache, mh_leaf(leaves, nLeaves, mh_t(w)), mh_t(w), s); return s[mh_j(w)]; }}\n" + )); + } else { + s.push_str(&format!( + "{fn_} {u} mh_word({cptr} cache, {u} w) {{ {u} s[16]; mh_item(cache, mh_t(w), s); return s[mh_j(w)]; }}\n" + )); + } } s } @@ -872,12 +927,23 @@ pub fn metal_memhard_layout(mp: &MixParams, layout: Layout) -> String { s.push_str(" mh_cache_segment(cache, gid);\n"); s.push_str("}\n"); s.push_str("// One thread per 64-byte item (dataset words / 16 threads).\n"); - s.push_str( - "kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]],\n", - ); - s.push_str(" uint gid [[thread_position_in_grid]]) {\n"); - s.push_str(" uint s[16];\n"); - s.push_str(" mh_item(cache, gid, s);\n"); + if mp.shape.state { + s.push_str("// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) in buffer 2, their count in buffer 3.\n"); + s.push_str( + "kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]],\n", + ); + s.push_str(" device const uint* leaves [[buffer(2)]], constant uint& nLeaves [[buffer(3)]],\n"); + s.push_str(" uint gid [[thread_position_in_grid]]) {\n"); + s.push_str(" uint s[16];\n"); + s.push_str(" mh_item(cache, mh_leaf(leaves, nLeaves, gid), gid, s);\n"); + } else { + s.push_str( + "kernel void igneum_build(device const uint* cache [[buffer(0)]], device uint* dataset [[buffer(1)]],\n", + ); + s.push_str(" uint gid [[thread_position_in_grid]]) {\n"); + s.push_str(" uint s[16];\n"); + s.push_str(" mh_item(cache, gid, s);\n"); + } s.push_str(&build_store(layout, CoreDialect::Metal, "dataset", "gid")); s.push_str("}\n"); s @@ -1043,7 +1109,7 @@ fn generated_by(seed: &str) -> String { format!("// Generated by igneum-pow export (generator v{GENERATOR_VERSION}) for seed \"{seed}\". Do not edit by hand.\n") } -fn hex_bytes(b: &[u8]) -> String { +pub fn hex_bytes(b: &[u8]) -> String { b.iter().map(|x| format!("{x:02x}")).collect() } @@ -1157,11 +1223,20 @@ pub fn cuda_kernel_at(p: &Program, memhard: Option<&MixParams>, dataset_log2: u3 s.push_str(" uint32_t seg = blockIdx.x * blockDim.x + threadIdx.x;\n"); s.push_str(" if (seg < nSegments) mh_cache_segment(cache, seg);\n"); s.push_str("}\n"); - s.push_str("__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) {\n"); + if p.class.state { + s.push_str("// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) and their count.\n"); + s.push_str("__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems) {\n"); + } else { + s.push_str("__global__ void igneum_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) {\n"); + } s.push_str(" uint32_t t = blockIdx.x * blockDim.x + threadIdx.x;\n"); s.push_str(" if (t < nItems) {\n"); s.push_str(" uint32_t s[16];\n"); - s.push_str(" mh_item(cache, t, s);\n"); + if p.class.state { + s.push_str(" mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s);\n"); + } else { + s.push_str(" mh_item(cache, t, s);\n"); + } s.push_str(&build_store(layout, CoreDialect::Cuda, "ds", "t")); s.push_str(" }\n"); s.push_str("}\n"); @@ -1228,11 +1303,20 @@ pub fn cuda_kernel_at(p: &Program, memhard: Option<&MixParams>, dataset_log2: u3 s.push_str(" return cudaGetLastError();\n"); s.push_str("}\n"); s.push('\n'); - s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) {\n"); - s.push_str(" if (nItems == 0u) return cudaErrorInvalidValue;\n"); + if p.class.state { + s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems) {\n"); + s.push_str(" if (nItems == 0u || nLeaves == 0u) return cudaErrorInvalidValue;\n"); + } else { + s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems) {\n"); + s.push_str(" if (nItems == 0u) return cudaErrorInvalidValue;\n"); + } s.push_str(" uint32_t block = 256u;\n"); s.push_str(" uint32_t grid = (nItems + block - 1u) / block;\n"); - s.push_str(" igneum_build<<>>(ds, cache, nItems);\n"); + if p.class.state { + s.push_str(" igneum_build<<>>(ds, cache, leaves, nLeaves, nItems);\n"); + } else { + s.push_str(" igneum_build<<>>(ds, cache, nItems);\n"); + } s.push_str(" return cudaGetLastError();\n"); s.push_str("}\n"); s.push('\n'); @@ -1590,11 +1674,20 @@ pub fn opencl_kernel_at(p: &Program, memhard: Option<&MixParams>, dataset_log2: s.push_str(" uint seg = (uint)get_global_id(0);\n"); s.push_str(" if (seg < nSegments) mh_cache_segment(cache, seg);\n"); s.push_str("}\n"); - s.push_str("__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) {\n"); + if p.class.state { + s.push_str("// Class v5: the window's leaves (leaves.bin, IGNEUM_STATE_LEAVES x 16 words) and their count.\n"); + s.push_str("__kernel void igneum_build(__global uint* ds, __global const uint* cache, __global const uint* leaves, uint nLeaves, uint nItems) {\n"); + } else { + s.push_str("__kernel void igneum_build(__global uint* ds, __global const uint* cache, uint nItems) {\n"); + } s.push_str(" uint t = (uint)get_global_id(0);\n"); s.push_str(" if (t < nItems) {\n"); s.push_str(" uint s[16];\n"); - s.push_str(" mh_item(cache, t, s);\n"); + if p.class.state { + s.push_str(" mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s);\n"); + } else { + s.push_str(" mh_item(cache, t, s);\n"); + } s.push_str(&build_store(layout, CoreDialect::OpenCl, "ds", "t")); s.push_str(" }\n"); s.push_str("}\n"); @@ -1726,6 +1819,7 @@ pub fn program_header(p: &Program, day: &str, ds: &DatasetSource) -> String { s.push_str(&format!("#define IGNEUM_OP_MIX {}\n", jstr(&p.op_mix()))); s.push_str(&program_class_header_lines(p)); s.push_str(&class_header_lines(p)); + s.push_str(&state_header_lines(ds)); s.push_str(&scratch_header_lines(p)); s.push_str(&era_header_lines(p)); s.push_str(&hot_header_lines(p)); @@ -1762,7 +1856,11 @@ pub fn program_header(p: &Program, day: &str, ds: &DatasetSource) -> String { s.push_str("#ifndef IGNEUM_NO_CUDA\n"); s.push_str("// Defined in kernel.cu. All launch on the default stream and return cudaGetLastError().\n"); s.push_str("cudaError_t igneum_launch_cache_fill(uint32_t* cache, uint32_t nSegments);\n"); - s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems);\n"); + if p.class.state { + s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems);\n"); + } else { + s.push_str("cudaError_t igneum_launch_build(uint32_t* ds, const uint32_t* cache, uint32_t nItems);\n"); + } if p.has_hot() { s.push_str("cudaError_t igneum_launch_hot_fill(uint32_t* hot, uint32_t nSegments);\n"); } @@ -1960,6 +2058,19 @@ pub fn program_json(p: &Program, day: &str, ds: &DatasetSource) -> String { s.push_str(&format!(" \"era_seed_bytes\": {},\n", jstr(&hex_bytes(era)))); } } + if let Some(l) = ds.leaves() { + s.push_str(" \"state\": {\n"); + s.push_str(&format!(" \"block\": {},\n", jstr(&hex_bytes(&l.block)))); + s.push_str(&format!(" \"block_number\": {},\n", l.number)); + s.push_str(&format!(" \"root\": {},\n", jstr(&hex_bytes(&l.root)))); + s.push_str(&format!(" \"leaves\": {},\n", l.n())); + s.push_str(&format!(" \"records\": {},\n", l.records_total)); + s.push_str(&format!(" \"sampled\": {},\n", l.sampled)); + s.push_str(&format!(" \"leaves_fnv1a64\": {},\n", jhex64(l.fnv1a64()))); + s.push_str(" \"leaf_derivation\": \"leaves[i] = Blake2b-512('igneum-sd1/' || root || i_le32 || record_i) as 16 little-endian words; item t XORs leaves[t mod leaves] into its 16 initial words before the first mixer\",\n"); + s.push_str(" \"file\": \"leaves.bin\"\n"); + s.push_str(" },\n"); + } if !p.class.is_v2() { let c = p.width_counts(); s.push_str(&format!(" \"load_class\": {},\n", jstr(&p.class.name()))); @@ -2255,6 +2366,8 @@ pub fn vectors_json( /// A program pack: the files `--export-pack` writes, as (name, text). pub struct Pack { pub files: Vec<(String, String)>, + /// Binary files beside the texts: `leaves.bin` of a class v5 pack (empty for every other pack). + pub binaries: Vec<(String, Vec)>, pub bases: Vec, pub outs: Vec<[u64; 32]>, pub vectors: PackVectors, @@ -2266,6 +2379,9 @@ impl Pack { for (name, text) in &self.files { std::fs::write(dir.join(name), text)?; } + for (name, bytes) in &self.binaries { + std::fs::write(dir.join(name), bytes)?; + } Ok(()) } } @@ -2319,7 +2435,11 @@ pub fn export_pack(epoch: &Epoch, day: &str, source: &str) -> Pack { files.push(("memhard.h".to_string(), cuda_memhard_header(p, mp))); files.push(("memhard.metal".to_string(), metal_memhard_for(p, mp))); } - Pack { files, bases, outs, vectors: v } + let binaries = match ds.leaves() { + Some(l) => vec![("leaves.bin".to_string(), l.bytes())], + None => Vec::new(), + }; + Pack { files, binaries, bases, outs, vectors: v } } /// The dataset mode a pack was written in, from its program.json text (no JSON parser needed). diff --git a/igneum-pow/src/lib.rs b/igneum-pow/src/lib.rs index 49df395da..fca2e06fc 100644 --- a/igneum-pow/src/lib.rs +++ b/igneum-pow/src/lib.rs @@ -24,6 +24,7 @@ pub mod accept; pub mod bind; +pub mod blake2b; pub mod derive; pub mod emit; pub mod generator; @@ -31,11 +32,13 @@ pub mod memhard; pub mod mm8; pub mod packcheck; pub mod seed; +pub mod state; pub mod verify; pub use bind::{block_init_words, day_bytes, pow256_from_lane, target64_from_le256}; pub use accept::{check as accept_program, AcceptReport, Reject}; -pub use generator::{generate, generate_from_seed_bytes, generate_from_seed_bytes_program_class, generate_from_seed_bytes_program_class_shadow, v4_class_at, v4_counted_ops, v4_rung_reps, Instr, LoadClass, Op, Program, ProgramClass, GENERATOR_VERSION, GENERATOR_VERSION_V3, GENERATOR_VERSION_V4, V3_CLASS, V4_CLASS, V4_SHADOW_INSTRS, V4_SHADOW_REPS}; +pub use generator::{generate, generate_from_seed_bytes, generate_from_seed_bytes_program_class, generate_from_seed_bytes_program_class_shadow, v4_class_at, v4_counted_ops, v4_rung_reps, v5_class_at, v5_rung_reps, Instr, LoadClass, Op, Program, ProgramClass, GENERATOR_VERSION, GENERATOR_VERSION_V3, GENERATOR_VERSION_V4, GENERATOR_VERSION_V5, V3_CLASS, V4_CLASS, V4_SHADOW_INSTRS, V4_SHADOW_REPS, V5_CLASS, PROGRAM_SUBVERSION_V4}; pub use memhard::{cache_log2_words, dataset_log2_words, days_since_genesis, growth_doublings, Cache, MemhardCpu, MixParams, Shape}; pub use seed::{fnv1a64, seed_words, SplitMix64}; +pub use state::{StateLeaves, StateStream}; pub use verify::{hash_warp, interpret_warp_init, verify_block, DatasetMode, DatasetSource, Epoch}; diff --git a/igneum-pow/src/main.rs b/igneum-pow/src/main.rs index 29bb77d80..95795cd5d 100644 --- a/igneum-pow/src/main.rs +++ b/igneum-pow/src/main.rs @@ -39,6 +39,9 @@ struct Args { prehash: String, epoch_hex: Option, day_hex: Option, + /// Class v5: the window's state stream file (`--state `, the IGSD1 format of `igneum_pow::state`), whose + /// leaves every item of the dataset is keyed by. + state: Option, class: LoadClass, /// Days since genesis for the cache growth rule of a class with `growth` (0: the genesis cache). days: u64, @@ -101,7 +104,8 @@ fn usage() -> ! { \x20 --class C load class: v2 (default), mx4, mx8 (class v3: mixer x8, cache growth), dr (Counter ASIC 3.0 item 2: the per-day derivation program, dr736 = the x8-equivalent), w4, w16, w64, w64x4, p4,p16,p64[xN], m[g]\n\ \x20 also: w4, w16, w64, w64x4, p4,p16,p64[xN], m[g], +shx (latency-shadow block of S ALU instructions x R passes per iteration, Counter ASIC 3.0 item 8)\n\ \x20 --days N days since genesis for the cache growth rule of a class with it (default 0: the 2^26-word cache)\n\ - \x20 --program-class v2|v3|v4 the program class of the seam (v3 = generator 3 on V3_CLASS, v4 = generator 4 on V4_CLASS = mx8+sh256x27, the chain's own derivation; --era-hex records the era seed)\n\ + \x20 --program-class v2|v3|v4|v5 the program class of the seam (v3 = generator 3 on V3_CLASS, v4 = generator 4 on V4_CLASS = mx8+sh256x27, v5 = generator 5 on V5_CLASS = mx8+sh256x27+state, the chain's own derivation; --era-hex records the era seed)\n\ + \x20 --state class v5 (or any --class ...+state): the window's state stream (IGSD1 file, igneum-day-stream --out), whose leaves key every item\n\ \x20 --shadow-reps N class v4 at a rung of the latency ladder: the shadow block's pass count (0 = the class's own 27; docs/design/latency-ladder.md), with --program-class v4\n\ \x20 --era E era layout over --class: igneum-era-test/ or :<64 hex> (the 32-byte era seed E_n)\n\ \x20 --era-widths 4[,16,64] the width set the era draws from, in bytes (default 4: pinned; more lets the era draw it)" @@ -116,6 +120,7 @@ fn parse() -> Args { day: "2026-10-03".into(), out: None, closed_form: false, + state: None, dataset_log2: DEFAULT_DATASET_LOG2, warps: 20, nonce: 0, @@ -150,6 +155,7 @@ fn parse() -> Args { "--class" => a.class = LoadClass::parse(&val()).unwrap_or_else(|| usage()), "--days" => a.days = val().parse().unwrap_or_else(|_| usage()), "--program-class" => a.program_class = Some(ProgramClass::parse(&val()).unwrap_or_else(|| usage())), + "--state" => a.state = Some(val()), "--era-hex" => a.era_hex = Some(val()), "--shadow-reps" => a.shadow_reps = val().parse().unwrap_or_else(|_| usage()), "--era" => a.era = Some(parse_era(&val()).unwrap_or_else(|| usage())), @@ -216,6 +222,33 @@ fn main() { fn epoch_of(a: &Args, mode: DatasetMode) -> (Epoch, String) { let (mut e, label) = epoch_of_class(a, mode); stamp_era(&mut e, a); + // class v5: the leaves of --state, built for the dataset's size; a state class without --state is refused here + // rather than at the first derivation + if e.program.class.state { + let Some(path) = &a.state else { + eprintln!("class {} keys every item by the window's state: give --state (igneum-day-stream --out)", e.program.class.name()); + std::process::exit(2); + }; + let stream = igneum_pow::state::StateStream::read_file(std::path::Path::new(path)).unwrap_or_else(|err| { + eprintln!("{err}"); + std::process::exit(2) + }); + let leaves = igneum_pow::state::StateLeaves::from_stream(&stream, e.dataset.log2_words); + eprintln!( + "state stream {}: chain block {} {}, root {}, {} records, {} leaves{}", + path, + stream.number, + igneum_pow::emit::hex_bytes(&stream.block), + igneum_pow::emit::hex_bytes(&stream.root), + stream.records.len(), + leaves.n(), + if leaves.sampled { " (sampled)" } else { "" } + ); + e.dataset = e.dataset.with_leaves(std::sync::Arc::new(leaves)); + } else if a.state.is_some() { + eprintln!("--state given for a class without state leaves ({}); use --program-class v5 or --class +state", e.program.class.name()); + std::process::exit(2); + } (e, label) } diff --git a/igneum-pow/src/memhard.rs b/igneum-pow/src/memhard.rs index ad42470b3..63a35ee50 100644 --- a/igneum-pow/src/memhard.rs +++ b/igneum-pow/src/memhard.rs @@ -12,6 +12,8 @@ use crate::derive::{run_round, DeriveProgram, SoaState, DERIVE_REGS, SOA_LANES}; use crate::generator::LoadClass; use crate::seed::{day_key, fnv1a64_words, SplitMix64}; +use crate::state::StateLeaves; +use std::sync::Arc; pub const CACHE_LOG2_WORDS: usize = 26; pub const CACHE_SEGMENT_LOG2_LINES: usize = 6; @@ -50,11 +52,14 @@ pub struct Shape { /// program, which replaces the `mixer_mult` applications of `M_r` in every mixer slot when non-zero. 0 for /// version 2 and class v3 (the fixed mixer). pub derive_len: u32, + /// Class v5 (`docs/design/class-v5-stored-state.md`, 7 October 2026): the item derivation XORs the window's state + /// leaf `leaf(t)` into the 16 initial words before the first mixer (`crate::state`). `false` for every other class. + pub state: bool, } impl Shape { /// Version 2: one mixer application per round, a 2^26-word cache. - pub const V2: Shape = Shape { mixer_mult: 1, cache_log2_words: CACHE_LOG2_WORDS as u32, derive_len: 0 }; + pub const V2: Shape = Shape { mixer_mult: 1, cache_log2_words: CACHE_LOG2_WORDS as u32, derive_len: 0, state: false }; /// The shape of a load class on day 0 of the chain (and on every day for a class without the growth rule). pub fn for_class(class: &LoadClass) -> Shape { @@ -68,6 +73,7 @@ impl Shape { mixer_mult: class.mixer_mult(), cache_log2_words: if class.growth { cache_log2_words(days_since_genesis) } else { CACHE_LOG2_WORDS as u32 }, derive_len: class.derive_len as u32, + state: class.state, } } @@ -200,6 +206,46 @@ pub struct MixParams { pub shape: Shape, /// The per-day derivation program when `shape.derive_len != 0`, else `None`. pub derive: Option, + /// Class v5: how many mixer blocks the AP-F4-1 rule redrew before this one (0 on every other class, and on most days). + pub redraws: u32, +} + +/// Class v5's mixer-draw rule (AP-F4-1): the NAF sum of the 16 multipliers at least this. +pub const MIXER_NAF_SUM_MIN: u32 = 163; +/// Class v5's mixer-draw rule: every multiplier's NAF weight at least this. +pub const MIXER_NAF_WORD_MIN: u32 = 4; +/// Class v5's mixer-draw rule: at least this many distinct rotation amounts among the eight. +pub const MIXER_DISTINCT_ROT_MIN: usize = 4; +/// Class v5's mixer-draw rule: redraws before the last block stands as drawn (never reached at 6.1e-4 per try). +pub const MIXER_REDRAW_CAP: u32 = 64; + +/// The non-adjacent-form weight of a 32-bit word: the number of non-zero digits of its NAF, the adders a +/// shift-and-add multiplier by that constant needs (the M1 metric of the weak-day census). +pub fn naf_weight(mut x: u64) -> u32 { + let mut w = 0; + while x != 0 { + if x & 1 == 1 { + w += 1; + // the digit is +1 or -1: take x to the nearest multiple of 4 + if x & 3 == 3 { + x += 1; + } else { + x -= 1; + } + } + x >>= 1; + } + w +} + +/// Whether a mixer block passes class v5's draw rule (AP-F4-1). +pub fn mixer_block_admissible(rot: &[u32; 8], mul: &[u32; 16]) -> bool { + let sum: u32 = mul.iter().map(|&m| naf_weight(m as u64)).sum(); + let words = mul.iter().all(|&m| naf_weight(m as u64) >= MIXER_NAF_WORD_MIN); + let mut distinct = rot.to_vec(); + distinct.sort_unstable(); + distinct.dedup(); + sum >= MIXER_NAF_SUM_MIN && words && distinct.len() >= MIXER_DISTINCT_ROT_MIN } impl MixParams { @@ -221,8 +267,28 @@ impl MixParams { for c in rc.iter_mut() { *c = rng.next() as u32; } + let mut redraws = 0u32; + if shape.state { + // Class v5 (docs/design/class-v5-stored-state.md section 11, AP-F4-1, the attack-pass lane's weak-day census): + // a mixer block whose multipliers are cheap on an adder datapath (NAF sum under 163, a word under NAF weight 4) + // or whose rotations repeat (under 4 distinct amounts) is redrawn from the next stream values, so no day is a + // weak day for a per-day LUT-recompute FPGA (the worst calendar day of the census, chain day 29,337, was 1.121x). + // About 6.1e-4 of days redraw. The derive program's draws (none under v5) come after, as before. + while !mixer_block_admissible(&rot, &mul) && redraws < MIXER_REDRAW_CAP { + for r in rot.iter_mut() { + *r = 1 + rng.below(31) as u32; + } + for m in mul.iter_mut() { + *m = (rng.next() as u32) | 1; + } + for c in rc.iter_mut() { + *c = rng.next() as u32; + } + redraws += 1; + } + } let derive = if shape.is_derived() { Some(DeriveProgram::draw(&mut rng, shape.derive_len)) } else { None }; - Self { key, rot, mul, rc, shape, derive } + Self { key, rot, mul, rc, shape, derive, redraws } } /// Parameters for a day string: the key is `seed_words("day/" + day)`. pub fn for_day(day: &str) -> Self { @@ -374,7 +440,7 @@ impl Cache { /// are the smaller cache's segments word for word. pub fn fill_log2(key: [u32; 8], log2_words: u32) -> Cache { assert!((10..=30).contains(&log2_words), "cache log2 words must be in 10..=30"); - let shape = Shape { mixer_mult: 1, cache_log2_words: log2_words, derive_len: 0 }; + let shape = Shape { mixer_mult: 1, cache_log2_words: log2_words, derive_len: 0, state: false }; let mut words = vec![0u32; shape.cache_words()]; for seg in 0..shape.cache_segments() { Self::fill_segment(&mut words, seg, &key); @@ -505,8 +571,21 @@ impl HotTable { /// (`mp.shape.mixer_mult`) round `r` applies `M` with keys `round_key(r m + j)` for `j = 0 .. m - 1` before its /// one cache read; the final mixer applies `M` with keys `round_key(8 m + j)`. `m = 1` is version 2. pub fn derive_items(ts: &[u32], mp: &MixParams, cache: &Cache, out: &mut [[u32; 16]]) { + derive_items_leaves(ts, mp, cache, None, out) +} + +/// [`derive_items`] with the state leaves of class v5 (`docs/design/class-v5-stored-state.md` section 2): under a +/// shape with `state`, `leaf(t)` is XORed into the 16 initial words of item `t` before the first mixer, and the leaves +/// are required; under any other shape they must be absent. A mismatch is a programming error and panics: a dataset +/// built without the state it needs would be wrong on every item, which is the class's point. +pub fn derive_items_leaves(ts: &[u32], mp: &MixParams, cache: &Cache, leaves: Option<&StateLeaves>, out: &mut [[u32; 16]]) { + match (mp.shape.state, leaves) { + (true, None) => panic!("class v5 item derivation needs the window's state leaves and was given none"), + (false, Some(_)) => panic!("state leaves given to an item derivation whose shape has no state"), + _ => {} + } if let Some(prog) = &mp.derive { - return derive_items_program(ts, mp, prog, cache, out); + return derive_items_program(ts, mp, prog, cache, leaves, out); } // The item loop lives in its own function, one instance per cache size the growth rule can reach with the line // mask a constant, never inlined into the callers. Inlined into `MemhardCpu::fetch` it ran at 1.33 ms per unit @@ -515,19 +594,19 @@ pub fn derive_items(ts: &[u32], mp: &MixParams, cache: &Cache, out: &mut [[u32; // constant with the loop still inlined, all stayed at 1.33; the out-of-line instances read 0.60 to 0.62). Any // other cache size (tests) takes the instance with the run-time mask. match cache.log2_words { - 26 => derive_items_mask::<{ (1u32 << 22) - 1 }>(ts, mp, cache, out), - 27 => derive_items_mask::<{ (1u32 << 23) - 1 }>(ts, mp, cache, out), - 28 => derive_items_mask::<{ (1u32 << 24) - 1 }>(ts, mp, cache, out), - 29 => derive_items_mask::<{ (1u32 << 25) - 1 }>(ts, mp, cache, out), - 30 => derive_items_mask::<{ (1u32 << 26) - 1 }>(ts, mp, cache, out), - _ => derive_items_mask::<0>(ts, mp, cache, out), + 26 => derive_items_mask::<{ (1u32 << 22) - 1 }>(ts, mp, cache, leaves, out), + 27 => derive_items_mask::<{ (1u32 << 23) - 1 }>(ts, mp, cache, leaves, out), + 28 => derive_items_mask::<{ (1u32 << 24) - 1 }>(ts, mp, cache, leaves, out), + 29 => derive_items_mask::<{ (1u32 << 25) - 1 }>(ts, mp, cache, leaves, out), + 30 => derive_items_mask::<{ (1u32 << 26) - 1 }>(ts, mp, cache, leaves, out), + _ => derive_items_mask::<0>(ts, mp, cache, leaves, out), } } /// [`derive_items`] with the cache line mask as a constant (`LINE_MASK = 0`: the cache's own run-time mask). Kept /// out of line on purpose (see [`derive_items`]). #[inline(never)] -fn derive_items_mask(ts: &[u32], mp: &MixParams, cache: &Cache, out: &mut [[u32; 16]]) { +fn derive_items_mask(ts: &[u32], mp: &MixParams, cache: &Cache, leaves: Option<&StateLeaves>, out: &mut [[u32; 16]]) { let n = ts.len(); debug_assert!(out.len() >= n); debug_assert!(LINE_MASK == 0 || LINE_MASK == cache.line_mask); @@ -539,6 +618,13 @@ fn derive_items_mask(ts: &[u32], mp: &MixParams, cache: &C for i in 0..8 { s[8 + i] = t.wrapping_mul(mp.mul[i]).wrapping_add(mp.rc[i]); } + if let Some(l) = leaves { + // class v5: the window's state leaf of item t, before the first mixer + let leaf = l.leaf(t); + for i in 0..16 { + s[i] ^= leaf[i]; + } + } } for r in 0..ITEM_ROUNDS { for j in 0..m { @@ -570,7 +656,7 @@ fn derive_items_mask(ts: &[u32], mp: &MixParams, cache: &C /// cache reads of the batch are issued together, as in the fixed-mixer loop, so the 8 dependent misses of /// independent items overlap in the memory system. #[inline(never)] -pub fn derive_items_program(ts: &[u32], mp: &MixParams, prog: &DeriveProgram, cache: &Cache, out: &mut [[u32; 16]]) { +pub fn derive_items_program(ts: &[u32], mp: &MixParams, prog: &DeriveProgram, cache: &Cache, leaves: Option<&StateLeaves>, out: &mut [[u32; 16]]) { let n = ts.len(); debug_assert!(out.len() >= n && n <= SOA_LANES); assert_eq!(prog.rounds.len(), ITEM_ROUNDS + 1); @@ -581,6 +667,12 @@ pub fn derive_items_program(ts: &[u32], mp: &MixParams, prog: &DeriveProgram, ca st[i][k] = mp.key[i]; st[8 + i][k] = t.wrapping_mul(mp.mul[i]).wrapping_add(mp.rc[i]); } + if let Some(l) = leaves { + let leaf = l.leaf(t); + for i in 0..16 { + st[i][k] ^= leaf[i]; + } + } } let mask = cache.line_mask(); for r in 0..ITEM_ROUNDS { @@ -602,15 +694,22 @@ pub fn derive_items_program(ts: &[u32], mp: &MixParams, prog: &DeriveProgram, ca /// One dataset item, 16 words. pub fn derive_item(t: u32, mp: &MixParams, cache: &Cache) -> [u32; 16] { + derive_item_leaves(t, mp, cache, None) +} + +/// [`derive_item`] with the state leaves of class v5. +pub fn derive_item_leaves(t: u32, mp: &MixParams, cache: &Cache, leaves: Option<&StateLeaves>) -> [u32; 16] { let mut out = [[0u32; 16]; 1]; - derive_items(&[t], mp, cache, &mut out); + derive_items_leaves(&[t], mp, cache, leaves, &mut out); out[0] } -/// The CPU verifier's view of the memory-hard dataset: the mixer parameters (with the shape) and the cache. +/// The CPU verifier's view of the memory-hard dataset: the mixer parameters (with the shape), the cache (shared, so +/// a class v5 window refresh keeps the day's 256 MiB and swaps the leaves) and, under class v5, the window's leaves. pub struct MemhardCpu { pub params: MixParams, - pub cache: Cache, + pub cache: Arc, + pub leaves: Option>, } /// Largest batch `MemhardCpu::fetch` accepts (two warps). @@ -622,7 +721,7 @@ impl MemhardCpu { Self::with_shape(key, Shape::V2) } pub fn with_shape(key: [u32; 8], shape: Shape) -> Self { - Self { params: MixParams::with_shape(key, shape), cache: Cache::fill_log2(key, shape.cache_log2_words) } + Self { params: MixParams::with_shape(key, shape), cache: Arc::new(Cache::fill_log2(key, shape.cache_log2_words)), leaves: None } } pub fn for_day(day: &str) -> Self { Self::new(day_key(day)) @@ -630,6 +729,17 @@ impl MemhardCpu { pub fn shape(&self) -> Shape { self.params.shape } + /// This view with the window's state leaves (class v5). The shape must have `state`. + pub fn with_leaves(mut self, leaves: Arc) -> Self { + assert!(self.params.shape.state, "state leaves on a shape without state"); + self.leaves = Some(leaves); + self + } + /// A view of the same day (the same cache, shared) with other leaves: the class v5 window refresh. + pub fn refreshed(&self, leaves: Arc) -> Self { + assert!(self.params.shape.state, "state leaves on a shape without state"); + Self { params: self.params.clone(), cache: self.cache.clone(), leaves: Some(leaves) } + } /// `dataset[w] = item(w >> 4)[w & 15]` (the linear layout). pub fn word(&self, w: u32) -> u32 { self.word_at(Layout::LINEAR, w) @@ -638,7 +748,7 @@ impl MemhardCpu { /// day's, so one cache serves every era of a day). pub fn word_at(&self, layout: Layout, w: u32) -> u32 { let (t, j) = layout.split(w); - derive_item(t, &self.params, &self.cache)[j as usize] + derive_item_leaves(t, &self.params, &self.cache, self.leaves.as_deref())[j as usize] } /// `out[k] = dataset[idx[k]]` for every k, `idx.len() <= FETCH_MAX`. Equal items are derived once. /// Returns the number of distinct items derived. @@ -664,7 +774,7 @@ impl MemhardCpu { slot[k] = j as u8; } let mut items = [[0u32; 16]; FETCH_MAX]; - derive_items(&uniq[..u], &self.params, &self.cache, &mut items); + derive_items_leaves(&uniq[..u], &self.params, &self.cache, self.leaves.as_deref(), &mut items); for k in 0..n { out[k] = items[slot[k] as usize][word[k] as usize]; } @@ -695,7 +805,7 @@ impl MemhardCpu { slot[k] = j as u8; } let mut items = [[0u32; 16]; FETCH_MAX]; - derive_items(&uniq[..u], &self.params, &self.cache, &mut items); + derive_items_leaves(&uniq[..u], &self.params, &self.cache, self.leaves.as_deref(), &mut items); for k in 0..n { let o = word[k] as usize; out[k][..width].copy_from_slice(&items[slot[k] as usize][o..o + width]); @@ -708,6 +818,50 @@ impl MemhardCpu { mod tests { use super::*; + /// Class v5's mixer-draw rule (AP-F4-1), the known-failed case first: a block of cheap multipliers (NAF sum under + /// 163) or repeated rotations is inadmissible; a scan of day keys finds days the rule redraws (the census's 6.1e-4), + /// every v5 block passes after the draw, and the v4 constants of the same keys never move. + #[test] + fn class_v5_mixer_draw_rule() { + assert_eq!(naf_weight(0), 0); + assert_eq!(naf_weight(1), 1); + assert_eq!(naf_weight(3), 2, "11 = 100 - 1"); + assert_eq!(naf_weight(7), 2, "111 = 1000 - 1"); + assert_eq!(naf_weight(0xffff_ffff), 2); + assert_eq!(naf_weight(0b1010_1010), 4); + let good_rot = [1u32, 5, 9, 13, 17, 21, 25, 29]; + let cheap = [0x8000_0001u32; 16]; + assert!(!mixer_block_admissible(&good_rot, &cheap), "the known-failed case: 16 two-adder multipliers"); + let dense = [0xaaaa_aaabu32; 16]; + assert!(mixer_block_admissible(&good_rot, &dense)); + assert!(!mixer_block_admissible(&[7u32; 8], &dense), "one rotation amount"); + assert!(!mixer_block_admissible(&[1u32, 2, 3, 3, 3, 3, 3, 3], &dense), "three distinct amounts"); + let v5 = Shape { mixer_mult: 8, cache_log2_words: 26, derive_len: 0, state: true }; + let v4 = Shape { mixer_mult: 8, cache_log2_words: 26, derive_len: 0, state: false }; + let mut redrawn = 0; + let mut scanned = 0; + for d in 0..60_000u64 { + let key = crate::seed::seed_words_from_bytes(&crate::bind::day_bytes(20_000 + d)); + let a = MixParams::with_shape(key, v5); + assert!(mixer_block_admissible(&a.rot, &a.mul), "day {d}: a v5 block fails the rule after the draw"); + if a.redraws > 0 { + redrawn += 1; + let b = MixParams::with_shape(key, v4); + assert_eq!(b.redraws, 0, "v4 never redraws"); + assert_ne!((a.rot, a.mul), (b.rot, b.mul), "day {d}: v5 redrew, v4 kept the block"); + assert!(!mixer_block_admissible(&b.rot, &b.mul), "day {d}: the v4 block was the inadmissible one"); + } else { + let b = MixParams::with_shape(key, v4); + assert_eq!((a.rot, a.mul, a.rc), (b.rot, b.mul, b.rc), "day {d}: an admissible day is byte for byte v4's"); + } + scanned += 1; + if redrawn >= 3 && scanned >= 2_000 { + break; + } + } + assert!(redrawn >= 1, "no redraw in {scanned} days (the census says about 6.1e-4 per day)"); + } + #[test] fn mix_params_for_day() { // MEMHARD.md section 1.4 and the igneum-genesis-mh pack. @@ -851,7 +1005,7 @@ mod tests { let v2 = Shape::for_class_day(&LoadClass::V2, 100_000); assert_eq!(v2, Shape::V2); let v3 = Shape::for_class_day(&LoadClass::MX4, 0); - assert_eq!(v3, Shape { mixer_mult: 4, cache_log2_words: 26, derive_len: 0 }); + assert_eq!(v3, Shape { mixer_mult: 4, cache_log2_words: 26, derive_len: 0, state: false }); assert_eq!(Shape::for_class_day(&LoadClass::MX4, 1_460).cache_log2_words, 27); assert_eq!(v3.mixers_per_item(), 36); assert_eq!(Shape::V2.mixers_per_item(), 9); @@ -872,7 +1026,7 @@ mod tests { assert_eq!(small.segments(), 64); assert_eq!(small.line_mask(), 4095); for m in [1u32, 2, 4] { - let mp = MixParams::with_shape(key, Shape { mixer_mult: m, cache_log2_words: 16, derive_len: 0 }); + let mp = MixParams::with_shape(key, Shape { mixer_mult: m, cache_log2_words: 16, derive_len: 0, state: false }); for t in [0u32, 1, 12_345, u32::MAX] { let got = derive_item(t, &mp, &small); let mut s = [0u32; 16]; @@ -895,8 +1049,8 @@ mod tests { assert_eq!(got, s, "m {m} t {t}"); } } - let v2 = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: 0 }); - let v3 = MixParams::with_shape(key, Shape { mixer_mult: 4, cache_log2_words: 16, derive_len: 0 }); + let v2 = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: 0, state: false }); + let v3 = MixParams::with_shape(key, Shape { mixer_mult: 4, cache_log2_words: 16, derive_len: 0, state: false }); assert_ne!(derive_item(0, &v2, &small), derive_item(0, &v3, &small)); assert_eq!(round_key_mult(0, 0, 1), round_key(0)); assert_eq!(round_key_mult(8, 0, 1), round_key(8)); diff --git a/igneum-pow/src/state.rs b/igneum-pow/src/state.rs new file mode 100644 index 000000000..4298b7fde --- /dev/null +++ b/igneum-pow/src/state.rs @@ -0,0 +1,287 @@ +//! Class v5, proof of stored state and of following (`docs/design/class-v5-stored-state.md`, 7 October 2026): the +//! leaves the item derivation XORs in (section 2 of the page), built from the canonical state stream of the +//! window's reference block. +//! +//! `D[i] = Blake2b-512("igneum-sd1/" || root || i_le32 || record_i)` for the `n` records of the stream, and item +//! `t` takes `leaf(t) = D[t mod n]`: every item is keyed by the state, so a hasher without it is wrong on every +//! item (the known-failed case, the first test). When the stream has more records than the dataset has items, the +//! records are ordered by `Blake2b-256("igneum-sd1-sample/" || root || record)` and the first `items` are taken, a +//! sample nobody can choose without the whole state and the root. +//! +//! The stream file (`StateStream`): the plain format every side reads without a serialisation library, `IGSD1\0`, +//! the chain block number (le64) and hash (32), the state root (32), the record count (le32), then each record as +//! its length (le32) and bytes. The node's executor writes it (`igneum/exec/src/day_stream.rs`), the miner fetches +//! it, the CLI's `--state` reads it, and a pack carries the leaves it yields as `leaves.bin`. + +use crate::blake2b::{blake2b_256, blake2b_512}; +use crate::seed::fnv1a64_words; + +pub const LEAF_TAG: &[u8] = b"igneum-sd1/"; +pub const SAMPLE_TAG: &[u8] = b"igneum-sd1-sample/"; +pub const STREAM_MAGIC: &[u8; 6] = b"IGSD1\0"; + +/// The canonical state stream at one chain block: what the executor serialises and what the leaves derive from. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct StateStream { + pub number: u64, + pub block: [u8; 32], + pub root: [u8; 32], + pub records: Vec>, +} + +impl StateStream { + pub fn encode(&self) -> Vec { + let mut b = Vec::with_capacity(6 + 8 + 32 + 32 + 4 + self.records.iter().map(|r| 4 + r.len()).sum::()); + b.extend_from_slice(STREAM_MAGIC); + b.extend_from_slice(&self.number.to_le_bytes()); + b.extend_from_slice(&self.block); + b.extend_from_slice(&self.root); + b.extend_from_slice(&(self.records.len() as u32).to_le_bytes()); + for r in &self.records { + b.extend_from_slice(&(r.len() as u32).to_le_bytes()); + b.extend_from_slice(r); + } + b + } + + pub fn decode(bytes: &[u8]) -> Result { + if bytes.len() < 6 + 8 + 32 + 32 + 4 || &bytes[..6] != STREAM_MAGIC { + return Err("not a state stream file (magic IGSD1)".into()); + } + let mut at = 6; + let number = u64::from_le_bytes(bytes[at..at + 8].try_into().unwrap()); + at += 8; + let block: [u8; 32] = bytes[at..at + 32].try_into().unwrap(); + at += 32; + let root: [u8; 32] = bytes[at..at + 32].try_into().unwrap(); + at += 32; + let n = u32::from_le_bytes(bytes[at..at + 4].try_into().unwrap()) as usize; + at += 4; + let mut records = Vec::with_capacity(n.min(1 << 20)); + for i in 0..n { + if at + 4 > bytes.len() { + return Err(format!("state stream truncated at record {i} of {n}")); + } + let len = u32::from_le_bytes(bytes[at..at + 4].try_into().unwrap()) as usize; + at += 4; + if at + len > bytes.len() { + return Err(format!("state stream truncated inside record {i} of {n}")); + } + records.push(bytes[at..at + len].to_vec()); + at += len; + } + if at != bytes.len() { + return Err(format!("state stream has {} trailing bytes", bytes.len() - at)); + } + Ok(StateStream { number, block, root, records }) + } + + pub fn read_file(path: &std::path::Path) -> Result { + let bytes = std::fs::read(path).map_err(|e| format!("read {}: {e}", path.display()))?; + Self::decode(&bytes) + } +} + +/// `D[i]`: the 64-byte digest of record `i` under `root`, as 16 little-endian words. +pub fn leaf_digest(root: &[u8; 32], i: u32, record: &[u8]) -> [u32; 16] { + let d = blake2b_512(&[LEAF_TAG, root, &i.to_le_bytes(), record]); + let mut w = [0u32; 16]; + for (k, x) in w.iter_mut().enumerate() { + *x = u32::from_le_bytes(d[k * 4..k * 4 + 4].try_into().unwrap()); + } + w +} + +/// The sample order key of a record under `root`. +pub fn sample_key(root: &[u8; 32], record: &[u8]) -> [u8; 32] { + blake2b_256(&[SAMPLE_TAG, root, record]) +} + +/// The leaves of one window (or day) of class v5: `n` digests of 64 bytes, `leaf(t) = D[t mod n]`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct StateLeaves { + pub root: [u8; 32], + pub block: [u8; 32], + pub number: u64, + /// Records in the stream before any sample. + pub records_total: u64, + /// Whether the stream had more records than the dataset has items (the sample rule applied). + pub sampled: bool, + leaves: Vec<[u32; 16]>, +} + +impl StateLeaves { + /// The items a dataset of `2^log2_words` words has: `2^(log2_words - 4)`. + pub fn items_of(log2_words: u32) -> u64 { + 1u64 << log2_words.saturating_sub(4) + } + + /// The leaves of `records` (canonical order) under `root` for a dataset of `2^log2_words` words. An empty stream + /// yields one leaf, the digest of the empty record, so `n` is never 0. + pub fn build(root: [u8; 32], block: [u8; 32], number: u64, records: &[Vec], log2_words: u32) -> StateLeaves { + let items = Self::items_of(log2_words); + let records_total = records.len() as u64; + let empty: Vec> = vec![Vec::new()]; + let records = if records.is_empty() { &empty[..] } else { records }; + let sampled = records.len() as u64 > items; + let chosen: Vec<&Vec> = if sampled { + let mut keyed: Vec<([u8; 32], &Vec)> = records.iter().map(|r| (sample_key(&root, r), r)).collect(); + keyed.sort_unstable_by(|a, b| a.0.cmp(&b.0).then_with(|| a.1.cmp(b.1))); + keyed.into_iter().take(items as usize).map(|(_, r)| r).collect() + } else { + records.iter().collect() + }; + let leaves = chosen.iter().enumerate().map(|(i, r)| leaf_digest(&root, i as u32, r)).collect(); + StateLeaves { root, block, number, records_total, sampled, leaves } + } + + pub fn from_stream(s: &StateStream, log2_words: u32) -> StateLeaves { + Self::build(s.root, s.block, s.number, &s.records, log2_words) + } + + /// Leaves from the raw words of a `leaves.bin` (16 words per leaf), for a worker or a test that holds no stream. + pub fn from_words(root: [u8; 32], block: [u8; 32], number: u64, words: &[u32]) -> StateLeaves { + assert!(!words.is_empty() && words.len() % 16 == 0, "leaves are 16 words each"); + let leaves = words.chunks_exact(16).map(|c| c.try_into().unwrap()).collect::>(); + StateLeaves { root, block, number, records_total: leaves.len() as u64, sampled: false, leaves } + } + + #[inline(always)] + pub fn n(&self) -> u32 { + self.leaves.len() as u32 + } + + /// `leaf(t) = D[t mod n]`. + #[inline(always)] + pub fn leaf(&self, t: u32) -> &[u32; 16] { + &self.leaves[(t % self.n()) as usize] + } + + pub fn leaves(&self) -> &[[u32; 16]] { + &self.leaves + } + + /// The flat words of `leaves.bin`. + pub fn words(&self) -> Vec { + self.leaves.iter().flat_map(|l| l.iter().copied()).collect() + } + + /// The bytes of `leaves.bin` (little-endian words). + pub fn bytes(&self) -> Vec { + self.words().iter().flat_map(|w| w.to_le_bytes()).collect() + } + + /// FNV-1a 64 over the leaves as little-endian bytes (the pack's `IGNEUM_STATE_LEAVES_FNV64`). + pub fn fnv1a64(&self) -> u64 { + fnv1a64_words(&self.words()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::generator::{generate_class, V5_CLASS}; + use crate::memhard::{derive_item_leaves, Cache, MixParams, Shape}; + use crate::seed::day_key; + use crate::verify::{hash_warp, DatasetMode, DatasetSource}; + use std::sync::Arc; + + fn records(n: usize, salt: u8) -> Vec> { + (0..n).map(|i| vec![salt, i as u8, (i >> 8) as u8, 7]).collect() + } + + fn leaves(root: u8, n: usize, log2_words: u32) -> Arc { + Arc::new(StateLeaves::build([root; 32], [0x22; 32], 5, &records(n, root), log2_words)) + } + + /// The known-failed case, first: a hasher without the state (no leaves, the leaves of another root, the leaves + /// of a stream one record short, the previous window's leaves) is wrong on every item and every lane. + #[test] + fn a_stateless_hasher_is_wrong_on_every_item() { + let key = day_key("2026-10-03"); + let shape = Shape { mixer_mult: 8, cache_log2_words: 16, derive_len: 0, state: true }; + let cache = Arc::new(Cache::fill_log2(key, 16)); + let mp = MixParams::with_shape(key, shape); + let good = leaves(0x11, 93, 20); + let other_root = leaves(0x12, 93, 20); + let one_short = Arc::new(StateLeaves::build([0x13; 32], [0x22; 32], 5, &records(92, 0x11), 20)); // a record short means another root + let previous_window = leaves(0x10, 93, 20); + for (name, bad) in [("another root", other_root.clone()), ("one record short", one_short.clone()), ("the previous window", previous_window.clone())] { + let equal = (0..64u32).filter(|&t| derive_item_leaves(t * 7919, &mp, &cache, Some(&good)) == derive_item_leaves(t * 7919, &mp, &cache, Some(&bad))).count(); + assert_eq!(equal, 0, "{name}: {equal} of 64 items equal"); + } + let stateless = Shape { state: false, ..shape }; + let mp_stateless = MixParams::with_shape(key, stateless); + let equal = (0..64u32).filter(|&t| derive_item_leaves(t * 7919, &mp, &cache, Some(&good)) == derive_item_leaves(t * 7919, &mp_stateless, &cache, None)).count(); + assert_eq!(equal, 0, "no leaves at all: {equal} of 64 items equal"); + // the warp: a class v5 program over a small dataset, the same program and cache, other leaves + let program = generate_class("igneum-genesis", V5_CLASS); + let ds = DatasetSource::new_shape("2026-10-03", DatasetMode::MemoryHard, 20, shape).with_leaves(good.clone()); + let ds_other = DatasetSource::new_shape("2026-10-03", DatasetMode::MemoryHard, 20, shape).with_leaves(previous_window.clone()); + let a = hash_warp(&program, 0, &ds); + let b = hash_warp(&program, 0, &ds_other); + assert_eq!(a.iter().zip(b.iter()).filter(|(x, y)| x == y).count(), 0, "0 of 32 lanes agree"); + assert_eq!(hash_warp(&program, 0, &ds), a, "the same leaves hash the same"); + } + + /// Every item takes a leaf: `leaf(t) = D[t mod n]`, so items `t` and `t + n` share a leaf and still differ. + #[test] + fn every_item_is_keyed_and_the_leaf_wraps() { + let l = leaves(0x11, 93, 28); + assert_eq!(l.n(), 93); + assert!(!l.sampled); + assert_eq!(l.records_total, 93); + for t in [0u32, 1, 92, 93, 94, 1_000_000, u32::MAX] { + assert_eq!(l.leaf(t), l.leaf(t % 93)); + assert_eq!(*l.leaf(t), leaf_digest(&[0x11; 32], t % 93, &records(93, 0x11)[(t % 93) as usize])); + } + let key = day_key("2026-10-03"); + let shape = Shape { mixer_mult: 8, cache_log2_words: 16, derive_len: 0, state: true }; + let cache = Cache::fill_log2(key, 16); + let mp = MixParams::with_shape(key, shape); + assert_ne!(derive_item_leaves(5, &mp, &cache, Some(&l)), derive_item_leaves(5 + 93, &mp, &cache, Some(&l))); + // an empty stream yields one leaf (the digest of the empty record), never a division by zero + let empty = StateLeaves::build([0x11; 32], [0; 32], 0, &[], 28); + assert_eq!(empty.n(), 1); + assert_eq!(empty.records_total, 0); + assert_eq!(*empty.leaf(12_345), leaf_digest(&[0x11; 32], 0, &[])); + } + + /// Above the dataset size the records are sampled in the keyed order: a different root picks a different set, + /// and the set cannot be the first `items` records of the stream. + #[test] + fn the_sample_above_the_dataset_size_is_keyed_by_the_root() { + let recs = records(40, 0x33); + let a = StateLeaves::build([0x11; 32], [0; 32], 0, &recs, 8); + let b = StateLeaves::build([0x12; 32], [0; 32], 0, &recs, 8); + assert_eq!(StateLeaves::items_of(8), 16); + assert_eq!((a.n(), a.sampled, a.records_total), (16, true, 40)); + assert_ne!(a.leaves(), b.leaves(), "another root, another sample"); + // the positional first 16 are not the sample (with overwhelming probability for 40 choose 16) + let positional = StateLeaves::build([0x11; 32], [0; 32], 0, &recs[..16], 8); + assert_ne!(a.leaves(), positional.leaves()); + // the same inputs sample the same + assert_eq!(StateLeaves::build([0x11; 32], [0; 32], 0, &recs, 8), a); + // at the dataset size exactly, no sample + let c = StateLeaves::build([0x11; 32], [0; 32], 0, &recs[..16], 8); + assert!(!c.sampled && c.n() == 16); + } + + #[test] + fn stream_file_round_trip_and_refusals() { + let s = StateStream { number: 159_357, block: [0xaf; 32], root: [0x1c; 32], records: records(93, 1) }; + let bytes = s.encode(); + assert_eq!(&bytes[..6], STREAM_MAGIC); + assert_eq!(StateStream::decode(&bytes).unwrap(), s); + assert!(StateStream::decode(&bytes[..bytes.len() - 1]).is_err(), "truncated"); + let mut trailing = bytes.clone(); + trailing.push(0); + assert!(StateStream::decode(&trailing).is_err(), "trailing bytes"); + assert!(StateStream::decode(b"IGSD0\0").is_err(), "wrong magic"); + let l = StateLeaves::from_stream(&s, 28); + let back = StateLeaves::from_words(s.root, s.block, s.number, &l.words()); + assert_eq!(back.leaves(), l.leaves()); + assert_eq!(l.bytes().len(), 93 * 64); + assert_eq!(l.fnv1a64(), back.fnv1a64()); + } +} diff --git a/igneum-pow/src/verify.rs b/igneum-pow/src/verify.rs index 972557a96..c59204edc 100644 --- a/igneum-pow/src/verify.rs +++ b/igneum-pow/src/verify.rs @@ -227,6 +227,42 @@ impl DatasetSource { Self { log2_words, mask, key, key_bytes: Vec::new(), dataset, hot: None } } + /// This source with the window's state leaves (class v5, `docs/design/class-v5-stored-state.md`): memory-hard mode + /// under a shape with `state` only. + pub fn with_leaves(mut self, leaves: std::sync::Arc) -> Self { + match &mut self.dataset { + Dataset::MemoryHard(m) => { + assert!(m.params.shape.state, "state leaves on a dataset whose shape has no state"); + m.leaves = Some(leaves); + } + Dataset::ClosedForm { .. } => panic!("state leaves on a closed-form dataset"), + } + self + } + + /// A source of the same day with other leaves, the 256 MiB cache shared (the class v5 window refresh). + pub fn refreshed(&self, leaves: std::sync::Arc) -> Self { + let dataset = match &self.dataset { + Dataset::MemoryHard(m) => Dataset::MemoryHard(m.refreshed(leaves)), + Dataset::ClosedForm { .. } => panic!("state leaves on a closed-form dataset"), + }; + Self { log2_words: self.log2_words, mask: self.mask, key: self.key, key_bytes: self.key_bytes.clone(), dataset, hot: None } + } + + /// A copy of this source sharing its cache (and leaves), for a caller that needs an owned source from a shared one. + pub fn refreshed_or_clone(&self) -> Self { + let dataset = match &self.dataset { + Dataset::MemoryHard(m) => Dataset::MemoryHard(crate::memhard::MemhardCpu { params: m.params.clone(), cache: m.cache.clone(), leaves: m.leaves.clone() }), + Dataset::ClosedForm { d0, d1 } => Dataset::ClosedForm { d0: *d0, d1: *d1 }, + }; + Self { log2_words: self.log2_words, mask: self.mask, key: self.key, key_bytes: self.key_bytes.clone(), dataset, hot: None } + } + + /// The window's state leaves, when the source carries them. + pub fn leaves(&self) -> Option<&std::sync::Arc> { + self.memhard().and_then(|m| m.leaves.as_ref()) + } + /// This source with the hot table of the epoch whose program seed bytes are `seed_bytes` (`mb` MiB). pub fn with_hot(mut self, seed_bytes: &[u8], mb: u32) -> Self { self.hot = Some(HotTable::for_seed_bytes(seed_bytes, mb)); diff --git a/igneum-pow/tests/derive.rs b/igneum-pow/tests/derive.rs index 66b58df74..a64af0292 100644 --- a/igneum-pow/tests/derive.rs +++ b/igneum-pow/tests/derive.rs @@ -43,7 +43,7 @@ fn item_by_hand(t: u32, mp: &MixParams, cache: &Cache) -> [u32; 16] { fn derived_item_by_hand_and_in_batches() { let key = day_key(DAY); let cache = Cache::fill_log2(key, 16); - let shape = Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8 }; + let shape = Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8, state: false }; let mp = MixParams::with_shape(key, shape); let prog = mp.derive.as_ref().unwrap(); assert_eq!(prog.rounds.len(), DERIVE_PROGRAMS); @@ -64,7 +64,7 @@ fn derived_item_by_hand_and_in_batches() { derive_items(&ts[..5], &mp, &cache, &mut out5); assert_eq!(&out5[..], &out[..5]); // the fixed mixer of the same key gives other items - let v3 = MixParams::with_shape(key, Shape { mixer_mult: 8, cache_log2_words: 16, derive_len: 0 }); + let v3 = MixParams::with_shape(key, Shape { mixer_mult: 8, cache_log2_words: 16, derive_len: 0, state: false }); assert!(v3.derive.is_none()); assert_ne!(derive_item(0, &v3, &cache), derive_item(0, &mp, &cache)); } @@ -79,7 +79,7 @@ fn v2_and_v3_are_untouched() { let key = day_key(DAY); let cache = Cache::fill_log2(key, 16); // the version 2 item restated by hand (the mixer_mult_by_hand test of memhard.rs, m = 1) - let v2 = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: 0 }); + let v2 = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: 0, state: false }); let t = 12_345u32; let mut s = [0u32; 16]; s[..8].copy_from_slice(&key); @@ -96,7 +96,7 @@ fn v2_and_v3_are_untouched() { mixer(&mut s, round_key(8), &v2); assert_eq!(derive_item(t, &v2, &cache), s); // the mixer constants of the derivation class are the v2 draws (the stream continues after them) - let dr = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8 }); + let dr = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8, state: false }); assert_eq!((dr.rot, dr.mul, dr.rc), (v2.rot, v2.mul, v2.rc)); } @@ -109,12 +109,12 @@ fn stream_class_name_and_id() { rng.next(); } let expect = DeriveProgram::draw(&mut rng, DERIVE_LEN_X8); - let mp = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: DERIVE_LEN_X8 }); + let mp = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: DERIVE_LEN_X8, state: false }); assert_eq!(mp.derive.as_ref().unwrap(), &expect); // another day, another program; another length, another program - let other = MixParams::with_shape(day_key("2026-10-04"), Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: DERIVE_LEN_X8 }); + let other = MixParams::with_shape(day_key("2026-10-04"), Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: DERIVE_LEN_X8, state: false }); assert_ne!(other.derive.as_ref().unwrap().fingerprint(), expect.fingerprint()); - let short = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: 368 }); + let short = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 26, derive_len: 368, state: false }); assert_eq!(short.derive.as_ref().unwrap().instr_count(), 9 * 368); // the class: name, parse, id, and the v2 program stream (v2 loads, no width roll) let c = LoadClass::DR736; @@ -179,8 +179,8 @@ fn determinism_and_pack_text() { fn stats_beside_x8() { let key = day_key(DAY); let cache = Cache::fill_log2(key, 18); - let dr = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 18, derive_len: DERIVE_LEN_X8 }); - let x8 = MixParams::with_shape(key, Shape { mixer_mult: 8, cache_log2_words: 18, derive_len: 0 }); + let dr = MixParams::with_shape(key, Shape { mixer_mult: 1, cache_log2_words: 18, derive_len: DERIVE_LEN_X8, state: false }); + let x8 = MixParams::with_shape(key, Shape { mixer_mult: 8, cache_log2_words: 18, derive_len: 0, state: false }); for (label, mp) in [("dr736", &dr), ("x8", &x8)] { let n = 2048u32; let mut ones = [0u32; 512]; @@ -265,7 +265,7 @@ fn text_forms_match_scalar_reference() { /// The dataset source of the class on a day: the verifier's `word` path derives through the program. #[test] fn dataset_source_word_path() { - let ds = DatasetSource::new_shape(DAY, DatasetMode::MemoryHard, 20, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8 }); + let ds = DatasetSource::new_shape(DAY, DatasetMode::MemoryHard, 20, Shape { mixer_mult: 1, cache_log2_words: 16, derive_len: DERIVE_LEN_X8, state: false }); let m = ds.memhard().unwrap(); let item = derive_item(3, &m.params, &m.cache); for j in 0..16u32 { diff --git a/igneum-pow/tests/mixer.rs b/igneum-pow/tests/mixer.rs index 61e32aa05..f4644ae8d 100644 --- a/igneum-pow/tests/mixer.rs +++ b/igneum-pow/tests/mixer.rs @@ -275,7 +275,7 @@ fn edge_items_every_multiplier() { let key = day_key(DAY); let cache = Cache::fill_log2(key, 14); for m in [1u32, 2, 4, 8] { - let mp = MixParams::with_shape(key, Shape { mixer_mult: m, cache_log2_words: 14, derive_len: 0 }); + let mp = MixParams::with_shape(key, Shape { mixer_mult: m, cache_log2_words: 14, derive_len: 0, state: false }); let by_hand = |t: u32| -> [u32; 16] { let mut s = [0u32; 16]; s[..8].copy_from_slice(&key); diff --git a/igneum-pow/tests/packs.rs b/igneum-pow/tests/packs.rs index 98446833d..f66d91536 100644 --- a/igneum-pow/tests/packs.rs +++ b/igneum-pow/tests/packs.rs @@ -369,7 +369,7 @@ fn v3_packs_are_the_v2_seeds_under_mixer_x8() { assert_eq!(e3.program.program_id(), igneum_pow::generator::program_id(GENERATOR_VERSION_V3, &e3.program.seed, e3.program.attempt)); let m3 = e3.dataset.memhard().unwrap(); let m2 = e2.dataset.memhard().unwrap(); - assert_eq!(m3.shape(), Shape { mixer_mult: 8, cache_log2_words: 26, derive_len: 0 }); + assert_eq!(m3.shape(), Shape { mixer_mult: 8, cache_log2_words: 26, derive_len: 0, state: false }); assert_eq!(m3.cache.fnv1a64(), m2.cache.fnv1a64(), "{v3}: the same cache as v2 on day 0"); assert_eq!(m3.params.rot, m2.params.rot); assert_eq!(e3.dataset.log2_words, 28); @@ -405,7 +405,7 @@ fn v3_packs_are_the_v2_seeds_under_mixer_x8() { assert_eq!(j["load_class"].as_str().unwrap(), "mx4"); assert_eq!(e4.program.class, LoadClass::MX4); assert_eq!(e4.program.instrs, epoch(v2).program.instrs); - assert_eq!(e4.dataset.memhard().unwrap().shape(), Shape { mixer_mult: 4, cache_log2_words: 26, derive_len: 0 }); + assert_eq!(e4.dataset.memhard().unwrap().shape(), Shape { mixer_mult: 4, cache_log2_words: 26, derive_len: 0, state: false }); assert!(read(x4, "memhard.h").contains("j < 4u; ++j) mh_mixer(s, 0x9E3779B9u * (r * 4u + j + 1u))")); } } @@ -899,3 +899,101 @@ fn hot_packs_emitted_sources_and_load_forms() { assert!(ph.contains("igneum_launch_hot_fill(")); } } + +// --------------------------------------------------------------------------------------------------------------- +// Class v5 (docs/design/class-v5-stored-state.md, 7 October 2026): the pinned pack under proto-cuda/packs-ca3-v5/ +// --------------------------------------------------------------------------------------------------------------- + +fn v5_packs_dir() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../proto-cuda/packs-ca3-v5") +} + +fn v5_read(pack: &str, file: &str) -> String { + std::fs::read_to_string(v5_packs_dir().join(pack).join(file)).unwrap_or_else(|e| panic!("{pack}/{file}: {e}")) +} + +fn v5_json(pack: &str, file: &str) -> Value { + serde_json::from_str(&v5_read(pack, file)).unwrap() +} + +/// The epoch of a pinned class v4 or v5 pack of the string seed and day: the program through the seam, the dataset at +/// the day-0 size, and for a v5 pack the leaves of its `state.igsd1` (the devnet's state stream of 7 October 2026, +/// node 1's exec snapshot at chain block 159,357: 93 records, root 0x1c583d35...). +fn v5_epoch(pack: &str) -> Epoch { + let j = v5_json(pack, "program.json"); + let seed = j["seed"].as_str().unwrap(); + let class = ProgramClass::parse(j["program_class"].as_str().unwrap()).unwrap(); + let program = generate_from_seed_bytes_program_class(seed, seed.as_bytes(), class, None); + let day = j["dataset"]["day"].as_str().unwrap(); + let log2 = j["dataset"]["log2_words"].as_u64().unwrap() as u32; + let shape = Shape::for_class(&program.class); + let mut dataset = DatasetSource::new_shape(day, DatasetMode::MemoryHard, log2, shape); + if class == ProgramClass::V5 { + let stream = igneum_pow::StateStream::read_file(&v5_packs_dir().join(pack).join("state.igsd1")).unwrap(); + dataset = dataset.with_leaves(std::sync::Arc::new(igneum_pow::StateLeaves::from_stream(&stream, log2))); + } + Epoch { program, dataset } +} + +/// The class v5 pack is the class v4 program of the same seed over the state leaves: generator 5 and +/// `program_id(5, seed, attempt)`, the base program, the shadow block and the dataset's cache equal to the v4 pack's, +/// every vector and dataset word different, every emitted file byte for byte what the crate exports (leaves.bin +/// included, its FNV in program.h), and the hash kernel text of kernel.cu equal to the v4 pack's but for the build +/// kernel and the class lines. The known-failed case first: the v4 control pack's vectors under the v5 epoch agree on +/// no lane. +#[test] +fn v5_pack_is_the_v4_program_over_the_state_leaves() { + let e5 = v5_epoch("v5-genesis"); + let e4 = v5_epoch("v4-genesis"); + let v4 = v5_json("v4-genesis", "vectors.json"); + // the known-failed case: the v4 pack's hashes are not the v5 epoch's on any lane + let out4: Vec = v4["warps"][0]["expected"].as_array().unwrap().iter().map(hex64).collect(); + let got5 = e5.hash_warp(0); + assert_eq!(out4.iter().zip(got5.iter()).filter(|(a, b)| a == b).count(), 0, "0 of 32 lanes of the v4 pack agree with the v5 epoch"); + assert_eq!(e4.hash_warp(0).to_vec(), out4, "the v4 control pack is the v4 epoch"); + // the program: v4's draw, generator 5, the state in the class and the id + assert_eq!(e5.program.generator, igneum_pow::GENERATOR_VERSION_V5); + assert_eq!(e5.program.class, igneum_pow::V5_CLASS); + assert_eq!(e5.program.class.name(), "mx8+sh256x27+state"); + assert_eq!(e5.program.instrs, e4.program.instrs); + assert_eq!(e5.program.shadow, e4.program.shadow); + assert_eq!((e5.program.seed, e5.program.attempt), (e4.program.seed, e4.program.attempt)); + assert_eq!(e5.program.program_id(), igneum_pow::generator::program_id(igneum_pow::GENERATOR_VERSION_V5, &e5.program.seed, e5.program.attempt)); + assert_ne!(e5.program.program_id(), e4.program.program_id()); + // the dataset: the same cache, other items + let m5 = e5.dataset.memhard().unwrap(); + let m4 = e4.dataset.memhard().unwrap(); + assert_eq!(m5.cache.fnv1a64(), m4.cache.fnv1a64(), "one day cache"); + assert!(m5.shape().state && !m4.shape().state); + let leaves = e5.dataset.leaves().unwrap(); + assert_eq!((leaves.n(), leaves.records_total, leaves.sampled), (93, 93, false)); + assert_ne!(e5.dataset_word(0), e4.dataset_word(0)); + // every file as the crate exports it, leaves.bin included + for pack in ["v4-genesis", "v5-genesis"] { + let e = if pack == "v5-genesis" { &e5 } else { &e4 }; + let v = v5_json(pack, "vectors.json"); + let out = export_pack(e, v["day"].as_str().unwrap(), v["source"].as_str().unwrap()); + for (name, text) in &out.files { + assert_eq!(v5_read(pack, name), *text, "{pack}/{name} differs from the export"); + } + for (name, bytes) in &out.binaries { + assert_eq!(std::fs::read(v5_packs_dir().join(pack).join(name)).unwrap(), *bytes, "{pack}/{name}"); + } + assert_eq!(out.binaries.len(), (pack == "v5-genesis") as usize); + } + let h5 = v5_read("v5-genesis", "program.h"); + assert!(h5.contains("#define IGNEUM_PROGRAM_CLASS \"v5\"") && h5.contains("#define IGNEUM_STATE_LEAVES 93") && h5.contains(&format!("#define IGNEUM_STATE_LEAVES_FNV64 {}", igneum_pow::emit::hex64(leaves.fnv1a64())))); + assert!(h5.contains("igneum_launch_build(uint32_t* ds, const uint32_t* cache, const uint32_t* leaves, uint32_t nLeaves, uint32_t nItems)")); + // the hash kernel text is class v4's byte for byte; the build kernel and the class lines are what differ + let hash_text = |s: &str| { + let a = s.find("__global__ void igneum_hash(").unwrap(); + let b = s.find("// Host-side launch wrappers").unwrap(); + s[a..b].to_string() + }; + let k5 = v5_read("v5-genesis", "kernel.cu"); + let k4 = v5_read("v4-genesis", "kernel.cu"); + assert_eq!(hash_text(&k5), hash_text(&k4), "the hash kernel is class v4's"); + assert!(k5.contains("mh_item(cache, mh_leaf(leaves, nLeaves, t), t, s)") && !k4.contains("mh_leaf")); + let mh5 = v5_read("v5-genesis", "memhard.h"); + assert!(mh5.contains("s[i] ^= leaf[i]"), "the leaf XOR before the first mixer"); +} diff --git a/infra/fast-time/override-60x.json b/infra/fast-time/override-60x.json index 2a36de873..a955d932b 100644 --- a/infra/fast-time/override-60x.json +++ b/infra/fast-time/override-60x.json @@ -91,6 +91,7 @@ "proving_consensus_verify_daa": 18446744073709551615, "proving_shard_program_id": "", "proving_aggregator_id": "", + "verifier_in_consensus": false, "sig_scheme": 0, "sig_scheme_activation_daa": 18446744073709551615, "finality_succession_activation_daa": 18446744073709551615, diff --git a/infra/fast-time/proving-enforcement.mjs b/infra/fast-time/proving-enforcement.mjs new file mode 100644 index 000000000..bbd5c4b7b --- /dev/null +++ b/infra/fast-time/proving-enforcement.mjs @@ -0,0 +1,274 @@ +#!/usr/bin/env node +// Enforced proving (docs/spec/proving-enforcement.md section 8; ledger P21): the fast-time case that runs the seven +// refusals across the activation boundary. Three nodes on one fast-time network: H1 and H2 are ordinary unmodified +// validators (the in-process SP1 verifier, the body rule and the payment rule from the floor); A is the modified producer: +// its body rule is off (IGNEUM_TEST_SKIP_PROOF_RULE=1) and its pool trusts every record (IGNEUM_PROOF_VERIFY=trust), so a +// record it signs for the CORRECT native statement rides in its own blocks whatever bytes stand behind it. Every node +// mines with one CPU thread. The floor (`proving_consensus_verify_daa`, --floor DAA, the boundary) sits a few fast-time +// minutes ahead; the honest nodes pin the program ids of proving/igneum-prove/elf/manifest.json. +// +// Below the boundary A's forged records pay on H1 (the v0 rule: the finding of ledger P21, observed). From the boundary +// every carrying block of A is refused by H1 and H2 (IgneumInvalidProofRecord in their logs, or dropped unmarked after +// the 20-s proof fetch) and no record of A's pays. The seven shapes, each submitted for shard 0 of a fresh chain block of +// A's own chain, the native statement read from A's own node (igneum_getShardPlan with the payout address): +// (a) no proof: empty proof bytes (their hash is the record's proof hash) +// (b) a wrong proof: random bytes +// (c) a real proof for another statement or program: --real-proof (skipped when absent) +// (d) a replayed record: (b)'s record submitted again (A's own pool answers "accepted: false"; carried again by A it is +// "shard already paid" or refused with the block) +// (e) a wrong network id: signed for igneum-devnet-; A's own unmodified pool refuses it at submit ("bad signature"), +// the same check every honest node runs on a carried record +// (f) an altered payout address: signed for another payout with the statement of the first; A's pool refuses it (the +// native-execution veto), the same check every honest node runs +// (g) a duplicate of a paid record: a second key's own valid record for a shard already paid (below the boundary, where +// something pays): "shard already paid" on H1 +// The honest-pays-once case needs a real proof of this chain (a CPU prover, minutes); the unit tests hold it and the +// testnet holds it live. --expect refuse (the rule's case, PASS = below: paid; from the floor: nothing paid and a refusal +// logged) or --expect pay (the known-failed shape with --floor never: the forged record pays on both sides and must PASS +// as the finding; the harness's own failed shape is --floor never --expect refuse, which must FAIL). +// +// node infra/fast-time/proving-enforcement.mjs [--floor 240] [--before 90] [--after 150] [--slot 0] [--real-proof ] +// [--expect refuse|pay] [--out ] +// IGNEUMD and IGNEUM_MINER name the binaries (a Linux build on the box: tools/fast-time-remote.sh --node-bin ...). +// +// Leftovers of an earlier run of the same slot are stopped by PID FILE, never by name (CLAUDE.md): every process this +// harness starts is written to /pids and a pid is killed only when /proc//cmdline carries this slot's data +// directory or one of its ports. + +import { spawn, spawnSync } from 'node:child_process'; +import { mkdirSync, rmSync, writeFileSync, readFileSync, openSync, existsSync, appendFileSync } from 'node:fs'; +import { createHash, randomBytes } from 'node:crypto'; + +const ROOT = new URL('../../', import.meta.url).pathname; +const FILE = `${ROOT}infra/fast-time/override-60x.json`; +const MANIFEST = `${ROOT}proving/igneum-prove/elf/manifest.json`; +const IGNEUMD = process.env.IGNEUMD || `${ROOT}vendor/igneum-node/target-integration/release/igneumd`; +const CPU_MINER = process.env.IGNEUM_MINER || `${ROOT}vendor/igneum-node/target-integration/release/igneum-miner`; +const args = process.argv.slice(2); +const flag = (name, dflt) => { const i = args.indexOf(`--${name}`); return i >= 0 ? Number(args[i + 1]) : dflt; }; +const sflag = (name, dflt = null) => { const i = args.indexOf(`--${name}`); return i >= 0 ? args[i + 1] : dflt; }; +const NEVER = '18446744073709551615'; +const FLOOR = sflag('floor', '240'); +const BEFORE = flag('before', 90), AFTER = flag('after', 150); +const SLOT = flag('slot', 0); +const REAL_PROOF = sflag('real-proof'); +const EXPECT = sflag('expect', FLOOR === 'never' ? 'pay' : 'refuse'); +const GENESIS_BITS = flag('genesis-bits', 0x1f010000); +const CASE = sflag('case') || `floor-${FLOOR}-expect-${EXPECT}`; +const OUT = sflag('out') || `${ROOT}docs/plans/proving-enforcement/${CASE}.json`; +// 30890 and up: clear of every other fast-time harness (fork-gate 30690s, nuisance 30490s, headers-proof 30590s) +const BASE = 30890 + SLOT * 40, SUFFIX = 985 + SLOT; +const CHAIN = `igneum-devnet-${SUFFIX}`; +const TMP = `/tmp/igneum-fast-time-pe${SLOT}`; +if (!['refuse', 'pay'].includes(EXPECT)) { console.error('usage: --expect refuse|pay'); process.exit(2); } +const started = []; +const log = (...a) => console.log(new Date().toISOString().slice(11, 23), `pe${SLOT}`, ...a); +const sleep = (ms) => new Promise(r => setTimeout(r, ms)); +for (const b of [IGNEUMD, CPU_MINER]) if (!existsSync(b)) { console.error(`missing ${b}`); process.exit(2); } + +const PIDS = `${TMP}/pids`; +function stopLeftovers() { + if (!existsSync(PIDS)) return; + const ports = Array.from({ length: 40 }, (_, k) => `127.0.0.1:${BASE + k}`); + for (const line of readFileSync(PIDS, 'utf8').split('\n').filter(Boolean)) { + const pid = Number(line); + let cmd = ''; + try { cmd = readFileSync(`/proc/${pid}/cmdline`, 'utf8'); } catch { continue; } + if (!cmd.includes(TMP) && !ports.some(p => cmd.includes(p))) continue; + try { process.kill(pid, 'SIGKILL'); log(`stopped leftover pid ${pid} of an earlier run`); } catch { } + } +} +stopLeftovers(); +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'); +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; + for (const k of Object.keys(fields)) out = out.replace(new RegExp(`\\s*"${k}":\\s*[^,}\\n]+,?`), ''); + 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`); +} +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_shard_program_id: manifest.shard.program_id, proving_aggregator_id: manifest.aggregator.program_id, + verifier_in_consensus: 'false', + program_class_v3_activation_daa: NEVER, program_class_v4_activation_daa: NEVER, +})); +log(`case ${CASE}: floor ${FLOOR} DAA, before ${BEFORE} s, after ${AFTER} s, expect ${EXPECT}, real proof ${REAL_PROOF || 'none'}`); + +class Node { + constructor(name, i, peers = [], env = {}) { + this.name = name; this.i = i; this.grpcPort = BASE + i * 10; this.p2pPort = BASE + i * 10 + 1; this.jsonPort = BASE + i * 10 + 2; this.evmPort = BASE + i * 10 + 3; + this.peers = peers; this.env = env; this.dir = `${TMP}/${name}`; this.logFile = `${this.dir}/node.log`; + } + get grpc() { return `grpc://127.0.0.1:${this.grpcPort}`; } + async start() { + mkdirSync(this.dir, { recursive: true }); + const out = openSync(this.logFile, 'a'); + const a = ['--devnet', `--devnet-suffix=${SUFFIX}`, '--nodnsseed', '--disable-upnp', '--nologfiles', '--enable-unsynced-mining', '--utxoindex', + `--appdir=${this.dir}`, `--rpclisten=127.0.0.1:${this.grpcPort}`, `--rpclisten-json=127.0.0.1:${this.jsonPort}`, `--evm-rpclisten=127.0.0.1:${this.evmPort}`, + `--listen=127.0.0.1:${this.p2pPort}`, `--override-params-file=${override}`, '--loglevel=info', '--yes']; + if (this.peers.length) for (const p of this.peers) a.push(`--addpeer=127.0.0.1:${p}`); else a.push('--outpeers=0'); + this.proc = spawn(IGNEUMD, a, { stdio: ['ignore', out, out], env: { ...process.env, ...this.env } }); + track(this.proc); + for (let k = 0; k < 60; k++) { + await sleep(1000); + try { await this.exec('igneum_getExecStatus', []); log(`${this.name} up (pid ${this.proc.pid}) after ${k + 1} s`); return; } catch { } + if (this.proc.exitCode !== null) throw new Error(`${this.name} exited ${this.proc.exitCode}: ${readFileSync(this.logFile, 'utf8').split('\n').slice(-5).join(' | ')}`); + } + throw new Error(`${this.name} did not answer in 60 s`); + } + async exec(method, params) { + const r = await fetch(`http://127.0.0.1:${this.evmPort}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) }); + const j = await r.json(); + if (j.error) throw new Error(`${method}: ${j.error.message || JSON.stringify(j.error)}`); + return j.result; + } + logText() { try { return readFileSync(this.logFile, 'utf8'); } catch { return ''; } } + stop() { try { this.proc.kill('SIGINT'); } catch { } } +} + +function startMiner(node, label, secs) { + const out = openSync(`${TMP}/${label}.log`, 'a'); + const p = spawn(CPU_MINER, ['mine', node.grpc, '1', String(secs), label, '--engine', 'igneum-pow', '--payout-label', label, '--status-secs', '30', '--no-vote'], { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_POW_DAY_MS: String(DAY_MS) } }); + track(p); + return p; +} + +const sha256 = (b) => createHash('sha256').update(b).digest('hex'); +const hex = (b) => '0x' + Buffer.from(b).toString('hex'); +function signRecord(label, chain, block, number, shard, payout, statement, proofHash) { + const r = spawnSync(CPU_MINER, ['sign-record', label, chain, block, String(number), String(shard), payout, statement, proofHash], { encoding: 'utf8' }); + if (r.status !== 0) throw new Error(`sign-record failed: ${r.stderr || r.stdout}`); + return JSON.parse(r.stdout.trim().split('\n').pop()); +} + +const H1 = new Node('H1', 0); +const H2 = new Node('H2', 1, [H1.p2pPort]); +const A = new Node('A', 2, [H1.p2pPort, H2.p2pPort], { IGNEUM_TEST_SKIP_PROOF_RULE: '1', IGNEUM_PROOF_VERIFY: 'trust' }); +const nodes = [H1, H2, A]; +const result = { case: CASE, floor: FLOOR, expect: EXPECT, phases: {}, node: IGNEUMD, slot: SLOT, ports: { base: BASE, suffix: SUFFIX }, startedAt: new Date().toISOString() }; +let miners = []; +async function stopAll() { + for (const m of miners) { try { m.kill('SIGINT'); } catch { } } + for (const n of nodes) n.stop(); + await sleep(2000); + for (const p of started) { try { if (p.exitCode === null) p.kill('SIGKILL'); } catch { } } +} +process.on('SIGINT', async () => { await stopAll(); process.exit(130); }); + +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); } + +/// 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) { + 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]); + const statementB = planB.shards[0].statement; + const shapes = []; + const submit = async (name, record, proof) => { + let out; + try { out = await A.exec('igneum_submitProofRecord', [{ record, proof }]); } catch (e) { out = { accepted: false, reason: String(e.message) }; } + shapes.push({ shape: name, accepted: out.accepted, new: out.new, reason: out.reason }); + log(`${phase} ${name}: A's pool ${out.accepted ? 'accepted' : 'refused'} (${out.reason || ''})`); + return out; + }; + 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'); + // (b) a wrong proof + const recB = signRecord('forger-b', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(wrong)).record; + await submit('b-wrong-proof', recB, hex(wrong)); + // (c) a real proof of another statement or program + if (REAL_PROOF && existsSync(REAL_PROOF)) { + const real = readFileSync(REAL_PROOF); + await submit('c-other-program', signRecord('forger-c', CHAIN, block, n, 0, PAYOUT_A, statement, '0x' + sha256(real)).record, hex(real)); + } else shapes.push({ shape: 'c-other-program', skipped: 'no --real-proof file' }); + // (d) a replayed record + await submit('d-replay', recB, hex(wrong)); + // (e) a wrong network id + await submit('e-wrong-network', signRecord('forger-e', `igneum-devnet-${SUFFIX + 1}`, block, n, 0, PAYOUT_A, statement, '0x' + sha256(wrong)).record, hex(wrong)); + // (f) an altered payout address: the statement of PAYOUT_A signed for PAYOUT_B + await submit('f-altered-payout', signRecord('forger-f', CHAIN, block, n, 0, PAYOUT_B, statement, '0x' + sha256(wrong)).record, hex(wrong)); + // (g) a duplicate by another key, its own valid statement for its own payout + const dup = randomBytes(512); + await submit('g-duplicate', signRecord('forger-g', CHAIN, block, n, 0, PAYOUT_B, statementB, '0x' + sha256(dup)).record, hex(dup)); + return { block: n, hash: block, shapes }; +} + +/// What H1 holds for A's block `n`: the carried records and the paid map. +async function observe(n) { + try { + const r = await H1.exec('igneum_getProofRecords', ['0x' + n.toString(16)]); + const carried = (r.carried || []).map(c => ({ key: c.keyHash, carrier: c.carrierNumber, rejected: c.rejected, paidWei: c.paidWei })); + // `paid` holds one entry per shard, null when unpaid: keep the paid ones only + return { paid: (r.paid || []).filter(Boolean), carried }; + } catch (e) { return { error: e.message }; } +} +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 }; +}; + +try { + for (const n of nodes) await n.start(); + miners = [startMiner(H1, 'h1', BEFORE + AFTER + 600), startMiner(H2, 'h2', BEFORE + AFTER + 600), startMiner(A, 'attacker', BEFORE + AFTER + 600)]; + // phase 1: below the boundary + const floor = FLOOR === 'never' ? Infinity : Number(FLOOR); + log(`phase 1: mining ${BEFORE} s below the floor`); + await sleep(BEFORE * 1000); + let d = await daa(A), tip = await tipNumber(A); + 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 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)}`); + // phase 2: wait for the boundary, then forge again + 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); + 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 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 }; + log(`at floor: H1 paid ${JSON.stringify(o2.paid)}; carried ${JSON.stringify(o2.carried)}; refusals ${JSON.stringify(afterRefusals)}`); + // the verdict + const paidBelow = (o1.paid || []).length > 0; + const paidAt = (o2.paid || []).length > 0; + const newRefusals = (afterRefusals.H1.invalid + afterRefusals.H1.dropped) > (beforeRefusals.H1.invalid + beforeRefusals.H1.dropped) + || (afterRefusals.H2.invalid + afterRefusals.H2.dropped) > (beforeRefusals.H2.invalid + beforeRefusals.H2.dropped); + let pass; + if (EXPECT === 'refuse') pass = paidBelow && !paidAt && newRefusals; + else pass = paidBelow && paidAt; + result.verdict = { paidBelow, paidAt, newRefusals, pass }; + result.endedAt = new Date().toISOString(); + mkdirSync(OUT.replace(/\/[^/]+$/, ''), { recursive: true }); + writeFileSync(OUT, JSON.stringify(result, null, 2)); + log(`RESULT ${pass ? 'PASS' : 'FAIL'}: below the floor paid=${paidBelow}; at the floor paid=${paidAt}, new refusals=${newRefusals}; ${OUT}`); + await stopAll(); + process.exit(pass ? 0 : 1); +} catch (e) { + log(`ERROR ${e.message}`); + result.error = e.message; + try { mkdirSync(OUT.replace(/\/[^/]+$/, ''), { recursive: true }); writeFileSync(OUT, JSON.stringify(result, null, 2)); } catch { } + await stopAll(); + process.exit(2); +} diff --git a/infra/fast-time/testnet-object.mjs b/infra/fast-time/testnet-object.mjs new file mode 100644 index 000000000..9aea178d1 --- /dev/null +++ b/infra/fast-time/testnet-object.mjs @@ -0,0 +1,469 @@ +#!/usr/bin/env node +// igneum-testnet-1's object at fast time (the testnet genesis lane, 7 October 2026): a 3-node devnet-suffix network on +// override-60x.json with every switch of infra/seed-nodes/testnet-object.json on from genesis, as the testnet carries +// them (difficulty v3, the DAA-second finality rule, finality v3, the signed leave item, the signing bonus at 1,000 bps, +// class v4 unconditional, the latency ladder active at rung 0, consensus proof verification under the pinned ids, fees +// v1, EmissionSchedule::TESTNET_1), real CPU mining on every node (igneum-pow engine, CPU genesis bits), four voting keys +// and one key that never votes (--no-vote). What the testnet itself cannot show inside a run (its weight window is 30 +// days) this run shows in minutes: the first lock, a silent producer paid the bonus split, and a signed leave. +// +// What stays the devnet's, by design: the base unit (8 decimals: the devnet genesis payload is 8 bytes and the daemon +// refuses a unit its genesis does not parse at; the 18-decimal form is tools/fleet/base-unit-gate.sh on the testnet +// params), the finality object (the 60x file's: window 120, min_daa 120, presence 1, leave delay 60 = 3,600 / 60), the +// ladder window (60 DAA, one epoch, in place of 86,400) and the PoW schedule (epoch 60, lead 10, day 24 minutes). +// The testnet schedule is written at the devnet's unit (100 IGN a block = 10^10 sompi). +// +// Ports 29730 and up, network igneum-devnet-973, data under IGNEUM_TN_TMP (default /tmp/igneum-fast-time-testnet). The +// live devnet, Devnet 2 and the public testnet seeds are never touched (--nodnsseed, loopback only). Everything started +// is stopped at the end, by pid, never by name. +// +// Checks (each a line in the summary; PASS is every one true): +// every node prints the start-up lines of the object (digest, class v4, ladder active, proof verification from 0, fees v1, +// the signing bonus from 0, the leave item from 0) +// every epoch's template is class v4 at rung 0 (27 shadow passes); no ladder bits on the chain (no node signals); the +// object byte of every mined block is 0; the sinks and block counts agree across the nodes +// the first finality lock arrives (finality_active, latest_locked_index > 0) on every node +// the bonus pays: after the first lock, a chain block whose mergeset holds a block of the silent key pays that key's +// address 72 percent of the merged block's subsidy on the UTXO side and the pool 28 percent (the voting keys 80/20) +// the bridge is the identity under the bonus: for every chain block after the first lock, the sum of the UTXO coinbase +// outputs to each miner's address, times 10^10, equals the sum of the execution layer's segment rewards to that +// miner's EVM address (igneum_getSegment). Before the exec-side fix of 7 October 2026 this is the known-failed case: +// the executor credits 80 percent to a silent key while the coinbase pays 72 (the testnet lane's finding, 08:0x UK) +// a leave: at --leave-at seconds a voting key submits its signed leave (igneum-miner leave); the node accepts it, and +// within leave_delay + one checkpoint the checkpoints' voter count drops by one +// +// node infra/fast-time/testnet-object.mjs [--secs 600] [--leave-at 360] [--expect pass|bonus-fails] +// IGNEUMD, IGNEUM_MINER, IGNEUM_POW name the binaries (defaults: the testnet genesis worktree's fork under +// vendor/igneum-node-testnet-genesis/target/release and igneum-pow/target/release/igneum-pow, the layout on +// igneum-build-1 under /srv/builds/igneum-wt-testnet-genesis). + +import { spawn, spawnSync } from 'node:child_process'; +import { mkdirSync, rmSync, writeFileSync, readFileSync, openSync, existsSync } from 'node:fs'; +import { connectRpc } from '../../tools/finality-attacks/lib/rpc.mjs'; +import { devAddress } from '../../tools/harness/lib/address.mjs'; + +const ROOT = new URL('../../', import.meta.url).pathname; +const FILE = `${ROOT}infra/fast-time/override-60x.json`; +const OBJECT = `${ROOT}infra/seed-nodes/testnet-object.json`; +const BIN = process.env.IGNEUM_TN_BIN || `${ROOT}vendor/igneum-node-testnet-genesis/target/release`; +const IGNEUMD = process.env.IGNEUMD || `${BIN}/igneumd`; +const CPU_MINER = process.env.IGNEUM_MINER || `${BIN}/igneum-miner`; +const IGNEUM_POW = process.env.IGNEUM_POW || `${ROOT}igneum-pow/target/release/igneum-pow`; +const TMP = process.env.IGNEUM_TN_TMP || '/tmp/igneum-fast-time-testnet'; +const BASE = +(process.env.IGNEUM_TN_BASE_PORT || 29730), SUFFIX = +(process.env.IGNEUM_TN_SUFFIX || 973); +const RUNG0 = 27, SOMPI = 10n ** 8n, WEI_PER_SOMPI = 10n ** 10n; +const args = process.argv.slice(2); +const flag = (name, dflt) => { const i = args.indexOf(`--${name}`); return i >= 0 ? +args[i + 1] : dflt; }; +const sflag = (name) => { const i = args.indexOf(`--${name}`); return i >= 0 ? args[i + 1] : null; }; +const GENESIS_BITS = flag('genesis-bits', 0x1f010000); +const SECS = flag('secs', 600); +const LEAVE_AT = flag('leave-at', 360); +const EXPECT = sflag('expect') || 'pass'; +if (!['pass', 'bonus-fails'].includes(EXPECT)) { console.error('usage: [--secs 600] [--leave-at 360] [--expect pass|bonus-fails]'); process.exit(2); } +const started = []; +const log = (...a) => console.log(new Date().toISOString().slice(11, 23), ...a); +const sleep = (ms) => new Promise(r => setTimeout(r, ms)); +for (const b of [IGNEUMD, CPU_MINER]) if (!existsSync(b)) { console.error(`missing ${b}`); process.exit(2); } +if (!existsSync(OBJECT)) { console.error(`missing ${OBJECT} (print_testnet_object writes it)`); process.exit(2); } + +rmSync(TMP, { recursive: true, force: true }); mkdirSync(TMP, { recursive: true }); +// u64::MAX is not a JavaScript number: the files are merged as text, never through JSON.parse of the whole object +const baseText = readFileSync(FILE, 'utf8'); +const objectText = readFileSync(OBJECT, 'utf8'); +const num = (text, name) => { const m = new RegExp(`"${name}":\\s*([0-9]+)`).exec(text); return m ? m[1] : undefined; }; +const str = (text, name) => { const m = new RegExp(`"${name}":\\s*"([^"]*)"`).exec(text); return m ? m[1] : undefined; }; +const EPOCH = +num(baseText, 'pow_epoch_blocks'), LEAD = +num(baseText, 'pow_epoch_lead'), DAY_MS = +num(baseText, 'pow_day_ms'); +const LEAVE_DELAY = 60, LADDER_WINDOW = 60; +// the switches as the object carries them, the clocks at fast time, the unit the devnet's +const switches = { + genesis_bits: String(GENESIS_BITS), skip_proof_of_work: 'false', + difficulty_v2_activation_daa: num(objectText, 'difficulty_v2_activation_daa'), + difficulty_v3_activation_daa: num(objectText, 'difficulty_v3_activation_daa'), + proving_v0_activation_daa: num(objectText, 'proving_v0_activation_daa'), + finality_v3_activation_daa: num(objectText, 'finality_v3_activation_daa'), + finality_daa_rule_activation_daa: num(objectText, 'finality_daa_rule_activation_daa'), + finality_leave_activation_daa: num(objectText, 'finality_leave_activation_daa'), + signing_bonus_activation_daa: num(objectText, 'signing_bonus_activation_daa'), + signing_bonus_bps: num(objectText, 'signing_bonus_bps'), + program_class_v3_activation_daa: num(objectText, 'program_class_v3_activation_daa'), + program_class_v4_activation_daa: num(objectText, 'program_class_v4_activation_daa'), + program_class_v4_signal_window_daa: num(objectText, 'program_class_v4_signal_window_daa'), + program_class_v5_activation_daa: num(objectText, 'program_class_v5_activation_daa'), + latency_ladder_activation_daa: num(objectText, 'latency_ladder_activation_daa'), + latency_ladder_window_daa: String(LADDER_WINDOW), + fees_v1_activation_daa: num(objectText, 'fees_v1_activation_daa'), + proving_consensus_verify_daa: num(objectText, 'proving_consensus_verify_daa'), + subsidy_per_block_activation_daa: num(objectText, 'subsidy_per_block_activation_daa'), + proving_shard_program_id: JSON.stringify(str(objectText, 'proving_shard_program_id')), + proving_aggregator_id: JSON.stringify(str(objectText, 'proving_aggregator_id')), +}; +for (const [k, v] of Object.entries(switches)) if (v === undefined) { console.error(`the object has no ${k}`); process.exit(2); } +// the class every epoch's template must carry: 5 when the object holds class v5 from genesis (the go object 0d05e795 of +// 8 October 2026, byte 6), else 4 (the 5b673577 object, byte 7); before this the line copied only the v4 keys and ran +// class v4 under a class v5 object (row 9u of docs/plans/testnet-go.md) +const OBJECT_CLASS = String(switches.program_class_v5_activation_daa) === '0' ? 5 : 4; +const ladderList = /"latency_ladder":\s*(\[[\s\S]*?\])/.exec(objectText)[1].replace(/\s+/g, ''); +const feesObject = /"fees":\s*(\{[\s\S]*?\n \})/.exec(objectText)[1].replace(/\s+/g, ''); +const emissionObject = /"emission":\s*(\{[\s\S]*?\n \})/.exec(objectText)[1].replace(/\s+/g, '').replace(/"launch_rate":"(\d+)"/, (_, r) => `"launch_rate":"${BigInt(r) / WEI_PER_SOMPI}"`); +// the value of a top-level key in the file's text, nested objects and lists included (brace matching, never +// JSON.parse: u64::MAX is not a JavaScript number) +function spanOf(text, key) { + const m = new RegExp(`"${key}":\\s*`).exec(text); + if (!m) return null; + const start = m.index; let i = m.index + m[0].length; + const c = text[i]; + if (c === '{' || c === '[') { + const open = c, close = c === '{' ? '}' : ']'; let depth = 0; + for (; i < text.length; i++) { if (text[i] === open) depth++; else if (text[i] === close) { depth--; if (depth === 0) { i++; break; } } } + } else if (c === '"') { i = text.indexOf('"', i + 1) + 1; } else { while (i < text.length && !/[,}\n]/.test(text[i])) i++; } + // the trailing comma and the line break before the key + if (text[i] === ',') i++; + let s = start; while (s > 0 && /\s/.test(text[s - 1])) s--; + return [s, i]; +} +function mergeOverrideText(text, fields) { + let out = text; + for (const k of Object.keys(fields)) { const span = spanOf(out, k); if (span) out = out.slice(0, span[0]) + out.slice(span[1]); } + const extra = Object.entries(fields).map(([k, v]) => `"${k}": ${v}`).join(',\n '); + return out.replace(/,?\s*}\s*$/, `,\n ${extra}\n}\n`); +} +// the finality object: the 60x file's, with the leave delay at fast time +const finSpan = spanOf(baseText, 'finality'); +const fastFinality = baseText.slice(finSpan[0], finSpan[1]).replace(/^[\s,]*"finality":\s*/, '').replace(/,\s*$/, '').replace(/\s+/g, ''); +const finalityObject = fastFinality.includes('leave_delay') ? fastFinality.replace(/"leave_delay":\d+/, `"leave_delay":${LEAVE_DELAY}`) : fastFinality.replace(/\}$/, `,"leave_delay":${LEAVE_DELAY}}`); +const override = `${TMP}/override.json`; +writeFileSync(override, mergeOverrideText(baseText, { ...switches, latency_ladder: ladderList, fees: feesObject, emission: emissionObject, finality: finalityObject })); +log(`object: ${OBJECT}; every switch from genesis; finality ${finalityObject}; ladder window ${LADDER_WINDOW}; emission ${emissionObject}; run ${SECS} s, leave at ${LEAVE_AT} s; expect ${EXPECT}`); + +// six keys: five voters and one that never votes, so the silent key's share of the weight window sits far from the +// third at which the rule pauses by design (on the pin's run of 8 October 2026 one silent key of five held a quarter of +// the blocks and finality paused at the end on a 120-block window: the rule, not the object) +const LABELS = ['tn-voter-a', 'tn-voter-b', 'tn-voter-c', 'tn-voter-d', 'tn-voter-e', 'tn-silent']; +const EVM = ['00000000000000000000000000000000000000a0', '00000000000000000000000000000000000000a1', '00000000000000000000000000000000000000a2', '00000000000000000000000000000000000000a3', '00000000000000000000000000000000000000a5', '00000000000000000000000000000000000000a4']; +const N = LABELS.length, SILENT = N - 1, LEAVER = 1; +// each miner's payout address as the miner itself prints it (its first log line names it); devAddress(label) is the +// harness's own derivation and is not the miner's, so the chain's outputs are matched against the printed one +let ADDR = LABELS.map(l => devAddress(l)); +function addressesFromMinerLogs() { + return LABELS.map((_, i) => { const m = minerLog(i).join('\n').match(/igneum(?:dev|test)?:[a-z0-9]{20,}/); return m ? m[0] : ADDR[i]; }); +} +class Node { + constructor(i, connect = []) { + this.i = i; this.grpcPort = BASE + i * 10; this.p2pPort = BASE + i * 10 + 1; this.jsonPort = BASE + i * 10 + 2; this.evmPort = BASE + i * 10 + 3; + this.connect = connect; this.dir = `${TMP}/n${i}`; this.logFile = `${this.dir}/node.log`; + } + get grpc() { return `grpc://127.0.0.1:${this.grpcPort}`; } + async start() { + mkdirSync(this.dir, { recursive: true }); + const a = ['--devnet', `--devnet-suffix=${SUFFIX}`, '--nodnsseed', '--disable-upnp', '--nologfiles', '--enable-unsynced-mining', '--utxoindex', + `--appdir=${this.dir}`, `--rpclisten=127.0.0.1:${this.grpcPort}`, `--rpclisten-json=127.0.0.1:${this.jsonPort}`, `--evm-rpclisten=127.0.0.1:${this.evmPort}`, + `--listen=127.0.0.1:${this.p2pPort}`, `--override-params-file=${override}`, '--loglevel=info', '--yes']; + if (this.connect.length) a.push(`--connect=${this.connect.join(',')}`); else a.push('--outpeers=0'); + const out = openSync(this.logFile, 'a'); + this.proc = spawn(IGNEUMD, a, { stdio: ['ignore', out, out] }); + started.push(this.proc); + writeFileSync(`${TMP}/n${this.i}.pid`, String(this.proc.pid)); + await sleep(1500); + this.rpc = await connectRpc(`ws://127.0.0.1:${this.jsonPort}`); + log(`n${this.i} up pid ${this.proc.pid} json ${this.jsonPort} p2p ${this.p2pPort} evm ${this.evmPort}`); + return this; + } + grepLog(re) { try { return readFileSync(this.logFile, 'utf8').split('\n').filter(l => re.test(l)); } catch { return []; } } + async evm(method, params) { + const r = await fetch(`http://127.0.0.1:${this.evmPort}`, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) }); + return (await r.json()).result; + } +} +function miner(bin, argv, name, env = {}) { + const out = openSync(`${TMP}/${name}.log`, 'a'); + const p = spawn(bin, argv, { stdio: ['ignore', out, out], env: { ...process.env, ...env } }); + started.push(p); + writeFileSync(`${TMP}/${name}.pid`, String(p.pid)); + return p; +} +async function stopAll() { + for (const p of started.reverse()) { try { p.kill('SIGINT'); } catch { } } + await sleep(1500); + for (const p of started) { try { p.kill('SIGKILL'); } catch { } } +} +process.on('SIGINT', async () => { await stopAll(); process.exit(130); }); +process.on('unhandledRejection', async (e) => { log(`FAILED: ${e?.stack || e}`); await stopAll(); process.exit(3); }); +process.on('uncaughtException', async (e) => { log(`FAILED: ${e?.stack || e}`); await stopAll(); process.exit(3); }); +const minerLog = (i) => { try { return readFileSync(`${TMP}/cpu${i}.log`, 'utf8').split('\n'); } catch { return []; } }; + +const t0 = Date.now(); +const since = () => ((Date.now() - t0) / 1000).toFixed(1); +try { +const n0 = await new Node(0).start(); +const nodes = [n0]; +for (let i = 1; i < N; i++) nodes.push(await new Node(i, [`127.0.0.1:${n0.p2pPort}`]).start()); +const n1 = nodes[LEAVER]; +const START_LINES = { + digest: /Consensus params digest: ([0-9a-f]{64})/, + class_v4: /program class v4|class v4 from|Program class: v4|class_v4/i, + ladder_active: /Latency ladder active: rungs/, + proof_verification_from_0: /Proving: consensus proof verification from DAA score 0/, + fees_v1: /calibrated v1 from DAA score 0/, + finality_v3_and_c1: /rule v3 \(frozen table, certificate fold\) from checkpoint DAA 0.*C1 in DAA seconds/, +}; +for (const n of nodes) log(`n${n.i}: ${Object.entries(START_LINES).map(([k, re]) => `${k}=${n.grepLog(re).length > 0}`).join(' ')} | digest ${(n.grepLog(START_LINES.digest)[0] || '').replace(/^.*?digest: /, '').slice(0, 16)}`); +// n0 and n1 vote (the key is the payout label's identity); n2 never votes: the silent key +// the miners (and so the voters) outlive the run by five minutes and are stopped by the stop hook, so the final finality +// read never sees a table nobody signs (pod 2 of 8 October 2026 read "0.00% signing" after the voters had exited with the run) +const miners = nodes.map((n, i) => miner(CPU_MINER, ['mine', n.grpc, '1', String(SECS + 300), `cpu${i}`, '--engine', 'igneum-pow', '--payout-label', LABELS[i], '--evm-address', EVM[i], '--dev-fee', '0', '--status-secs', '30', '--stall-secs', '0', '--exec-rpc', `http://127.0.0.1:${n.evmPort}`, ...(i === SILENT ? ['--no-vote'] : [])], `cpu${i}`, { IGNEUM_POW_DAY_MS: String(DAY_MS) })); +// --exec-rpc: the class v5 state provider's address; without it the 0.3.24-line miner asks the devnet port 26790 on every +// network (row 9t), and five one-box nodes have five exec ports +const pay = devAddress('fast-time-testnet-object'); + +const epochs = new Map(); +let lastEpoch = -1, lastReport = 0, lastDaa = 0, firstLock = null, leaveSent = null, leaveOutcome = null, votersBeforeLeave = null, votersAfterLeave = null, leaveSeenAt = null; +const samples = []; +const inactiveAfterLeave = []; +async function report(node, last = 50) { return node.rpc.call('getFinalityCheckpoints', { last }).catch(() => null); } +while (Date.now() - t0 < SECS * 1000) { + await sleep(1000); + let daa = null, epoch = null, cls = null, reps = null, step = null, sig = null; + try { + const t = await n0.rpc.call('getBlockTemplate', { payAddress: pay, extraData: [] }); + const pe = t.powEpoch || t.pow_epoch || {}; + daa = pe.virtualDaaScore ?? t.block?.header?.daaScore; epoch = pe.epochIndex; cls = pe.programClass; + reps = pe.latencyLadderReps; step = pe.latencyLadderStep; sig = pe.latencyLadderSignal; + } catch (e) { log(`template: ${e.message}`); } + if (epoch != null && epoch !== lastEpoch) { + epochs.set(epoch, { class: cls, reps, step, firstSeenDaa: daa, at: +since() }); + log(`epoch ${lastEpoch} -> ${epoch} at daa ${daa}, ${since()} s: template class ${cls} rung ${step} (${reps} passes), this node signals ${sig}`); + lastEpoch = epoch; + } + lastDaa = daa ?? lastDaa; + const r = await report(n0, 5); + if (r && firstLock == null && r.latestLockedIndex > 0) { firstLock = { index: r.latestLockedIndex, daa, at: +since() }; log(`FIRST LOCK: index ${r.latestLockedIndex} at daa ${daa}, ${since()} s wall (active ${r.finalityActive})`); } + if (leaveSent == null && Date.now() - t0 >= LEAVE_AT * 1000 && firstLock != null) { + const before = await report(n1, 3); + votersBeforeLeave = before?.checkpoints?.at(-1)?.voters ?? null; + const out = spawnSync(CPU_MINER, ['leave', n1.grpc, LABELS[LEAVER]], { encoding: 'utf8', timeout: 20000 }); + leaveSent = { at: +since(), daa, stdout: (out.stdout || '').trim().slice(0, 300), stderr: (out.stderr || '').trim().slice(0, 300) }; + leaveOutcome = /LEAVE key=/.test(out.stdout || '') ? 'accepted' : 'refused'; + log(`LEAVE by ${LABELS[LEAVER]} at daa ${daa}: ${leaveOutcome} (${leaveSent.stdout || leaveSent.stderr}); voters before ${votersBeforeLeave}; stopping its miner (a clean departure)`); + try { miners[LEAVER].kill('SIGINT'); } catch { } + } + if (leaveSent != null && votersAfterLeave == null) { + const after = await report(n0, 3); + const v = after?.checkpoints?.at(-1)?.voters ?? null; + if (v != null && votersBeforeLeave != null && v < votersBeforeLeave) { votersAfterLeave = v; leaveSeenAt = { at: +since(), daa }; log(`LEAVE TOOK EFFECT: voters ${votersBeforeLeave} -> ${v} at daa ${daa}, ${since()} s`); } + } + if (leaveSent != null && r && r.finalityActive === false) { inactiveAfterLeave.push({ at: +since(), daa, reason: r.finalityReason }); } + if (Date.now() - lastReport > 15000) { + lastReport = Date.now(); + const counts = await Promise.all(nodes.map(async n => { try { const d = await n.rpc.call('getBlockDagInfo'); return `${d.blockCount}/${String(d.sink).slice(0, 8)}`; } catch { return '?'; } })); + log(`t=${since()} s daa ${daa} epoch ${epoch} class ${cls} rung ${step} (${reps}) lock ${r?.latestLockedIndex ?? '?'} active ${r?.finalityActive ?? '?'} blocks/sink per node ${counts.join(' ')}`); + samples.push({ t: +since(), daa, epoch, class: cls, step, reps, locked: r?.latestLockedIndex ?? null, active: r?.finalityActive ?? null, nodes: counts }); + } +} +// the final finality read, taken the moment the run ends and while every voter still signs +const finalReports = await Promise.all(nodes.map(n => report(n, 3))); +await sleep(3000); + +// the chain: every block with its coinbase outputs by address, and the execution layer's segment rewards by miner +const dag = await Promise.all(nodes.map(async n => { try { return await n.rpc.call('getBlockDagInfo'); } catch (e) { return { error: e.message }; } })); +const genesis = dag[0].pruningPointHash; +async function allBlocks(n) { + const out = []; let low = genesis; const seen = new Set(); + for (let round = 0; round < 500; round++) { + const r = await n.rpc.call('getBlocks', { lowHash: low, includeBlocks: true, includeTransactions: true }); + const blocks = r.blocks || []; + let added = 0; + for (const b of blocks) { + const h = b.verboseData?.hash || b.header?.hash; if (seen.has(h)) continue; seen.add(h); + const coinbase = (b.transactions || [])[0]; + const outputs = (coinbase?.outputs || []).map(o => ({ address: o.verboseData?.scriptPublicKeyAddress || '', value: BigInt(typeof o.value === 'string' ? o.value : Math.round(o.value)) })); + out.push({ hash: h, daa: +b.header.daaScore, version: +b.header.version, chain: !!b.verboseData?.isChainBlock, outputs }); added++; + } + if (!blocks.length || added === 0) break; + low = (r.blockHashes || []).at(-1) || blocks.at(-1).verboseData?.hash; if (!low) break; + } + return out; +} +let blocks = []; +try { blocks = await allBlocks(n0); } catch (e) { log(`getBlocks: ${e.message}`); } +const chainBlocks = blocks.filter(b => b.chain && b.daa > 0).sort((a, b) => a.daa - b.daa); +const segments = []; +const tip = Number(BigInt(await n0.evm('eth_blockNumber', []).catch(() => '0x0'))); +for (let i = 1; i <= tip; i++) { const s = await n0.evm('igneum_getSegment', [`0x${i.toString(16)}`]).catch(() => null); if (s) segments.push(s); } +const segByHash0 = new Map(segments.map(s => [String(s.hash).replace(/^0x/, '').toLowerCase(), s])); +ADDR = addressesFromMinerLogs(); +const isPool = (o) => o.address === '' || o.address == null; +const hashKey = (h) => String(h).replace(/^0x/, '').toLowerCase(); +const byHash = new Map(blocks.map(b => [hashKey(b.hash), b])); +// What each coinbase pays and what each segment credits (the node lane's reading of 7 October 2026, confirmed on the +// chain here): the coinbase of chain block b pays b's mergeset, which is chain block b-1 (its selected parent) plus the +// side blocks b merges; the execution record of chain block b credits b ITSELF plus the side blues b merges. So a chain +// block is paid by its child's coinbase and credited in its own segment, one record apart; a side blue is paid and +// credited in the same chain block. Totals per miner over the chain agree exactly once the tip's own credit (not yet +// paid by a child) is set aside. +const chainIndex = new Map(chainBlocks.map((b, i) => [hashKey(b.hash), i])); +const sidesOf = (seg, selfHash) => (seg?.mergeset || []).filter(m => hashKey(m.hash) !== selfHash); +const segHoldsItself = chainBlocks.filter(b => { const seg = segByHash0.get(hashKey(b.hash)); return seg && (seg.mergeset || []).some(m => hashKey(m.hash) === hashKey(b.hash)); }).length; +log(`segments: ${segByHash0.size}; chain blocks whose own segment lists them in its mergeset: ${segHoldsItself} of ${chainBlocks.length}`); +// the TESTNET_1 schedule at the devnet's unit inside the ramp (the run is minutes long; the first glide step is a month away) +const RAMP = 7_776_000n, START = 10n, FULL = 10_000_000_000n; +const subsidyAt = (daa) => { const sDaa = BigInt(daa); return sDaa >= RAMP ? FULL : FULL * (START * RAMP + (100n - START) * sDaa) / (100n * RAMP); }; +const poolShare = (a) => (a / 100n) * 20n + (a % 100n) * 20n / 100n; +const splitOf = (a, silent) => { const producerShare = a - poolShare(a); let producer = producerShare; let pool = poolShare(a); if (silent) { const bonus = producerShare * 1000n / 10000n; producer -= bonus > producer ? producer : bonus; pool += bonus; } return [producer, pool]; }; +// learn each miner's UTXO address from the chain: a chain block b whose coinbase has one producer output and whose +// mergeset is its selected parent alone (segment(b) lists no side block) pays chain block b-1, whose miner is the one +// reward of segment(b-1) when that segment has no sides either +{ + const learnt = new Map(); + for (let i = 1; i < chainBlocks.length; i++) { + const b = chainBlocks[i], parent = chainBlocks[i - 1]; + const seg = segByHash0.get(hashKey(b.hash)), segParent = segByHash0.get(hashKey(parent.hash)); + if (!seg || !segParent) continue; + if (sidesOf(seg, hashKey(b.hash)).length !== 0 || sidesOf(segParent, hashKey(parent.hash)).length !== 0) continue; + const producers = b.outputs.filter(o => !isPool(o)); + const rewards = segParent.rewards || []; + if (producers.length !== 1 || rewards.length !== 1) continue; + const k = EVM.indexOf(hashKey(rewards[0].miner)); + if (k >= 0 && !learnt.has(k)) learnt.set(k, producers[0].address); + } + for (const [i, a] of learnt) ADDR[i] = a; + log(`learnt addresses from the chain: ${[...learnt.entries()].map(([i, a]) => `${LABELS[i]}=${a.slice(0, 24)}`).join(' ')} (${learnt.size} of ${N})`); +} +const lockDaa = firstLock?.daa ?? Infinity; +// 1. the identity per miner over the whole chain: UTXO payments x 10^10 against execution credits, the tip's own +// credit set aside (its child's coinbase does not exist yet) +const tipBlock = chainBlocks.at(-1); +const tipSeg = tipBlock ? segByHash0.get(hashKey(tipBlock.hash)) : null; +const tipOwnCredit = (k) => { if (!tipSeg) return 0n; const blues = (tipSeg.mergeset || []).filter(m => m.blue); const self = blues.findIndex(m => hashKey(m.hash) === hashKey(tipBlock.hash)); const r = (tipSeg.rewards || [])[self]; return r && hashKey(r.miner) === EVM[k] ? BigInt(r.wei) : 0n; }; +const bridgeRows = []; +for (let k = 0; k < N; k++) { + const utxo = chainBlocks.reduce((s, b) => s + b.outputs.filter(o => o.address === ADDR[k]).reduce((t, o) => t + o.value, 0n), 0n); + const exec = [...segByHash0.values()].reduce((s, seg) => s + (seg.rewards || []).filter(r => hashKey(r.miner) === EVM[k]).reduce((t, r) => t + BigInt(r.wei), 0n), 0n); + const execPaid = exec - tipOwnCredit(k); + bridgeRows.push({ miner: LABELS[k], utxo_sompi: String(utxo), exec_wei: String(exec), exec_wei_less_tip: String(execPaid), identity: utxo * WEI_PER_SOMPI === execPaid, blocks_paid: chainBlocks.reduce((n, b) => n + b.outputs.filter(o => o.address === ADDR[k]).length, 0) }); +} +const bridgeIdentityVoters = bridgeRows.filter(r => r.miner !== LABELS[SILENT]).every(r => r.identity && r.blocks_paid > 0); +// 2. the bonus on the UTXO side: every coinbase output after the first lock, matched to the block it pays (chain b-1 +// or a side blue of b, by miner, when that miner has exactly one blue block in the mergeset), priced at that block's +// own DAA: a silent key's block is paid the bonus split, a voting key's the plain 80 percent +const bonusRows = []; +for (let i = 1; i < chainBlocks.length; i++) { + const b = chainBlocks[i]; + if (b.daa <= lockDaa) continue; + const seg = segByHash0.get(hashKey(b.hash)); + if (!seg) continue; + const paid = [{ hash: hashKey(chainBlocks[i - 1].hash), blue: true }, ...sidesOf(seg, hashKey(b.hash)).map(m => ({ hash: hashKey(m.hash), blue: !!m.blue }))]; + const paidBlocks = paid.map(p => ({ ...p, block: byHash.get(p.hash) })).filter(p => p.block); + for (let k = 0; k < N; k++) { + const mine = paidBlocks.filter(p => p.block.outputs !== undefined && minerOf(p.block) === k); + if (mine.length !== 1 || !mine[0].blue) continue; + const out = b.outputs.filter(o => o.address === ADDR[k]); + if (out.length !== 1) continue; + const [expectVoting] = splitOf(subsidyAt(mine[0].block.daa), false); + const [expectSilent] = splitOf(subsidyAt(mine[0].block.daa), true); + bonusRows.push({ chain_daa: b.daa, paid_block_daa: mine[0].block.daa, miner: LABELS[k], silent_key: k === SILENT, utxo_producer_sompi: String(out[0].value), expect_voting: String(expectVoting), expect_silent: String(expectSilent) }); + } +} +function minerOf(block) { for (let k = 0; k < N; k++) if (block.outputs.some(() => false)) return -1; return block.minerIndex ?? -1; } +// a block's miner: the vote key hash is not in getBlocks' verbose data here, so take it from the segment that credits +// the block (its own segment for a chain block, the merging chain block's segment for a side blue) +for (const b of blocks) { + const own = segByHash0.get(hashKey(b.hash)); + let miner = null; + if (own) { const blues = (own.mergeset || []).filter(m => m.blue); const self = blues.findIndex(m => hashKey(m.hash) === hashKey(b.hash)); const r = (own.rewards || [])[self]; if (r) miner = hashKey(r.miner); } + if (miner == null) for (const seg of segByHash0.values()) { const blues = (seg.mergeset || []).filter(m => m.blue); const j = blues.findIndex(m => hashKey(m.hash) === hashKey(b.hash)); if (j >= 0) { const r = (seg.rewards || [])[j]; if (r) { miner = hashKey(r.miner); break; } } } + b.minerIndex = miner == null ? -1 : EVM.indexOf(miner); +} +// the bonus rows were built before minerIndex existed: build them again now that every block knows its miner +bonusRows.length = 0; +for (let i = 1; i < chainBlocks.length; i++) { + const b = chainBlocks[i]; + if (b.daa <= lockDaa) continue; + const seg = segByHash0.get(hashKey(b.hash)); + if (!seg) continue; + const paid = [{ hash: hashKey(chainBlocks[i - 1].hash), blue: true }, ...sidesOf(seg, hashKey(b.hash)).map(m => ({ hash: hashKey(m.hash), blue: !!m.blue }))]; + const paidBlocks = paid.map(p => ({ ...p, block: byHash.get(p.hash) })).filter(p => p.block); + for (let k = 0; k < N; k++) { + const mine = paidBlocks.filter(p => p.block.minerIndex === k); + if (mine.length !== 1 || !mine[0].blue) continue; + const out = b.outputs.filter(o => o.address === ADDR[k]); + if (out.length !== 1) continue; + const [expectVoting] = splitOf(subsidyAt(mine[0].block.daa), false); + const [expectSilent] = splitOf(subsidyAt(mine[0].block.daa), true); + bonusRows.push({ chain_daa: b.daa, paid_block_daa: mine[0].block.daa, miner: LABELS[k], silent_key: k === SILENT, utxo_producer_sompi: String(out[0].value), expect_voting: String(expectVoting), expect_silent: String(expectSilent) }); + } +} +const silentRows = bonusRows.filter(r => r.silent_key); +const votingRows = bonusRows.filter(r => !r.silent_key); +const bonusPaidOnUtxo = silentRows.length > 0 && silentRows.every(r => r.utxo_producer_sompi === r.expect_silent); +const votersPaidPlain = votingRows.length > 0 && votingRows.every(r => r.utxo_producer_sompi === r.expect_voting); +const silentPaidLessThanVoters = bonusPaidOnUtxo && votersPaidPlain; +const bridgeIdentity = bridgeRows.every(r => r.identity); + +const bridgeIdentitySilent = bridgeRows.filter(r => r.miner === LABELS[SILENT]).every(r => r.identity && r.blocks_paid > 0); + +const stampedByte = (() => { const m = n0.grepLog(/stamps object version (\d+)/).map(l => +(/stamps object version (\d+)/.exec(l)[1]))[0]; return m == null ? 0 : m; })(); +const objectBytes = blocks.filter(b => b.daa > 0).reduce((m, b) => { const v = (b.version >> 8) & 0x3f; m[v] = (m[v] || 0) + 1; return m; }, {}); +const ladderBits = blocks.filter(b => b.daa > 0).reduce((m, b) => { const k = (b.version & 0x8000) ? 'up' : (b.version & 0x4000) ? 'down' : 'none'; m[k] = (m[k] || 0) + 1; return m; }, {}); +const sinks = dag.map(d => String(d.sink || '?').slice(0, 16)); +const counts = dag.map(d => d.blockCount ?? '?'); +const accepted = LABELS.map((_, i) => minerLog(i).filter(l => /ACCEPTED block/.test(l)).length); +const rejectedNode = nodes.map(n => n.grepLog(/PoW rejected|Rejected block|rejected block/i).length); +// the report's reason flickers for one read at every new lock (the table frozen at the lock reads 0.00 percent signing +// for a second); a pause is consecutive inactive reads, measured in seconds of the 1-s poll, never one read +function longestInactiveStretchAfter(daa) { + const xs = inactiveAfterLeave.filter(x => x.daa > daa).map(x => x.at).sort((a, b) => a - b); + let best = 0, start = null, prev = null; + for (const t of xs) { if (prev == null || t - prev > 2.5) { start = t; } prev = t; best = Math.max(best, t - start + 1); } + return best; +} +const checks = { + start_lines_on_every_node: nodes.every(n => Object.entries(START_LINES).every(([k, re]) => k === 'class_v4' || n.grepLog(re).length > 0)), + digest_equal_on_every_node: new Set(nodes.map(n => (n.grepLog(START_LINES.digest)[0] || '').replace(/^.*?digest: /, '').slice(0, 64))).size === 1, + every_epoch_object_class_at_rung_0: epochs.size > 0 && [...epochs.values()].every(e => e.class === OBJECT_CLASS && (e.step === 0 || e.step == null) && (e.reps === RUNG0 || e.reps == null)), + // the object byte every mined block stamps is the one the node's own start-up line names ("stamps object version N"; 6 on + // the go object with class v5 from genesis, 7 on the 5b673577 object, the Devnet 3 shape with class signalling on; 0 when + // signalling is off); no ladder bits + no_ladder_bits_and_object_byte_as_stamped: blocks.length > 0 && Object.keys(ladderBits).every(k => k === 'none') && Object.keys(objectBytes).every(v => +v === stampedByte), + zero_rejected_by_nodes: rejectedNode.every(c => c === 0), + sinks_and_counts_agree: new Set(sinks).size === 1 && new Set(counts.map(String)).size === 1, + first_lock_on_every_node: firstLock != null && finalReports.every(r => r && r.latestLockedIndex > 0), + silent_key_mined_after_the_lock: silentRows.length > 0, + bonus_paid_on_the_utxo_side: silentPaidLessThanVoters && bonusPaidOnUtxo, + voters_paid_the_plain_split_on_the_utxo_side: votersPaidPlain, + bridge_identity_for_voting_keys: bridgeIdentityVoters, + bridge_identity_for_the_silent_key: bridgeIdentitySilent, + leave_accepted: leaveOutcome === 'accepted', + leave_took_effect_within_delay_and_a_window: leaveSeenAt != null && leaveSent != null && (leaveSeenAt.daa - leaveSent.daa) <= LEAVE_DELAY + 120 + 30 + 5, + // the point of the leave item: a clean departure never holds finality for a window; the pause after the leave, if any, + // ends inside the delay plus one checkpoint, never a full window (120 DAA at fast time) + // rule v3's share swings per checkpoint while CPU voters sign late; what the leave item buys is that a clean departure + // never holds finality for a window: no inactive stretch of a window (120 DAA) after the leave took effect + no_window_pause_after_the_leave_took_effect: leaveSeenAt != null && longestInactiveStretchAfter(leaveSeenAt.daa) < 120, // seconds: one block a second at fast time, so a window of 120 DAA is 120 s + finality_active_at_the_end: finalReports.every(r => r && r.finalityActive === true), +}; +let pass; +if (EXPECT === 'bonus-fails') { + // the known-failed case: the executor before the fix pays the silent key the full share, every other check holds + pass = Object.entries(checks).every(([k, v]) => k === 'bridge_identity_for_the_silent_key' ? v === false : v); +} else { + pass = Object.values(checks).every(Boolean); +} +const summary = { + pass, expect: EXPECT, checks, node: IGNEUMD, miner: CPU_MINER, override, run_secs: SECS, final_daa: lastDaa, + epochs: Object.fromEntries([...epochs.entries()]), first_lock: firstLock, + leave: { sent: leaveSent, outcome: leaveOutcome, voters_before: votersBeforeLeave, voters_after: votersAfterLeave, seen_at: leaveSeenAt, delay_daa: LEAVE_DELAY, longest_inactive_stretch_secs_after_effect: leaveSeenAt ? longestInactiveStretchAfter(leaveSeenAt.daa) : null, inactive_after: inactiveAfterLeave }, + blocks: { total: blocks.length, chain: chainBlocks.length, segments: segments.length, object_bytes: objectBytes, ladder_bits: ladderBits }, + bridge_rows: bridgeRows, bonus_rows: bonusRows, accepted_per_miner: accepted, rejected_by_nodes: rejectedNode, sinks, block_counts: counts, samples, + final_reports: finalReports.map(r => r && { active: r.finalityActive, reason: r.finalityReason, locked: r.latestLockedIndex, voters: r.checkpoints?.at(-1)?.voters ?? null }), +}; +writeFileSync(`${TMP}/summary.json`, JSON.stringify(summary, null, 2)); +log(`SUMMARY ${pass ? 'PASS' : 'FAIL'} (expect ${EXPECT}): epochs ${[...epochs.entries()].map(([e, v]) => `e${e}:v${v.class}:r${v.step}`).join(' ')}; first lock ${firstLock ? `index ${firstLock.index} at daa ${firstLock.daa}` : 'none'}; silent rows ${silentRows.length} (${silentRows.slice(0, 2).map(r => `daa ${r.paid_block_daa} utxo ${r.utxo_producer_sompi} silent ${r.expect_silent} voting ${r.expect_voting}`).join('; ')}), voting rows ${votingRows.length}; bridge ${bridgeRows.map(r => `${r.miner} utxo ${r.utxo_sompi} exec-tip ${r.exec_wei_less_tip} ${r.identity}`).join('; ')}; leave ${leaveOutcome} voters ${votersBeforeLeave} -> ${votersAfterLeave}; blocks ${blocks.length} chain ${chainBlocks.length}; rejected ${rejectedNode.join('/')}; sinks ${sinks.join(' ')} at ${counts.join('/')}`); +for (const [k, v] of Object.entries(checks)) if (!v) log(`${EXPECT === 'bonus-fails' && k === 'bridge_identity_for_the_silent_key' ? 'EXPECTED FAILED CHECK' : 'FAILED CHECK'} ${k}`); +log(`summary: ${TMP}/summary.json`); +await stopAll(); +process.exit(pass ? 0 : 1); +} catch (e) { + log(`FAILED: ${e?.stack || e}`); + await stopAll(); + process.exit(3); +} diff --git a/infra/fast-time/tn-late-join.mjs b/infra/fast-time/tn-late-join.mjs new file mode 100644 index 000000000..5d2573f17 --- /dev/null +++ b/infra/fast-time/tn-late-join.mjs @@ -0,0 +1,228 @@ +#!/usr/bin/env node +// The testnet lane's copy of infra/fast-time/headers-proof-join.mjs (ca3-v4-node e5f993d4) for the late-join gate of +// ledger N9's second half, 7 October 2026: the same join, with consensus proof verification and proving v0 from genesis +// in the override and a prover beside node A (--prover), so the joiner's proofs come from A's archive. +// +// The 0.3.17 canary's own path (7 October 2026): a FRESH node joining through IBD WITH A HEADERS PROOF a chain whose sink +// carries legal version-1026 signalling headers. The two-daemon test covers relay and headerless IBD; the proof path +// needs a chain past the pruning depth, so this harness runs one on a fast-time profile at the Prunality floor +// (finality 120, merge 60, k 18: pruning 2F + 4Mk + 2k + 2 = 4,598 DAA, set 4,600) and lets a fresh node join it. +// +// node A: override-60x.json re-depthed as above, the window object (window 120, floor 100000), IGNEUM_CLASS_SIGNAL=4, +// three CPU threads (about 2.3 blocks/s on this Mac) until its pruning point has left genesis and the sink is +// --margin blocks past that (about 35 minutes), then the miner stops. +// node B: fresh, the same override, --addpeer A. PASS (--expect join): B's log carries "Starting IBD with headers +// proof" and "IBD with peer ... completed successfully", B's sink equals A's within --watch seconds, and +// the sink's header on B reads version 1026. The known-failed shape of the gate is the 0.3.17 binary (no +// knob reproduces its raw comparison); the harness's own failed shape is `--expect stall`, which must FAIL. +// +// node infra/fast-time/headers-proof-join.mjs [--expect join|stall] [--margin 200] [--watch 600] [--threads 3] +// IGNEUMD, IGNEUM_MINER name the binaries (defaults: vendor/igneum-node-0316/target-0316/release). + +import { spawn, spawnSync } from 'node:child_process'; +import { mkdirSync, rmSync, writeFileSync, readFileSync, openSync, existsSync, copyFileSync } from 'node:fs'; +import { connectRpc } from '../../tools/finality-attacks/lib/rpc.mjs'; + +const ROOT = new URL('../../', import.meta.url).pathname; +const FILE = `${ROOT}infra/fast-time/override-60x.json`; +const BIN = process.env.IGNEUM_0316_BIN || `${ROOT}vendor/igneum-node-0316/target-0316/release`; +const IGNEUMD = process.env.IGNEUMD || `${BIN}/igneumd`; +const CPU_MINER = process.env.IGNEUM_MINER || `${BIN}/igneum-miner`; +const TMP = process.env.IGNEUM_TN_TMP || '/tmp/igneum-fast-time-tn-join'; +const BASE = +(process.env.IGNEUM_TN_BASE_PORT || 30590), SUFFIX = +(process.env.IGNEUM_TN_SUFFIX || 997); +const NEVER = '18446744073709551615'; +const args = process.argv.slice(2); +const flag = (name, dflt) => { const i = args.indexOf(`--${name}`); return i >= 0 ? Number(args[i + 1]) : dflt; }; +const sflag = (name) => { const i = args.indexOf(`--${name}`); return i >= 0 ? args[i + 1] : null; }; +const EXPECT = sflag('expect') || 'join'; +const WINDOW = Number(sflag('window') || 150); +// The testnet lane's late-join case (ledger N9's second half, 7 October 2026): --prover "" starts a prover +// beside A's miner (its records land in A's blocks through the ordinary record flows; the command sees IGNEUM_GRPC +// and IGNEUM_EVM_RPC for node A), and --join-after holds B's start until A has mined that many blocks past +// its ready point, so B joins after the pool's 600-chain-block window has passed and every proof it asks for must +// come from the peers' archives. PASS is the same join; the failed shape is the node before the archive, which +// stalls on "proofs this peer did not deliver in 20 s". +const PROVER = sflag('prover') || null; +const JOIN_AFTER = Number(sflag('join-after') || 0); +// --resume: node A is already up on BASE's ports with its chain (a harness instance whose miner ran out before the join), and +// RESUME_PIDS names pid files of the processes to stop before B joins (the rescue miner, the prover); nothing is wiped +const RESUME = args.includes('--resume'); +const RESUME_PIDS = (sflag('resume-pids') || '').split(',').filter(Boolean); +const MARGIN = flag('margin', 200), WATCH = flag('watch', 600), THREADS = flag('threads', 3), MAX_MINE = flag('max-mine', 5400); +const OUT = sflag('out') || `${TMP}/late-join-expect-${EXPECT}.json`; +if (!['join', 'stall'].includes(EXPECT)) { console.error('usage: --expect join|stall'); process.exit(2); } +const started = []; +const log = (...a) => console.log(new Date().toISOString().slice(11, 23), ...a); +const sleep = (ms) => new Promise(r => setTimeout(r, ms)); +for (const b of [IGNEUMD, CPU_MINER]) if (!existsSync(b)) { console.error(`missing ${b}`); process.exit(2); } +if (!RESUME) { rmSync(TMP, { recursive: true, force: true }); } mkdirSync(TMP, { recursive: true }); + +const baseText = readFileSync(FILE, 'utf8'); +const field = (name) => { const m = new RegExp(`"${name}":\\s*([0-9]+)`).exec(baseText); return m ? +m[1] : undefined; }; +export function mergeOverrideText(text, fields) { + let out = text; + for (const k of Object.keys(fields)) out = out.replace(new RegExp(`\\s*"${k}":\\s*[^,}\\n]+,?`), ''); + const extra = Object.entries(fields).map(([k, v]) => `"${k}": ${typeof v === 'string' && !/^\d+$/.test(v) ? JSON.stringify(v) : v}`).join(', '); + return out.replace(/,?\s*}\s*$/, `,\n ${extra}\n}\n`); +} +// the depths at the Prunality floor: the blockrate block's finality_depth and pruning_depth replaced in place +export function redepth(text) { + // --window: the sampled difficulty window in samples (rate 4). The default 150 (the minimum) spans 600 DAA, which the + // pruning point at DAA about 800 fills; 661 (the devnet's own) spans 2,644 DAA and is the known-failed shape found + // on the first run (7 October 2026, 05:45 UK): the joiner's walk through the sampled trusted blocks runs out at a + // gap before genesis and the rule "DAA window data has only N entries" ends the IBD. The devnet meets that for + // the 2,644 DAA after its pruning point first leaves genesis; the node fix makes a young chain's short window legal. + return text + .replace(/"finality_depth":\s*\d+/, '"finality_depth": 120') + .replace(/"pruning_depth":\s*\d+/, '"pruning_depth": 4600') + .replace(/"difficulty_window_size":\s*\d+/, `"difficulty_window_size": ${WINDOW}`); +} +const DAY_MS = field('pow_day_ms'); +const override = `${TMP}/override.json`; +if (!RESUME) writeFileSync(override, mergeOverrideText(redepth(baseText), { + genesis_bits: 0x1f010000, skip_proof_of_work: false, + program_class_v3_activation_daa: NEVER, program_class_v4_activation_daa: '100000', program_class_v4_signal_window_daa: 120, + // the testnet lane's late-join case (ledger N9's second half): consensus proof verification from genesis under the + // testnet object's pinned ids and proving v0 from genesis, so the prover's records are carried and verified, and a + // joiner past the pool's window must get their proofs from the peers' archives + proving_v0_activation_daa: '0', proving_consensus_verify_daa: '0', + proving_shard_program_id: '0x2b1a81cb413236cf063077b46ed3111628f6c41036bcf6e23ee4cbbf5679ef7a', proving_aggregator_id: '0x474678f35f7545db28055d5e5bbc308231d84a5a072202087a2a8d5b09123896', +})); +log(`expect ${EXPECT}: pruning depth 4600 (finality 120, merge 60, k 18), the window object set, signal byte 4, ${THREADS} threads, margin ${MARGIN}, watch ${WATCH} s`); + +class Node { + constructor(i, connect = null) { + this.i = i; this.grpcPort = BASE + i * 10; this.p2pPort = BASE + i * 10 + 1; this.jsonPort = BASE + i * 10 + 2; this.evmPort = BASE + i * 10 + 3; + this.connect = connect; this.dir = `${TMP}/n${i}`; this.logFile = `${this.dir}/node.log`; + } + get grpc() { return `grpc://127.0.0.1:${this.grpcPort}`; } + async attach() { + for (let i = 0; i < 20; i++) { + try { this.rpc = await connectRpc(`ws://127.0.0.1:${this.jsonPort}`); await this.rpc.call('getBlockDagInfo'); break; } catch { this.rpc = null; await sleep(500); } + } + if (!this.rpc) throw new Error(`n${this.i}: no live node answers on ${this.jsonPort}`); + log(`n${this.i} attached on json ${this.jsonPort} (resume)`); + return this; + } + async start() { + mkdirSync(this.dir, { recursive: true }); + const a = ['--devnet', `--devnet-suffix=${SUFFIX}`, '--nodnsseed', '--disable-upnp', '--nologfiles', '--enable-unsynced-mining', '--utxoindex', + `--appdir=${this.dir}`, `--rpclisten=127.0.0.1:${this.grpcPort}`, `--rpclisten-json=127.0.0.1:${this.jsonPort}`, `--evm-rpclisten=127.0.0.1:${this.evmPort}`, + `--listen=127.0.0.1:${this.p2pPort}`, `--override-params-file=${override}`, '--loglevel=info', '--yes']; + if (this.connect) a.push(`--addpeer=127.0.0.1:${this.connect}`); else a.push('--outpeers=0'); + const out = openSync(this.logFile, 'a'); + this.proc = spawn(IGNEUMD, a, { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_CLASS_SIGNAL: '4' } }); + started.push(this.proc); + writeFileSync(`${TMP}/n${this.i}.pid`, String(this.proc.pid)); + await sleep(1500); + if (this.proc.exitCode != null) throw new Error(`n${this.i} exited ${this.proc.exitCode}: ${this.grepLog(/ERROR|Error|error|refused|invalid/).slice(-3).join(' | ')}`); + for (let i = 0; i < 20; i++) { + try { this.rpc = await connectRpc(`ws://127.0.0.1:${this.jsonPort}`); await this.rpc.call('getBlockDagInfo'); break; } catch { this.rpc = null; await sleep(500); } + } + if (!this.rpc) throw new Error(`n${this.i}: the RPC did not answer within 10 s`); + log(`n${this.i} up pid ${this.proc.pid} json ${this.jsonPort} p2p ${this.p2pPort}${this.connect ? ` addpeer ${this.connect}` : ''}`); + return this; + } + grepLog(re) { try { return readFileSync(this.logFile, 'utf8').split('\n').filter(l => re.test(l)); } catch { return []; } } + async dag() { return this.rpc.call('getBlockDagInfo'); } + async headerOf(hash) { const b = await this.rpc.call('getBlock', { hash, includeTransactions: false }); return b.block.header; } +} +function miner(name, grpc, threads, secs) { + const out = openSync(`${TMP}/${name}.log`, 'a'); + const p = spawn(CPU_MINER, ['mine', grpc, String(threads), String(secs), name, '--engine', 'igneum-pow', '--payout-label', name, '--status-secs', '60', '--no-vote', '--stall-secs', '0'], { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_POW_DAY_MS: String(DAY_MS) } }); + started.push(p); + writeFileSync(`${TMP}/${name}.pid`, String(p.pid)); + return p; +} +async function stopAll() { + for (const p of [...started].reverse()) { try { p.kill('SIGINT'); } catch { } } + await sleep(1500); + for (const p of started) { try { p.kill('SIGKILL'); } catch { } } +} +process.on('SIGINT', async () => { await stopAll(); process.exit(130); }); +process.on('unhandledRejection', async (e) => { log(`FAILED: ${e?.stack || e}`); await stopAll(); process.exit(3); }); +process.on('uncaughtException', async (e) => { log(`FAILED: ${e?.stack || e}`); await stopAll(); process.exit(3); }); + +const a = RESUME ? await new Node(0).attach() : await new Node(0).start(); +const genesis = (await a.dag()).pruningPointHash; +const m = RESUME ? null : miner('a-miner', a.grpc, THREADS, MAX_MINE); +// the testnet lane's prover beside A's miner (its records reach A's blocks through the record flows) +let prover = null; +if (PROVER) { + const out = openSync(`${TMP}/prover.log`, 'a'); + prover = spawn('/bin/sh', ['-c', PROVER], { stdio: ['ignore', out, out], env: { ...process.env, IGNEUM_GRPC: a.grpc, IGNEUM_EVM_RPC: `http://127.0.0.1:${a.evmPort}` } }); + started.push(prover); + writeFileSync(`${TMP}/prover.pid`, String(prover.pid)); + log(`prover up pid ${prover.pid}: ${PROVER}`); +} +const t0 = Date.now(); +const since = () => ((Date.now() - t0) / 1000).toFixed(1); +let lastReport = 0, pruningMovedAt = null, pruningPoint = null; +if (RESUME) { const d = await a.dag(); pruningMovedAt = { t: 0, daa: +d.virtualDaaScore, blocks: d.blockCount, resumed: true }; pruningPoint = d.pruningPointHash; log(`resume: A at ${d.blockCount} blocks, daa ${d.virtualDaaScore}, pruning point ${String(d.pruningPointHash).slice(0, 8)} (taken as moved)`); } +while (!RESUME && Date.now() - t0 < MAX_MINE * 1000) { + await sleep(10000); + const d = await a.dag(); + if (pruningMovedAt == null && d.pruningPointHash !== genesis) { pruningMovedAt = { t: +since(), daa: +d.virtualDaaScore, blocks: d.blockCount }; pruningPoint = d.pruningPointHash; log(`A's pruning point left genesis at ${since()} s: ${String(d.pruningPointHash).slice(0, 8)} at DAA ${d.virtualDaaScore}, ${d.blockCount} blocks`); } + if (Date.now() - lastReport > 120000) { lastReport = Date.now(); log(`t=${since()} s A ${d.blockCount} blocks daa ${d.virtualDaaScore} pruning ${String(d.pruningPointHash).slice(0, 8)}${pruningMovedAt ? ' (moved)' : ''}`); } + if (pruningMovedAt && d.blockCount >= pruningMovedAt.blocks + MARGIN) break; +} +// --join-after: A's miner runs on this many blocks past the ready point (past the pool's 600-chain-block record +// window, so every proof B asks for must come from the peers' archives), then stops as before so B joins a still sink +if (JOIN_AFTER > 0) { + // past the pool's 600-chain-block record window, measured in DAA (one block a second here): the block count is the + // unpruned count and plateaus once the pruning point moves (seen on the pod, 7 October 2026, 13:4x UK) + const readyDaa = +(await a.dag()).virtualDaaScore; + const target = readyDaa + JOIN_AFTER; + log(`A ready at daa ${readyDaa}; mining on to daa ${target} (${JOIN_AFTER} past the ready point) before B joins`); + for (;;) { + const d = await a.rpc.call('getBlockDagInfo'); + if (+d.virtualDaaScore >= target) break; + await sleep(5000); + } +} +for (const f of RESUME_PIDS) { try { const pid = +readFileSync(f, 'utf8').trim(); if (pid > 1) { process.kill(pid, 'SIGINT'); log(`resume: stopped pid ${pid} from ${f}`); } } catch (e) { log(`resume: ${f}: ${e.message}`); } } +try { m?.kill('SIGINT'); } catch { } +try { prover?.kill('SIGINT'); } catch { } +await sleep(3000); +const aAtJoin = await a.dag(); +const aSinkHeader = await a.headerOf(aAtJoin.sink); +log(`A ready for the join: ${aAtJoin.blockCount} blocks, ${aAtJoin.headerCount} headers, daa ${aAtJoin.virtualDaaScore}, pruning point ${String(aAtJoin.pruningPointHash).slice(0, 8)}, sink ${String(aAtJoin.sink).slice(0, 8)} version ${aSinkHeader.version}`); +if (!pruningMovedAt) { log(`SUMMARY FAIL (expect ${EXPECT}): A's pruning point never left genesis in ${MAX_MINE} s; the chain is too short for a headers-proof join`); await stopAll(); process.exit(1); } + +// the fresh node (on a resume, B's directory from an earlier join is wiped so B joins fresh) +if (RESUME) rmSync(`${TMP}/n1`, { recursive: true, force: true }); +const b = await new Node(1, a.p2pPort).start(); +const tj = Date.now(); +let joined = null, proofLine = null, doneLine = null, lastJ = 0; +while (Date.now() - tj < WATCH * 1000) { + await sleep(5000); + const d = await b.dag().catch(() => null); + proofLine = proofLine || b.grepLog(/Starting IBD with headers proof/)[0] || null; + doneLine = doneLine || b.grepLog(/IBD with peer .* completed successfully/)[0] || null; + if (d && String(d.sink) === String(aAtJoin.sink) && joined == null) { joined = { t: (Date.now() - tj) / 1000, blocks: d.blockCount, headers: d.headerCount }; log(`B reached A's sink at ${joined.t} s after the join: ${d.blockCount} blocks, ${d.headerCount} headers`); } + if (Date.now() - lastJ > 30000) { lastJ = Date.now(); log(`t+${((Date.now() - tj) / 1000).toFixed(0)} s B ${d?.blockCount} blocks ${d?.headerCount} headers sink ${d ? String(d.sink).slice(0, 8) : '?'}; proof line ${proofLine ? 'yes' : 'no'}, done ${doneLine ? 'yes' : 'no'}`); } + if (joined && doneLine) break; +} +const bSinkVersion = joined ? (await b.headerOf(aAtJoin.sink).catch(() => null))?.version ?? null : null; +const errors = b.grepLog(/flow error|header version mismatch|wrong block version|completed with error/).slice(0, 5).map(l => l.replace(/^.*?\] /, '').slice(0, 200)); +const checks = { + pruning_point_moved: !!pruningMovedAt, + a_sink_signalling: aSinkHeader.version === 1026, + headers_proof_path_taken: !!proofLine, + ibd_completed: !!doneLine, + b_reached_a_sink: !!joined, + b_sink_version_1026: bSinkVersion === 1026, + no_version_refusal: !errors.some(e => /header version mismatch|wrong block version/.test(e)), +}; +const good = EXPECT === 'join' + ? Object.values(checks).every(Boolean) + : !(checks.b_reached_a_sink && checks.ibd_completed); +const summary = { pass: good, expect: EXPECT, window: WINDOW, pruning_depth: 4600, margin: MARGIN, threads: THREADS, a_at_join: { blocks: aAtJoin.blockCount, headers: aAtJoin.headerCount, daa: aAtJoin.virtualDaaScore, pruning: String(aAtJoin.pruningPointHash).slice(0, 16), sink: String(aAtJoin.sink).slice(0, 16), sink_version: aSinkHeader.version }, pruning_moved_at: pruningMovedAt, joined, proof_line: proofLine?.replace(/^.*?\] /, '').slice(0, 200) ?? null, done_line: doneLine?.replace(/^.*?\] /, '').slice(0, 200) ?? null, b_sink_version: bSinkVersion, b_errors: errors, checks, node: IGNEUMD, miner: CPU_MINER }; +mkdirSync(OUT.replace(/\/[^/]+$/, ''), { recursive: true }); +writeFileSync(OUT, JSON.stringify(summary, null, 2)); +try { copyFileSync(b.logFile, OUT.replace(/\.json$/, '-b-node.log')); } catch { } +const fails = Object.entries(checks).filter(([, v]) => !v).map(([k]) => k); +log(`SUMMARY ${good ? 'PASS' : 'FAIL'} (expect ${EXPECT}): A ${aAtJoin.blockCount} blocks at DAA ${aAtJoin.virtualDaaScore} with the pruning point moved at ${pruningMovedAt?.t} s, sink version ${aSinkHeader.version}; B ${proofLine ? 'took the headers-proof path' : 'did not take the headers-proof path'}, ${doneLine ? 'IBD completed' : 'IBD not completed'}, ${joined ? `reached A's sink at ${joined.t} s with ${joined.headers} headers` : 'did not reach the sink of A'}, sink version on B ${bSinkVersion}; B errors: ${errors.length}${fails.length ? `; FAILED CHECK ${fails.join(', ')}` : ''}`); +log(`summary: ${OUT}`); +await stopAll(); +process.exit(good ? 0 : 1); diff --git a/infra/fast-time/tn-prover-loop.mjs b/infra/fast-time/tn-prover-loop.mjs new file mode 100644 index 000000000..7c6363f18 --- /dev/null +++ b/infra/fast-time/tn-prover-loop.mjs @@ -0,0 +1,84 @@ +#!/usr/bin/env node +// A prover beside a fast-time node (the testnet genesis lane, 7 October 2026): every --every seconds it asks the node for +// the shards its key is assigned, takes the newest empty one it has not proved, exports the chain, cuts the fixture, +// proves the shard on the CPU (igneum-prove-host --mode compressed, SP1_PROVER=cpu), signs the record with the key and +// submits it with the proof bytes. Its records reach the node's blocks through the ordinary record flows, which is what +// the late-join gate needs: proofs carried by blocks that leave the pool's window before a joiner asks for them. +// +// IGNEUM_GRPC=grpc://127.0.0.1:P IGNEUM_EVM_RPC=http://127.0.0.1:Q node infra/fast-time/tn-prover-loop.mjs \ +// --label a-miner --chain igneum-devnet-997 [--every 20] [--window 100] [--tmp /tmp/tn-prover] +// IGNEUM_MINER, IGNEUM_PROVE_HOST, IGNEUM_PROVE_EXPORT name the binaries (the miner for key-hash and sign-record). +// +// One RESULT line per event (assigned, export, prove, submit, refused) with a UTC stamp; the loop never kills anything. + +import { spawnSync } from 'node:child_process'; +import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs'; + +const args = process.argv.slice(2); +const sflag = (name, dflt) => { const i = args.indexOf(`--${name}`); return i >= 0 ? args[i + 1] : dflt; }; +const LABEL = sflag('label', 'a-miner'); +const CHAIN = sflag('chain', 'igneum-devnet-997'); +const EVERY = +sflag('every', 20); +const WINDOW = +sflag('window', 100); +const TMP = sflag('tmp', '/tmp/tn-prover'); +const EVM = process.env.IGNEUM_EVM_RPC || 'http://127.0.0.1:30593'; +const MINER = process.env.IGNEUM_MINER; +const HOST = process.env.IGNEUM_PROVE_HOST; +const EXPORT = process.env.IGNEUM_PROVE_EXPORT; +const PAYOUT = '0x4242424242424242424242424242424242424242'; +const log = (...a) => console.log(new Date().toISOString(), ...a); +for (const b of [MINER, HOST, EXPORT]) if (!b || !existsSync(b)) { console.error(`missing binary: ${b}`); process.exit(2); } +mkdirSync(TMP, { recursive: true }); + +async function rpc(method, params) { + const r = await fetch(EVM, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }) }); + const j = await r.json(); + if (j.error) throw new Error(`${method}: ${JSON.stringify(j.error)}`); + return j.result; +} +function run(bin, argv, env = {}) { + const t = Date.now(); + const r = spawnSync(bin, argv, { encoding: 'utf8', env: { ...process.env, ...env }, maxBuffer: 1 << 28 }); + return { code: r.status, out: `${r.stdout || ''}${r.stderr || ''}`, secs: ((Date.now() - t) / 1000).toFixed(1) }; +} +const kh = run(MINER, ['key-hash', LABEL]); +const KEY_HASH = (kh.out.trim().split('\n').pop() || '').trim(); +if (!/^[0-9a-f]{64}$/.test(KEY_HASH)) { console.error(`key-hash ${LABEL}: ${kh.out}`); process.exit(2); } +log(`RESULT start label=${LABEL} key=${KEY_HASH} chain=${CHAIN} evm=${EVM} every=${EVERY}s window=${WINDOW}`); +const done = new Set(); +let proved = 0, refused = 0; +const sleep = (ms) => new Promise(r => setTimeout(r, ms)); +for (;;) { + try { + const work = await rpc('igneum_getAssignedShards', [[`0x${KEY_HASH}`], WINDOW]); + const mine = (work || []).filter(w => w.assigned && w.txCount === 0 && !w.paid && !done.has(`${w.number}/${w.shard}`)); + mine.sort((x, y) => parseInt(y.number, 16) - parseInt(x.number, 16)); + const target = mine[0]; + if (!target) { await sleep(EVERY * 1000); continue; } + const number = parseInt(target.number, 16); + done.add(`${target.number}/${target.shard}`); + log(`RESULT assigned number=${number} shard=${target.shard} listed=${work.length} mine=${mine.length}`); + const plan = await rpc('igneum_getShardPlan', [target.number]); + const seq = await rpc('igneum_exportSegments', ['0x0', target.number]); + writeFileSync(`${TMP}/seq.json`, JSON.stringify(seq)); + const fixture = `${TMP}/block-${number}.json`; + const ex = run(EXPORT, [`${TMP}/seq.json`, String(number), fixture, '--source', `tn late-join network block ${number}`]); + if (ex.code !== 0) { log(`RESULT export_failed number=${number} secs=${ex.secs} tail=${ex.out.split('\n').slice(-3).join(' | ').slice(0, 300)}`); continue; } + log(`RESULT export number=${number} secs=${ex.secs}`); + const results = `${TMP}/results-${number}-${target.shard}.json`; + const pr = run(HOST, [fixture, '--mode', 'compressed', '--shard', String(target.shard), '--prover', PAYOUT, '--out', results], { SP1_PROVER: 'cpu', RUST_LOG: 'off' }); + writeFileSync(`${TMP}/prove-${number}-${target.shard}.log`, pr.out); + if (pr.code !== 0) { log(`RESULT prove_failed number=${number} secs=${pr.secs} tail=${pr.out.split('\n').filter(l => /RESULT|rror/.test(l)).slice(-3).join(' | ').slice(0, 400)}`); continue; } + const res = JSON.parse(readFileSync(results, 'utf8')); + log(`RESULT prove number=${number} shard=${target.shard} secs=${pr.secs} cycles=${res.cycles} proof_bytes=${res.compressed_proof_bytes}`); + const sg = run(MINER, ['sign-record', LABEL, CHAIN, plan.hash, String(number), String(target.shard), PAYOUT, res.statement, res.proof_sha256]); + if (sg.code !== 0) { log(`RESULT sign_failed number=${number} out=${sg.out.slice(0, 300)}`); continue; } + const signed = JSON.parse(sg.out.trim().split('\n').pop()); + const proofHex = '0x' + readFileSync(res.proof_file).toString('hex'); + const sub = await rpc('igneum_submitProofRecord', [{ record: signed.record, proof: proofHex }]); + if (sub.accepted) { proved++; log(`RESULT submit number=${number} shard=${target.shard} accepted proved_total=${proved}`); } else { refused++; log(`RESULT refused number=${number} shard=${target.shard} reason=${sub.reason} refused_total=${refused}`); } + } catch (e) { + log(`RESULT error ${String(e.message || e).slice(0, 300)}`); + await sleep(EVERY * 1000); + } +} diff --git a/infra/seed-nodes/testnet-object.json b/infra/seed-nodes/testnet-object.json new file mode 100644 index 000000000..a1823aac5 --- /dev/null +++ b/infra/seed-nodes/testnet-object.json @@ -0,0 +1,163 @@ +{ + "timestamp_deviation_tolerance": 132, + "past_median_time_window_size": 27, + "difficulty_window_size": 661, + "min_difficulty_window_size": 150, + "difficulty_rule": "igneum-dual", + "coinbase_payload_script_public_key_max_len": 150, + "max_coinbase_payload_len": 16384, + "max_tx_inputs": 1000, + "max_tx_outputs": 1000, + "max_signature_script_len": 250000, + "max_script_public_key_len": 10000, + "mass_per_tx_byte": 1, + "mass_per_script_pub_key_byte": 10, + "mass_per_sig_op": 1000, + "block_mass_limits": { + "storage": 500000, + "compute": 500000, + "transient": 1000000 + }, + "block_lane_limits": { + "lanes_per_block": 50, + "gas_per_lane": 1000000000 + }, + "storage_mass_parameter": 1000000000000, + "deflationary_phase_daa_score": 0, + "pre_deflationary_phase_base_subsidy": 50000000000, + "skip_proof_of_work": false, + "max_block_level": 250, + "pruning_proof_m": 1000, + "blockrate": { + "target_time_per_block": 1000, + "ghostdag_k": 18, + "past_median_time_sample_rate": 10, + "difficulty_sample_rate": 4, + "max_block_parents": 10, + "mergeset_size_limit": 180, + "merge_depth": 3600, + "finality_depth": 43200, + "pruning_depth": 108000, + "coinbase_maturity": 100 + }, + "pre_crescendo_target_time_per_block": 1000, + "crescendo_activation": 0, + "genesis_bits": 487587840, + "finality": { + "checkpoint_interval": 30, + "checkpoint_depth": 60, + "weight_window": 2592000, + "dust": 100, + "presence_window": 240, + "aggregators": 8, + "equivocation_ban": 2592000, + "min_daa": 2592000, + "aggregator_fallback": 15, + "certificate_fold": 6, + "leave_delay": 3600 + }, + "pow_epoch_blocks": 3600, + "pow_epoch_lead": 600, + "pow_day_ms": 86400000, + "difficulty_v2_activation_daa": 0, + "difficulty_v3_activation_daa": 0, + "proving_v0_activation_daa": 0, + "finality_v3_activation_daa": 0, + "finality_daa_rule_activation_daa": 0, + "fork_gate_activation_daa": 18446744073709551615, + "fork_gate_window_daa": 600, + "peer_directory_activation_daa": 18446744073709551615, + "subsidy_per_block_activation_daa": 0, + "signing_bonus_activation_daa": 0, + "signing_bonus_bps": 1000, + "finality_leave_activation_daa": 0, + "program_class_v3_activation_daa": 0, + "program_class_v4_activation_daa": 0, + "program_class_v4_signal_window_daa": 86400, + "base_unit_decimals": 18, + "program_class_v5_activation_daa": 0, + "pow_genesis_dataset_log2": 28, + "latency_ladder": [ + { + "reps": 27, + "admissible": true + }, + { + "reps": 35, + "admissible": true + }, + { + "reps": 53, + "admissible": true + }, + { + "reps": 88, + "admissible": false + }, + { + "reps": 173, + "admissible": false + }, + { + "reps": 267, + "admissible": false + } + ], + "latency_ladder_activation_daa": 0, + "latency_ladder_window_daa": 86400, + "latency_ladder_cache_rung": { + "mib": 512, + "admissible": false + }, + "latency_ladder_cache_rung_activation_daa": 0, + "sig_scheme": 0, + "sig_scheme_activation_daa": 0, + "finality_succession_activation_daa": 0, + "pow_era_blocks": 15552000, + "pow_era_lead": 7200, + "era_vdf_activation_daa": 0, + "vdf_scheme": 0, + "era_vdf_t": 108000000, + "fees": { + "pgas": { + "version": 1, + "cycles_per_pgas": 1000, + "intrinsic_pgas_per_tx": 300, + "modexp_base": 10, + "modexp_per_byte_numer": 1, + "modexp_per_byte_denom": 10 + }, + "block_proving_gas_limit": 120000, + "shard_proving_gas_budget": 30000, + "min_execution_base_fee_wei": 100000000000, + "min_proving_base_fee_wei": 10000000000000, + "initial_execution_base_fee_wei": 100000000000, + "initial_proving_base_fee_wei": 10000000000000, + "base_fee_change_denominator": 8 + }, + "fees_v1_activation_daa": 0, + "proving_v1_activation_daa": 0, + "proving_v1_segment_blocks": 8, + "proving_v1_unproven_daa": 600, + "proving_v1_aggregator_share_bps": 1000, + "proving_v1_fresh_rule_daa": 0, + "pool_split_activation_daa": 18446744073709551615, + "exec_restart_number": 18446744073709551615, + "exec_restart_hash": "", + "exec_restart_trust_daa": 18446744073709551615, + "exec_restart_state_root": "", + "emission": { + "launch_rate": "100000000000000000000", + "ramp_seconds": 7776000, + "ramp_start_percent": 10, + "step_seconds": 2629800, + "step_decay_q32": 4172697914, + "tail": { + "kind": "percent", + "bps_per_year": 100 + } + }, + "proving_consensus_verify_daa": 0, + "proving_shard_program_id": "0x2b1a81cb413236cf063077b46ed3111628f6c41036bcf6e23ee4cbbf5679ef7a", + "proving_aggregator_id": "0x474678f35f7545db28055d5e5bbc308231d84a5a072202087a2a8d5b09123896" +} diff --git a/site/404.html b/site/404.html index de511b685..fb8ed730e 100644 --- a/site/404.html +++ b/site/404.html @@ -130,6 +130,7 @@ main{flex:1} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet. @@ -167,6 +168,7 @@ main{flex:1} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/address.html b/site/address.html index 142f773c4..618b1aa85 100644 --- a/site/address.html +++ b/site/address.html @@ -170,6 +170,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -207,6 +208,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/app.html b/site/app.html index 78d8cb5bc..45c66efcc 100644 --- a/site/app.html +++ b/site/app.html @@ -138,6 +138,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -175,6 +176,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/block.html b/site/block.html index 360f8493d..d565f981b 100644 --- a/site/block.html +++ b/site/block.html @@ -170,6 +170,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -207,6 +208,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/build.html b/site/build.html index ec0c048b7..1e57ba252 100644 --- a/site/build.html +++ b/site/build.html @@ -143,6 +143,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -180,6 +181,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/build.mjs b/site/build.mjs index c34c73ef7..e27884e67 100644 --- a/site/build.mjs +++ b/site/build.mjs @@ -226,7 +226,8 @@ let built = []; // files of docs/build/ (the walkthrough, the RPC list, the faucet, the verifier) are linked from /build on the git host. for (const [src, file, title, desc, heading, lead, eyebrow] of [ ['build.md', 'build.html', 'Build on Igneum: chain ids, RPC, a contract in five minutes', 'The developer entry page for Igneum: what is different, the chain ids and RPC endpoints, the wallet, the explorer, the faucet, a five-minute contract deploy and a block you verify in your browser.', 'Build on Igneum', 'Built to prove every block. A lock in minutes. Nothing to stake. The EVM you already know: Solidity deploys unchanged. Here are the chain ids, the endpoints and a contract in five minutes.', 'Developers'], - ['grants.md', 'grants.html', 'Igneum grants: tooling, reference apps, infrastructure, research', 'The Igneum grants programme: four tiers, what a grant is, how to apply with an issue on the git host, the weekly review, and the lines that stay honest about value, amounts and dates.', 'Grants', 'Paid in IGN from the dev fee fund, on delivery, on the devnet first. Four tiers. One issue to apply. A weekly review.', 'The programme'], + ['grants.md', 'grants.html', 'Igneum grants: tooling, reference apps, infrastructure, research', 'The Igneum grants programme: four tiers, what a grant is, how to apply with an issue on the git host, the weekly review, and the lines that stay honest about value, amounts and dates.', 'Grants', 'Paid in IGN from the dev fee fund, on delivery, on the Igneum 2.0 devnet first. Four tiers. One issue to apply. A weekly review.', 'The programme'], + ['compatibility.md', 'compatibility.html', 'Igneum compatibility, measured: every row a test run against the devnet', 'Compatibility as a product deliverable: representative contracts, wallet fee estimation, indexing, failed transactions, receipts, application assumptions and the measured differences (block context, randomness, two-dimensional fees), each a test with its evidence. Devnet, no value.', 'Compatibility, measured', 'Every row is a test that ran against the devnet, with its evidence; a row that could not run says why.', 'Build · compatibility'], ]) { const mdp = join(docs, 'build', src); if (!existsSync(mdp)) continue; // the gate builds a copy of site/ alone: the committed page stands diff --git a/site/claims.html b/site/claims.html index 509a43aee..956910ff7 100644 --- a/site/claims.html +++ b/site/claims.html @@ -142,6 +142,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -179,6 +180,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/compatibility.html b/site/compatibility.html new file mode 100644 index 000000000..224d60164 --- /dev/null +++ b/site/compatibility.html @@ -0,0 +1,362 @@ + + + + + +Igneum compatibility, measured: every row a test run against the devnet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ +
Build · compatibility
+

Compatibility, measured

+

Every row is a test that ran against the devnet, with its evidence; a row that could not run says why.

+
+
+
+ +
+ +

Compatibility, measured

+

A GPU-secured network for Ethereum-compatible applications and verifiable computation. Compatibility is a product deliverable here, not a sentence: every row below is a test that ran against the devnet from the repository (tools/reference-apps/compat/run.mjs), with its evidence, and a row that could not run says so and why. Devnet, no value.

+

Last run: not run yet. 0 passed, 0 failed, 0 untested. Sender none.

+

Three boundaries hold for everything on this page: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. The four words included, executed, proven and finalised are defined on /receipt.

+
+

Representative contracts

+
RowVerdictWhat was measuredEvidence
an ERC-20 deploys (CREATE address, code at the address)untestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
ERC-20 transfer: balances, the Transfer log, eth_calluntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
ERC-20 approve and transferFromuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
a probe contract deploysuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
a counter increments and persistsuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Wallet fee estimation

+
RowVerdictWhat was measuredEvidence
eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory shapesuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
a transfer: estimateGas against gasUseduntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
a contract call: estimateGas against gasUseduntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
the documented difference: a transfer sent with a local 21,000 limituntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Indexing

+
RowVerdictWhat was measuredEvidence
eth_getLogs by address, topic and range against the receiptsuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
block, receipts and transaction lookups agree on indicesuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Failed transactions

+
RowVerdictWhat was measuredEvidence
a revert: status 0, gas charged, nonce advanced, eth_call reasonuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
an out-of-gas calluntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Receipts

+
RowVerdictWhat was measuredEvidence
every Ethereum field, logsBloom from the logs, contractAddress on creationuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
the receipts trie root rebuilt equal to the headeruntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Application assumptions

+
RowVerdictWhat was measuredEvidence
block.number, timestamp, chainid, basefee, blockhash(n-1), msg.sender, tx.originuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
CREATE2 addressuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Differences: block context

+
RowVerdictWhat was measuredEvidence
block.coinbase is the including DAG block's mineruntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Differences: randomness

+
RowVerdictWhat was measuredEvidence
block.prevrandao derives from the epoch seed, fixed per epochuntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

Differences: two-dimensional fees

+
RowVerdictWhat was measuredEvidence
the receipt's proving dimension and the fee splituntestednot run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet
+
+

What the differences mean for an application

+
  • Block context: block.coinbase is the miner of the DAG block that first included the transaction, so one chain block can carry transactions with different coinbases; code that pays or trusts block.coinbase as "the block producer" sees several producers per block.
  • Randomness: block.prevrandao derives from the chain's epoch seed and holds for an epoch, so it is not fresh per block and must not seed a lottery or a commitment; use an application-level randomness source.
  • Two-dimensional fees: every transaction pays execution gas and proving gas; the node folds the second into the gas it quotes, so a wallet that quotes from the node (eth_estimateGas, eth_gasPrice, eth_feeHistory) is covered and a wallet with Ethereum's constants (21,000 for a transfer) is not; the receipt carries the split under igneum (pgasUsed, provingBaseFeePerGas, burnedProvingFee, burnedExecutionBaseFee, minerTip).
+

Source: tools/reference-apps/compat/run.mjs (the rows), tools/reference-apps/compat/results.json (the evidence), docs/build/compatibility.md (this page, rendered by render.mjs).

+
+

Generated from docs/build/compatibility.md in the repository at build time. Times are UTC.

+
+
+ + + + + + + + \ No newline at end of file diff --git a/site/dev-fee.html b/site/dev-fee.html index 471e192e4..06880461d 100644 --- a/site/dev-fee.html +++ b/site/dev-fee.html @@ -142,6 +142,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -179,6 +180,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/download.html b/site/download.html index 685bf6d71..6250e333e 100644 --- a/site/download.html +++ b/site/download.html @@ -132,6 +132,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -169,6 +170,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/economics.html b/site/economics.html index e67e97f04..d01a65f21 100644 --- a/site/economics.html +++ b/site/economics.html @@ -116,6 +116,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -153,6 +154,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/evidence.html b/site/evidence.html index c919cb746..1c2e8b3aa 100644 --- a/site/evidence.html +++ b/site/evidence.html @@ -153,6 +153,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -190,6 +191,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/explorer.html b/site/explorer.html index 67d8a7bbe..64730e892 100644 --- a/site/explorer.html +++ b/site/explorer.html @@ -169,6 +169,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -206,6 +207,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/faucet.html b/site/faucet.html index f26b615f5..3835141bb 100644 --- a/site/faucet.html +++ b/site/faucet.html @@ -146,6 +146,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:14px;overflo Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -183,6 +184,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:14px;overflo Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/grants.html b/site/grants.html index b7d5671e4..45cde08d6 100644 --- a/site/grants.html +++ b/site/grants.html @@ -143,6 +143,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -180,6 +181,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download @@ -240,7 +242,7 @@ table{min-width:560px}
The programme

Grants

-

Paid in IGN from the dev fee fund, on delivery, on the devnet first. Four tiers. One issue to apply. A weekly review.

+

Paid in IGN from the dev fee fund, on delivery, on the Igneum 2.0 devnet first. Four tiers. One issue to apply. A weekly review.

diff --git a/site/income.html b/site/income.html index 7245cc9c4..8f6cba381 100644 --- a/site/income.html +++ b/site/income.html @@ -116,6 +116,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -153,6 +154,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/index.html b/site/index.html index 6ed0a5d97..5543a1b68 100644 --- a/site/index.html +++ b/site/index.html @@ -134,6 +134,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -171,6 +172,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/ledger.html b/site/ledger.html index 11fb9ae87..0d0381bc4 100644 --- a/site/ledger.html +++ b/site/ledger.html @@ -147,6 +147,7 @@ blockquote{margin:10px 0;padding:10px 14px;border-left:3px solid var(--line-2);c Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -184,6 +185,7 @@ blockquote{margin:10px 0;padding:10px 14px;border-left:3px solid var(--line-2);c Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/light.html b/site/light.html index 16a0a744b..ab518c0d7 100644 --- a/site/light.html +++ b/site/light.html @@ -150,6 +150,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -187,6 +188,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download @@ -247,6 +249,7 @@
Reference app 1 · the devnet, no value

A balance verified in your browser, trust stated.

+

A GPU-secured network for Ethereum-compatible applications and verifiable computation. Devnet, no value.

Paste a devnet address. This tab fetches the latest finality certificate, the header chain, the carrier block's coinbase, the segment record and an account proof from a read service, then recomputes every link itself: BLS over the checkpoint, every header hash and parent link, the merkle path, the aggregator's signature, the Merkle Patricia proof under the committed state root. This is a verification path with stated trust assumptions, listed below; it is not a browser that needs no trusted inputs. The read service cannot change what those inputs commit to. It can only refuse to answer.

Trusted inputs, stated

  • The voter table with weights comes from the node (no header field commits to it yet; spec 10.1). A node that lies about the table could present a different set of signers.
  • @@ -255,7 +258,7 @@
-

Why this only works on a proven chain. Account proofs exist on Ethereum too; what differs here is how the state root is authenticated. The root comes from a segment record an aggregator signed inside a block after proving the segment's execution, which nodes check against their own execution before paying, under a finality certificate the miners signed. The page states what that chain rests on.

+

Why this only works on a proven chain. Three boundaries hold wherever the proof architecture is explained: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. Account proofs exist on Ethereum too; what differs here is how the state root is authenticated. The root comes from a segment record an aggregator signed inside a block after proving the segment's execution, which nodes check against their own execution before paying, under a finality certificate the miners signed. The page states what that chain rests on.

Source: site/lc/core.js (the checks), site/lc/app.js (this page), tools/reference-apps/light-service/serve.mjs (the read service), fork branch light-apps-node (eth_getProof on the node). Test with the negative cases: /lc/test in the browser, tools/reference-apps/light-service/verify.test.mjs under Node.

diff --git a/site/litepaper.html b/site/litepaper.html index 28cd9a945..5d7cb94b0 100644 --- a/site/litepaper.html +++ b/site/litepaper.html @@ -199,6 +199,7 @@ body.all .pager{display:none} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet. @@ -236,6 +237,7 @@ body.all .pager{display:none} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/live.html b/site/live.html index 092dcd1c2..e5a88e234 100644 --- a/site/live.html +++ b/site/live.html @@ -283,6 +283,7 @@ details.tablebar summary{display:flex;align-items:center} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -320,6 +321,7 @@ details.tablebar summary{display:flex;align-items:center} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/metamask.html b/site/metamask.html index c171e8409..e81f4c523 100644 --- a/site/metamask.html +++ b/site/metamask.html @@ -144,6 +144,7 @@ ol{margin:0 0 14px;padding-left:22px}li{margin-bottom:6px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -181,6 +182,7 @@ ol{margin:0 0 14px;padding-left:22px}li{margin-bottom:6px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/miner.html b/site/miner.html index cb0665aa0..989d9b4c6 100644 --- a/site/miner.html +++ b/site/miner.html @@ -139,6 +139,7 @@ pre b{color:var(--molten-text);font-weight:500} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -176,6 +177,7 @@ pre b{color:var(--molten-text);font-weight:500} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/miners.html b/site/miners.html index 27acb388d..2315d8d10 100644 --- a/site/miners.html +++ b/site/miners.html @@ -143,6 +143,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -180,6 +181,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/oracle.html b/site/oracle.html index 2571ea0b7..015e3d8d2 100644 --- a/site/oracle.html +++ b/site/oracle.html @@ -150,6 +150,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -187,6 +188,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download @@ -247,11 +249,12 @@
Reference app 3 · the devnet, no value

Devnet balances, read from Sepolia.

-

A contract on Ethereum Sepolia stores Igneum 2.0 devnet finality certificates that anyone submits, checked by a shared certificate verifier, and state roots bound to those checkpoints through the header chain, the coinbase and the segment record. Other contracts then read a proven devnet balance or storage slot with an ordinary Merkle Patricia proof. No relayer is trusted: a wrong certificate or a wrong proof reverts.

+

A GPU-secured network for Ethereum-compatible applications and verifiable computation. Devnet, no value.

+

A contract on Ethereum Sepolia stores Igneum 2.0 devnet finality certificates that anyone submits, checked by a shared certificate verifier, and state roots bound to those checkpoints through the header chain, the coinbase and the segment record. Other contracts then read a proven the devnet balance or storage slot with an ordinary Merkle Patricia proof. No relayer is trusted: a wrong certificate or a wrong proof reverts.

-

Why this only works on a proven chain. Another chain can only use Igneum state if a contract can check it without running an Igneum node: a weighted certificate over a checkpoint and a state root proven under it are small enough to verify in a few hundred thousand gas. A chain whose state is only "what most nodes say" has nothing a contract can check.

-

Source: tools/reference-apps/oracle/contracts/ (IgneumStateOracle.sol and its libraries), tools/reference-apps/oracle/demo.mjs (the demo that reads a devnet balance from Sepolia), tools/reference-apps/oracle/test.mjs (the negative cases through eth_call). The shared certificate verifier is the DEX lane's contracts/bridge/src/IgneumCertificateVerifier.sol.

+

Why this only works on a proven chain. Three boundaries hold wherever the proof architecture is explained: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. Another chain can only use Igneum state if a contract can check it without running an Igneum node: a weighted certificate over a checkpoint and a state root proven under it are small enough to verify in a few hundred thousand gas. A chain whose state is only "what most nodes say" has nothing a contract can check.

+

Source: tools/reference-apps/oracle/contracts/ (IgneumStateOracle.sol and its libraries), tools/reference-apps/oracle/demo.mjs (the demo that reads a the devnet balance from Sepolia), tools/reference-apps/oracle/test.mjs (the negative cases through eth_call). The shared certificate verifier is the DEX lane's contracts/bridge/src/IgneumCertificateVerifier.sol.

diff --git a/site/partials/nav.html b/site/partials/nav.html index 91bfc2cce..81690eeca 100644 --- a/site/partials/nav.html +++ b/site/partials/nav.html @@ -58,6 +58,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet. @@ -95,6 +96,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/provenance.html b/site/provenance.html index a111c9d7a..674190689 100644 --- a/site/provenance.html +++ b/site/provenance.html @@ -143,6 +143,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -180,6 +181,7 @@ table{min-width:560px} Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/proving.html b/site/proving.html index c0ad09b39..961203d17 100644 --- a/site/proving.html +++ b/site/proving.html @@ -169,6 +169,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -206,6 +207,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/randomx.html b/site/randomx.html index 366e99e61..4ad928c1a 100644 --- a/site/randomx.html +++ b/site/randomx.html @@ -142,6 +142,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -179,6 +180,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/receipt.html b/site/receipt.html index 20fd74ea1..df2fa756b 100644 --- a/site/receipt.html +++ b/site/receipt.html @@ -148,6 +148,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -185,6 +186,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download @@ -245,6 +247,7 @@
Reference app 2 · the devnet, no value

A receipt any third party re-verifies.

+

A GPU-secured network for Ethereum-compatible applications and verifiable computation. Devnet, no value.

Paste a devnet transaction hash. This tab fetches the raw transaction, the including block's merkle path, every header up to the certified checkpoint and the certificate, then proves inclusion and finality itself. Download the receipt as JSON. Anyone checks it later with a one-file verifier, offline, with no node and no network. Test with the negative cases: tools/reference-apps/light-service/verify.test.mjs (eight payment cases, nine inclusion cases).

Which receipt this is

  • The page issues one of two receipts and names it on the result, in the file (field kind) and in the offline verifier's output.
  • @@ -253,7 +256,7 @@
-

Why this only works on a proven chain. A merchant's receipt is only worth something if the payment cannot be undone and the proof of that fits in a file: here the certificate is a weighted BLS signature by the miners over a checkpoint, and the block holding the payment hashes into that checkpoint's past. On a chain with probabilistic finality a receipt is a guess that ages well; here it is a fact that a file carries.

+

Why this only works on a proven chain. Three boundaries hold wherever the proof architecture is explained: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. A merchant's receipt is only worth something if the payment cannot be undone and the proof of that fits in a file: here the certificate is a weighted BLS signature by the miners over a checkpoint, and the block holding the payment hashes into that checkpoint's past. On a chain with probabilistic finality a receipt is a guess that ages well; here it is a fact that a file carries.

Source: site/lc/core.js (the checks), site/lc/app.js (this page), tools/reference-apps/receipt/verify-receipt.src.mjs (the one-file verifier, bundled to /lc/verify-receipt.js). Test with the negative cases: /lc/test in the browser, tools/reference-apps/light-service/verify.test.mjs under Node.

diff --git a/site/scenes.html b/site/scenes.html index 69a86d4ec..85ed60f1b 100644 --- a/site/scenes.html +++ b/site/scenes.html @@ -134,6 +134,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet. @@ -171,6 +172,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/sitemap.xml b/site/sitemap.xml index ca92f5a37..286151c47 100644 --- a/site/sitemap.xml +++ b/site/sitemap.xml @@ -23,4 +23,5 @@ https://igneum.network/build2026-10-08weekly0.8 https://igneum.network/swap2026-10-08weekly0.5 https://igneum.network/grants2026-10-08monthly0.6 + https://igneum.network/compatibility2026-10-08weekly0.6 diff --git a/site/swap.html b/site/swap.html index dd6777f43..334f46ab6 100644 --- a/site/swap.html +++ b/site/swap.html @@ -153,6 +153,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:13px;overflo Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -190,6 +191,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:13px;overflo Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/tx.html b/site/tx.html index d97e147f5..0e9a33b83 100644 --- a/site/tx.html +++ b/site/tx.html @@ -170,6 +170,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -207,6 +208,7 @@ main{padding-bottom:100px}.card{background:var(--row);border:1px solid var(--lin Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/site/wallet.html b/site/wallet.html index 411c44e1a..0adabb592 100644 --- a/site/wallet.html +++ b/site/wallet.html @@ -152,6 +152,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
@@ -189,6 +190,7 @@ Devnet faucet10 IGN of devnet coin, once a day. SwapTest tokens on the devnet; every swap is a proven block. GrantsTooling, apps, infrastructure, research. + CompatibilityEvery row a test run against the devnet.
Download diff --git a/tools/ci/export-exclude.txt b/tools/ci/export-exclude.txt index e4dcf3b6c..7d129a73b 100644 --- a/tools/ci/export-exclude.txt +++ b/tools/ci/export-exclude.txt @@ -32,3 +32,5 @@ docs/analysis/class-v6/coexistence-model.md # 8 October 2026: the public shape of the pre-2.0 ledger, kept as history at the Igneum 2.0 reset (not served, not linked; # docs/ledger-public.md is now generated from docs/fud-ledger-2.0.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 diff --git a/tools/ci/never-served-check.mjs b/tools/ci/never-served-check.mjs new file mode 100644 index 000000000..b22ce52fb --- /dev/null +++ b/tools/ci/never-served-check.mjs @@ -0,0 +1,30 @@ +// Never-served check (the Igneum 2.0 plan, 8 October 2026): the served pages never carry guaranteed chip death, a universal +// ASIC-efficiency ceiling, a chip-arrival probability, a guaranteed profit, Ethereum security by compatibility, privacy from +// ZK, a numerical rank, or the revenue thresholds the coexistence workbook holds (USD 340 M, USD 23 M, USD 20 to 75 M). +// node tools/ci/never-served-check.mjs exit 1 listing every hit (self-test first: a known-failed fixture per pattern) +import { readFileSync, readdirSync } from 'node:fs'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +const site = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'site'); +const RULES = [ + ['guaranteed chip death', /\b(every|each|any) chip (dies|will die|must die)\b|chips? (is|are) guaranteed to (die|expire)|guaranteed (chip|ASIC) death/i], + ['a universal ASIC-efficiency ceiling', /\buniversal (ASIC|chip)[- ]?(efficiency )?ceiling\b|\bno chip can ever\b/i], + ['a chip-arrival probability', /\b\d+ percent (chance|probability|odds) (of|that) (a |an )?(chip|ASIC)|\bprobability (of|that) (a |an )?(chip|ASIC) (arrives|arriving|ships|appears)|\bchip-arrival probabilit/i], + ['a guaranteed profit', /\bguaranteed (profit|profits|return|returns|income|earnings)\b/i], + ['Ethereum security by compatibility', /\b(inherits|inherit|gets|gives|with) Ethereum'?s? security\b|\bEthereum security (by|through|from) compatibility\b/i], + ['privacy from ZK', /\b(ZK|zero-knowledge) (makes|keeps|gives|means) (it |transactions |everything )?(private|privacy)\b|\bprivate (by|through) (ZK|zero-knowledge)\b/i], + ['a numerical rank', /\bnumber one\b|\b(the )?#1\b|\bno\. 1\b/i], + ['a workbook threshold served as a boundary', /USD 340 ?M\b|USD 23 ?M\b|USD 20 to 75 ?M\b/], +]; +const text = (html) => html.replace(/|/g, ' ').replace(/<[^>]+>/g, ' ').replace(/&[a-z]+;|&#\d+;/g, ' '); +const scan = (name, html) => { const t = text(html); const hits = []; for (const [what, re] of RULES) { const m = re.exec(t); if (m) hits.push(`${name}: ${what} ("${t.slice(Math.max(0, m.index - 40), m.index + m[0].length + 40).replace(/\s+/g, ' ').trim()}")`); } return hits; }; +// self-test: a known-failed fixture per rule, then a clean one +const fixtures = ['every chip dies within a year', 'a universal ASIC-efficiency ceiling of 2x', 'a 30 percent chance of a chip by 2027', 'guaranteed profits for miners', 'the chain inherits Ethereum security', 'ZK makes transactions private', 'the number one GPU chain', 'the capex wall at USD 340 M']; +let bad = 0; +fixtures.forEach((f, i) => { if (!RULES[i][1].test(f)) { console.error(`self-test: rule ${i} missed "${f}"`); bad++; } }); +if (scan('clean', '

A GPU-secured network for Ethereum-compatible applications and verifiable computation. ZK is not privacy. EVM compatibility is not Ethereum security.

').length) { console.error('self-test: the clean fixture was flagged'); bad++; } +if (bad) process.exit(1); +const hits = []; +for (const f of readdirSync(site).filter(f => f.endsWith('.html'))) hits.push(...scan(f, readFileSync(join(site, f), 'utf8'))); +if (hits.length) { console.error(`never-served check: ${hits.length} hit(s)\n ${hits.join('\n ')}`); process.exit(1); } +console.log(`never-served check: ${RULES.length} rules, self-test passed, no hit on the served pages`); diff --git a/tools/ci/site-nav-check.mjs b/tools/ci/site-nav-check.mjs index e52927f1a..3810dc510 100644 --- a/tools/ci/site-nav-check.mjs +++ b/tools/ci/site-nav-check.mjs @@ -16,7 +16,7 @@ const GROUPS = { mine: ['/miner', '/download', '/app', '/wallet', '/miners', '/dev-fee', '/metamask'], network: ['/live', '/explorer', '/evidence', '/light', '/receipt', '/oracle'], learn: ['/litepaper', '/income', '/economics', '/ledger', '/claims', '/randomx', '/provenance'], - build: ['/build', '/faucet', '/swap', '/grants'], // the builder programme (8 October 2026): the developer entry page, the Devnet 3 faucet, the swap, the grants + build: ['/build', '/faucet', '/swap', '/grants', '/compatibility'], // the builder programme (8 October 2026): the developer entry page, the Devnet 3 faucet, the swap, the grants }; const ROUTES = Object.values(GROUPS).flat(); // pages served without their own panel entry: the explorer's three rewrites (block, address, tx), its proving view, the 404 and the unlinked scenes lab diff --git a/tools/fleet/base-unit-gate.sh b/tools/fleet/base-unit-gate.sh new file mode 100755 index 000000000..027a1918b --- /dev/null +++ b/tools/fleet/base-unit-gate.sh @@ -0,0 +1,181 @@ +#!/usr/bin/env bash +# B10 of the base-unit widening (O-2.6, docs/design/base-unit.md section 8): two nodes on the testnet params (18 decimals) +# mine for N seconds on one box, then the coinbase, the gRPC and the execution layer must read one number. +# +# Runs ON igneum-build-1 (ssh build@188.40.146.49 'bash -s' < tools/fleet/base-unit-gate.sh [seconds]), against the +# binaries of the decimals worktree's fork (target/release of /srv/builds/igneum-wt-decimals/vendor/igneum-node-decimals). +# Ports 28110 to 28191 (nothing else on the box uses them); data under /srv/builds/_gate-decimals, wiped at the start; the +# processes it starts are the only ones it stops (a pid file each, never a pattern). PASS is the last line. +# +# What it checks (each a FAIL line otherwise): +# 1. both nodes answer and B reaches the same sink and block count as A (the p2p wire carries the wide amounts) +# 2. at least MIN_BLOCKS blocks were mined +# 3. igneum-miner inspect over the last 30 blocks: every coinbase's payload subsidy is above u64::MAX (18 decimals), +# the outputs split 80/20 exactly (the UTXO side), identical on both nodes +# 4. the execution layer: eth_getBalance of the miner's EVM address is equal on both nodes and equals the sum of the +# producer shares the segments paid (igneum_getSegment over every chain block), which is the identity bridge +# 5. every reward in a segment equals producer_share(block_subsidy(daa of the rewarded block itself)) under the testnet +# schedule at 18 decimals (100 IGN a second, the 90-day ramp from 10%), computed here in exact integers (each merged +# block its own DAA: subsidy_per_block_activation_daa 0 on the testnet since the re-cut of 7 October 2026) +# +# CPU note (7 October 2026, 01:5x UK): the testnet genesis bits are 2^28 expected hashes a block and the box's CPU engine +# does 0.147 MH/s on 32 threads, so a block takes 10 to 30 minutes on CPU; the ten-minute, hundreds-of-blocks form of +# this gate needs a GPU wave box (the fleet lane's); on the box alone run it for an hour with MIN_BLOCKS=3. +# +# The nodes run --nodnsseed: a gate never dials the public testnet seeds (the pod run of 8 October 2026 did, and was refused on +# the digest; harmless, and wrong). +# A fresh chain is never "synced" by the mining rule (its sink is the two-day-old genesis), so both nodes run with +# --enable-unsynced-mining, as a devnet's first node does; without it every found block is Reject(IsInIBD) (seen 00:2x UK). +# +# Known-failed case: run with GATE_EXPECT_DECIMALS=8 against the same nodes and check 3 and 5 fail (the schedule at 8 +# does not match an 18-decimal chain). The self-test target below does that on the recorded output. +set -euo pipefail +SECS="${1:-600}"; MIN_BLOCKS="${MIN_BLOCKS:-60}"; THREADS="${THREADS:-48}" +BIN="${BIN:-/srv/builds/igneum-wt-decimals/vendor/igneum-node-decimals/target/release}" +ROOT="${ROOT:-/srv/builds/_gate-decimals}"; A_RPC=28110; A_P2P=28111; A_EVM=28190; B_RPC=28120; B_P2P=28121; B_EVM=28191 +# WORKER=: the GPU form (a wave box; the fleet lane rents it): the first +# pack is exported from node A, the worker serves it and the miner prepares the next seeds; THREADS is then ignored +WORKER="${WORKER:-}" +EVM_ADDR="00000000000000000000000000000000000000aa" +fail=0 +say() { echo "$(date -u +%H:%M:%SZ) gate: $*"; } +die() { say "FAIL: $*"; fail=1; } +stop_all() { + for p in "$ROOT"/*.pid; do [ -f "$p" ] && kill "$(cat "$p")" 2>/dev/null || true; done + sleep 2 +} +trap stop_all EXIT +rm -rf "$ROOT"; mkdir -p "$ROOT/a" "$ROOT/b" +[ -x "$BIN/igneumd" ] && [ -x "$BIN/igneum-miner" ] || { echo "FAIL: binaries missing in $BIN"; exit 2; } + +say "starting node A (testnet params, 18 decimals)" +"$BIN/igneumd" --testnet --netsuffix=1 --nodnsseed --enable-unsynced-mining --appdir="$ROOT/a" --listen=127.0.0.1:$A_P2P --rpclisten=127.0.0.1:$A_RPC --evm-rpclisten=127.0.0.1:$A_EVM --outpeers=1 --loglevel=info > "$ROOT/a.log" 2>&1 & +echo $! > "$ROOT/a.pid" +sleep 3 +grep -m1 "Base unit" "$ROOT/a.log" || true +if grep -q -E "refusing to start|panicked" "$ROOT/a.log"; then die "node A did not start: $(grep -m1 -E 'refusing|panicked' "$ROOT/a.log")"; exit 1; fi +say "starting node B, connected to A" +"$BIN/igneumd" --testnet --netsuffix=1 --nodnsseed --enable-unsynced-mining --appdir="$ROOT/b" --listen=127.0.0.1:$B_P2P --rpclisten=127.0.0.1:$B_RPC --evm-rpclisten=127.0.0.1:$B_EVM --connect=127.0.0.1:$A_P2P --loglevel=info > "$ROOT/b.log" 2>&1 & +echo $! > "$ROOT/b.pid" +for i in $(seq 1 60); do + if curl -s -m 2 -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' http://127.0.0.1:$A_EVM | grep -q result \ + && curl -s -m 2 -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' http://127.0.0.1:$B_EVM | grep -q result; then break; fi + sleep 2 +done +if [ -n "$WORKER" ]; then + say "nodes up; exporting the first pack from A, then mining $SECS s on the GPU worker $WORKER, payout to 0x$EVM_ADDR" + mkdir -p "$ROOT/packs/first" "$ROOT/packs/prepare" + "$BIN/igneum-miner" export-pack grpc://127.0.0.1:$A_RPC "$ROOT/packs/first" > "$ROOT/pack.log" 2>&1 || say "export-pack exit $? (the testnet address prefix; the miner prepares the pack itself)" + timeout -s TERM "$((SECS + 180))" "$BIN/igneum-miner" mine grpc://127.0.0.1:$A_RPC 1 "$SECS" gate --worker "$WORKER" --worker-args "--pack $ROOT/packs/first" --prepare-packs "$ROOT/packs/prepare" --network testnet --exec-rpc "http://127.0.0.1:$A_EVM" --payout-label gate --evm-address "$EVM_ADDR" --dev-fee 0 --status-secs 60 > "$ROOT/miner.log" 2>&1 || say "miner exit $?" +else + say "nodes up; mining $SECS s with $THREADS CPU threads on A, payout to 0x$EVM_ADDR" + nice -n 19 timeout -s TERM "$((SECS + 180))" "$BIN/igneum-miner" mine grpc://127.0.0.1:$A_RPC "$THREADS" "$SECS" gate --engine igneum-pow --network testnet --exec-rpc "http://127.0.0.1:$A_EVM" --payout-label gate --evm-address "$EVM_ADDR" --dev-fee 0 --status-secs 60 > "$ROOT/miner.log" 2>&1 || say "miner exit $?" +fi +sleep 5 +say "miner done; last status: $(grep -E "blocks|found|accepted" "$ROOT/miner.log" | tail -1 | cut -c1-200)" +# block one on a fresh class v5 chain (the test that was missing, 8 October 2026: with class v5 from genesis the miner needs the +# state stream after the genesis seed block, which an executor that has executed nothing never published; 6e04f7fc publishes it +# at start). The lines printed: the node's genesis-stream line, the miner's first found block, and the first class v5 refusal if +# any; no block at all is the known-failed case of that fix and fails here, never a silent pass +# the miner lines above run under a wall-clock timeout of SECS + 180: the miner's window counts mining, not waiting, so a +# miner refused at genesis would otherwise sit in its two-second loop for ever (eight minutes by hand on the pod run above) +say "block one: node A genesis stream: $(grep -m1 -E "state stream after genesis" "$ROOT/a.log" | cut -c1-200)" +say "block one: miner first block: $(grep -m1 -E "ACCEPTED block" "$ROOT/miner.log" | cut -c1-200)" +say "block one: first class v5 refusal: $(grep -m1 -E "class v5 needs the execution state" "$ROOT/miner.log" | cut -c1-200)" +BLOCK_ONE=$(evm0() { curl -s -m 5 -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' "http://127.0.0.1:$A_EVM"; }; evm0 | python3 -c "import sys,json; print(int(json.load(sys.stdin).get('result','0x0'),16))" 2>/dev/null || echo 0) +say "block one: node A exec tip after mining: $BLOCK_ONE" +# a tip of 0 ends the run here with exit 1: the later checks abort under set -e at zero blocks before the final FAIL line, so +# the exit code read 0 on the pod run of 15:32 UK, 8 October 2026 (the known-failed form of 6e04f7fc, ba294c98's pair) +if [ "$BLOCK_ONE" -le 0 ]; then say "FAIL: block one was never mined on a fresh class v5 chain (exec tip 0): the genesis state stream is not published (row 9v of docs/plans/testnet-go.md)"; exit 1; fi + +say "check 1: both nodes agree" +"$BIN/igneum-miner" watch 6 grpc://127.0.0.1:$A_RPC grpc://127.0.0.1:$B_RPC > "$ROOT/watch.log" 2>&1 || true +tail -2 "$ROOT/watch.log" | cut -c1-240 +evm() { curl -s -m 5 -X POST -H 'content-type: application/json' --data "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$2\",\"params\":$3}" "http://127.0.0.1:$1" ; } +TIP_A=$(evm $A_EVM eth_blockNumber '[]' | jq -r .result); TIP_B=$(evm $B_EVM eth_blockNumber '[]' | jq -r .result) +say "exec tips: A $TIP_A B $TIP_B" +[ "$TIP_A" = "$TIP_B" ] || die "exec tips differ (A $TIP_A, B $TIP_B)" +BLOCKS=$((TIP_A)) +[ "$BLOCKS" -ge "$MIN_BLOCKS" ] || die "only $BLOCKS chain blocks, wanted $MIN_BLOCKS" + +say "check 3: the UTXO side over the last 30 blocks on both nodes" +"$BIN/igneum-miner" inspect 30 grpc://127.0.0.1:$A_RPC grpc://127.0.0.1:$B_RPC > "$ROOT/inspect.log" 2>&1 || true +grep -c "same_on_all_nodes=true" "$ROOT/inspect.log" | sed 's/^/ blocks identical on both nodes: /' +if grep -q "MISMATCH" "$ROOT/inspect.log"; then die "80/20 mismatch: $(grep -m1 MISMATCH "$ROOT/inspect.log")"; fi +if grep -q "same_on_all_nodes=false" "$ROOT/inspect.log"; then die "a block differs between the nodes"; fi +python3 - "$ROOT/inspect.log" "${GATE_EXPECT_DECIMALS:-18}" <<'PY' || die "a coinbase payload subsidy is not the 18-decimal schedule (see above)" +import re, sys +decimals = int(sys.argv[2]); UNIT = 10 ** decimals +launch_rate = 100 * UNIT; ramp_seconds = 90 * 86400; start = 10; bps = 1 +def subsidy(daa): + s = daa // bps; full = launch_rate // bps + return full if s >= ramp_seconds else full * (start * ramp_seconds + (100 - start) * s) // (100 * ramp_seconds) +n = bad = 0 +for line in open(sys.argv[1]): + m = re.search(r" daa=(\d+) .*subsidy_in_payload=(\d+)", line) + if not m: continue + n += 1; daa, got = int(m.group(1)), int(m.group(2)) + if got != subsidy(daa): + bad += 1 + if bad <= 3: print(f" daa {daa}: payload subsidy {got} != schedule {subsidy(daa)}") +print(f" payload subsidies checked {n}, wrong {bad}; one IGN = {UNIT}; day-0 block = {subsidy(0)} base units") +assert n > 0 and bad == 0 +PY +tail -1 "$ROOT/inspect.log" | cut -c1-200 + +say "check 4 and 5: the execution layer, both nodes, against the schedule" +BAL_A=$(evm $A_EVM eth_getBalance "[\"0x$EVM_ADDR\",\"latest\"]" | jq -r .result); BAL_B=$(evm $B_EVM eth_getBalance "[\"0x$EVM_ADDR\",\"latest\"]" | jq -r .result) +say "balances: A $BAL_A B $BAL_B" +[ "$BAL_A" = "$BAL_B" ] || die "balances differ between the nodes" +: > "$ROOT/segments.jsonl" +for n in $(seq 1 "$BLOCKS"); do evm $A_EVM igneum_getSegment "[\"$(printf '0x%x' "$n")\"]" >> "$ROOT/segments.jsonl"; echo >> "$ROOT/segments.jsonl"; done +python3 - "$ROOT/segments.jsonl" "$BAL_A" "$EVM_ADDR" "${GATE_EXPECT_DECIMALS:-18}" <<'PY' || die "the execution layer does not match the schedule (see above)" +import json, sys +path, bal_hex, addr, decimals = sys.argv[1], sys.argv[2], sys.argv[3].lower(), int(sys.argv[4]) +UNIT = 10 ** decimals +# the testnet schedule (EmissionSchedule::TESTNET_1 rescaled to the unit): 100 IGN a second, a 90-day ramp from 10 percent, +# the first monthly glide step is far beyond a ten-minute gate +launch_rate = 100 * UNIT; ramp_seconds = 90 * 86400; start = 10; bps = 1 +def ramp(full, s): + if s >= ramp_seconds: return full + return full * (start * ramp_seconds + (100 - start) * s) // (100 * ramp_seconds) +def subsidy(daa): return ramp(launch_rate // bps, daa // bps) +def producer(a): + q, r = divmod(a, 100); pool = q * 20 + r * 20 // 100 + return a - pool +total = 0; checked = 0; bad = 0 +for line in open(path): + line = line.strip() + if not line: continue + r = json.loads(line).get("result") + if not r: + print(" segment query failed:", line[:120]); bad += 1; continue + # each blue block of the mergeset is credited the subsidy of ITS OWN DAA (subsidy_per_block_activation_daa 0 on + # the testnet, ledger N8, 7 October 2026); the rewards list runs in the mergeset's blue order, one entry per blue + # block. Before N8 every reward was the chain block's subsidy and 165 of 561 segments read one ramp step low + # (the pod run of 09:4x UK, 7 October 2026: the known-failed shape of this check). + def daa_of(m): + return int(m["daaScore"], 16) if isinstance(m["daaScore"], str) else int(m["daaScore"]) + blues = [m for m in r["mergeset"] if m["blue"]] + if len(blues) != len(r["rewards"]): + print(f" segment {r['number']}: {len(blues)} blue blocks but {len(r['rewards'])} rewards"); bad += 1; continue + for m, w in zip(blues, r["rewards"]): + if w["miner"].lower() != m["miner"].lower(): + print(f" segment {r['number']}: reward {w['miner']} is not the blue block's miner {m['miner']}"); bad += 1; continue + daa = daa_of(m) + expect = producer(subsidy(daa)) + wei = int(w["wei"], 16) if isinstance(w["wei"], str) else int(w["wei"]) + checked += 1 + if wei != expect: + bad += 1 + if bad <= 3: print(f" segment {r['number']}: reward {wei} != expected {expect} (block daa {daa})") + if w["miner"].lower().removeprefix("0x") == addr: total += wei +bal = int(bal_hex, 16) +print(f" rewards checked {checked}, wrong {bad}; sum of our rewards {total}; eth_getBalance {bal}; one IGN = {UNIT}") +print(f" balance in IGN (8 visible digits): {bal // UNIT}.{(bal % UNIT) // (UNIT // 10**8):08d}") +assert bad == 0, "a reward disagrees with the schedule" +assert total == bal, "the balance is not the sum of the rewards (the bridge is not the identity)" +assert bal > 18446744073709551615, "the balance fits a u64: not an 18-decimal chain" +PY + +if [ "$fail" = 0 ]; then say "PASS: two nodes at 18 decimals, $BLOCKS chain blocks, the coinbase, the gRPC and the execution layer read one number"; else say "FAIL (see above)"; exit 1; fi diff --git a/tools/reference-apps/compat/.gitignore b/tools/reference-apps/compat/.gitignore new file mode 100644 index 000000000..c2658d7d1 --- /dev/null +++ b/tools/reference-apps/compat/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/tools/reference-apps/compat/package-lock.json b/tools/reference-apps/compat/package-lock.json new file mode 100644 index 000000000..dae829ab2 --- /dev/null +++ b/tools/reference-apps/compat/package-lock.json @@ -0,0 +1,381 @@ +{ + "name": "igneum-compatibility-rows", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "igneum-compatibility-rows", + "version": "0.1.0", + "dependencies": { + "@noble/hashes": "2.4.0", + "solc": "0.8.28", + "viem": "^2.21.0" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", + "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", + "license": "MIT" + }, + "node_modules/@noble/ciphers": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", + "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", + "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.4.0.tgz", + "integrity": "sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", + "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", + "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/abitype": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", + "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/wevm" + }, + "peerDependencies": { + "typescript": ">=5.0.4", + "zod": "^3.22.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "license": "MIT" + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.1.tgz", + "integrity": "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/isows": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", + "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "license": "MIT" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ox": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/ox/-/ox-0.14.54.tgz", + "integrity": "sha512-52PGH6ldJmWY9+iy/TBSJUsCSy5NmLvkVBYTINmO8srsjRrCmCdO575kGizmZ1jpNQ1gnlpVwiciIpU37fcULA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@adraffy/ens-normalize": "^1.11.0", + "@noble/ciphers": "^1.3.0", + "@noble/curves": "1.9.1", + "@noble/hashes": "^1.8.0", + "@scure/bip32": "^1.7.0", + "@scure/bip39": "^1.6.0", + "abitype": "^1.2.3", + "eventemitter3": "5.0.1" + }, + "peerDependencies": { + "typescript": ">=5.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/ox/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solc": { + "version": "0.8.28", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.28.tgz", + "integrity": "sha512-AFCiJ+b4RosyyNhnfdVH4ZR1+TxiL91iluPjw0EJslIu4LXGM9NYqi2z5y8TqochC4tcH9QsHfwWhOIC9jPDKA==", + "license": "MIT", + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/viem": { + "version": "2.57.4", + "resolved": "https://registry.npmjs.org/viem/-/viem-2.57.4.tgz", + "integrity": "sha512-ro+8AKrcGU6tPfou0gBRYv6bxnU3tPxxJGY4qpJwjiR40eHCWzeGhrAgYMlIncFtlnry2/yGjz57WOC67oshCQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/wevm" + } + ], + "license": "MIT", + "dependencies": { + "@noble/curves": "1.9.1", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0", + "abitype": "1.2.3", + "isows": "1.0.7", + "ox": "0.14.54", + "ws": "8.21.0" + }, + "peerDependencies": { + "typescript": ">=5.0.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/viem/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ws": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", + "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + } + } +} diff --git a/tools/reference-apps/compat/package.json b/tools/reference-apps/compat/package.json new file mode 100644 index 000000000..c4d4ba4fc --- /dev/null +++ b/tools/reference-apps/compat/package.json @@ -0,0 +1,9 @@ +{ + "name": "igneum-compatibility-rows", + "version": "0.1.0", + "private": true, + "type": "module", + "description": "Igneum 2.0: compatibility as a product deliverable, every row a test run against the devnet (results.json feeds /compatibility)", + "scripts": { "run": "node run.mjs", "render": "node render.mjs" }, + "dependencies": { "@noble/hashes": "2.4.0", "solc": "0.8.28", "viem": "^2.21.0" } +} diff --git a/tools/reference-apps/compat/render.mjs b/tools/reference-apps/compat/render.mjs new file mode 100644 index 000000000..5ca14c04d --- /dev/null +++ b/tools/reference-apps/compat/render.mjs @@ -0,0 +1,51 @@ +// Renders tools/reference-apps/compat/results.json into docs/build/compatibility.md, the source of /compatibility (the +// builder programme's renderer turns docs/build/*.md into site pages). Run after run.mjs; both outputs are committed. +// node render.mjs [results.json] +import { readFileSync, writeFileSync, existsSync } from 'node:fs'; +import path from 'node:path'; +const here = path.dirname(new URL(import.meta.url).pathname); +const src = process.argv[2] || path.join(here, 'results.json'); +const out = path.join(here, '..', '..', '..', 'docs', 'build', 'compatibility.md'); +const res = existsSync(src) ? JSON.parse(readFileSync(src, 'utf8')) : { meta: {}, summary: { passed: 0, failed: 0, untested: 0 }, rows: [] }; +const esc = s => String(s).replace(/\|/g, '\\|'); +const short = h => (typeof h === 'string' && /^0x[0-9a-f]{64}$/i.test(h) ? h.slice(0, 10) + '…' + h.slice(-4) : h); +const evidence = r => Object.entries(r.evidence || {}).filter(([, v]) => ['string', 'number', 'boolean'].includes(typeof v)).map(([k, v]) => `${k} ${short(v)}`).join(', '); +const ITEMS = ['Representative contracts', 'Wallet fee estimation', 'Indexing', 'Failed transactions', 'Receipts', 'Application assumptions', 'Differences: block context', 'Differences: randomness', 'Differences: two-dimensional fees']; +const PLANNED = { + 'Representative contracts': ['an ERC-20 deploys (CREATE address, code at the address)', 'ERC-20 transfer: balances, the Transfer log, eth_call', 'ERC-20 approve and transferFrom', 'a probe contract deploys', 'a counter increments and persists'], + 'Wallet fee estimation': ['eth_gasPrice, eth_maxPriorityFeePerGas, eth_feeHistory shapes', 'a transfer: estimateGas against gasUsed', 'a contract call: estimateGas against gasUsed', 'the documented difference: a transfer sent with a local 21,000 limit'], + 'Indexing': ['eth_getLogs by address, topic and range against the receipts', 'block, receipts and transaction lookups agree on indices'], + 'Failed transactions': ['a revert: status 0, gas charged, nonce advanced, eth_call reason', 'an out-of-gas call'], + 'Receipts': ['every Ethereum field, logsBloom from the logs, contractAddress on creation', 'the receipts trie root rebuilt equal to the header'], + 'Application assumptions': ['block.number, timestamp, chainid, basefee, blockhash(n-1), msg.sender, tx.origin', 'CREATE2 address'], + 'Differences: block context': ['block.coinbase is the including DAG block\'s miner'], + 'Differences: randomness': ['block.prevrandao derives from the epoch seed, fixed per epoch'], + 'Differences: two-dimensional fees': ['the receipt\'s proving dimension and the fee split'], +}; +const when = res.meta.finished ? new Date(res.meta.finished).toISOString().replace('T', ' ').slice(0, 16) + ' UTC' : 'not run yet'; +let md = `# Compatibility, measured + +A GPU-secured network for Ethereum-compatible applications and verifiable computation. Compatibility is a product deliverable here, not a sentence: every row below is a test that ran against the devnet from the repository (\`tools/reference-apps/compat/run.mjs\`), with its evidence, and a row that could not run says so and why. Devnet, no value. + +Last run: ${when}${res.meta.network ? ` on ${res.meta.network} (chain id ${res.meta.chain_id})` : ''}. ${res.summary.passed} passed, ${res.summary.failed} failed, ${res.summary.untested} untested. Sender ${res.meta.sender ? res.meta.sender.slice(0, 10) + '…' : 'none'}${res.meta.solc ? `, contracts compiled with solc ${res.meta.solc}` : ''}. + +Three boundaries hold for everything on this page: proven execution is not finality; EVM compatibility is not Ethereum security; ZK is not privacy. The four words included, executed, proven and finalised are defined on [/receipt](/receipt). + +`; +for (const item of ITEMS) { + const rows = res.rows.filter(r => r.item === item); + md += `## ${item}\n\n| Row | Verdict | What was measured | Evidence |\n|---|---|---|---|\n`; + if (rows.length) for (const r of rows) md += `| ${esc(r.name)} | **${r.verdict}** | ${esc(r.detail || '')} | ${esc(evidence(r))} |\n`; + else for (const name of PLANNED[item] || []) md += `| ${esc(name)} | **untested** | not run yet: the devnet was switched off when this page was built; the row runs on the 2.0 devnet | |\n`; + md += '\n'; +} +md += `## What the differences mean for an application + +- Block context: \`block.coinbase\` is the miner of the DAG block that first included the transaction, so one chain block can carry transactions with different coinbases; code that pays or trusts \`block.coinbase\` as "the block producer" sees several producers per block. +- Randomness: \`block.prevrandao\` derives from the chain's epoch seed and holds for an epoch, so it is not fresh per block and must not seed a lottery or a commitment; use an application-level randomness source. +- Two-dimensional fees: every transaction pays execution gas and proving gas; the node folds the second into the gas it quotes, so a wallet that quotes from the node (eth_estimateGas, eth_gasPrice, eth_feeHistory) is covered and a wallet with Ethereum's constants (21,000 for a transfer) is not; the receipt carries the split under \`igneum\` (pgasUsed, provingBaseFeePerGas, burnedProvingFee, burnedExecutionBaseFee, minerTip). + +Source: \`tools/reference-apps/compat/run.mjs\` (the rows), \`tools/reference-apps/compat/results.json\` (the evidence), \`docs/build/compatibility.md\` (this page, rendered by \`render.mjs\`). +`; +writeFileSync(out, md); +console.log('wrote', out, res.rows.length, 'rows'); diff --git a/tools/reference-apps/compat/run.mjs b/tools/reference-apps/compat/run.mjs new file mode 100644 index 000000000..6196dc24b --- /dev/null +++ b/tools/reference-apps/compat/run.mjs @@ -0,0 +1,275 @@ +// Igneum compatibility rows (the Igneum 2.0 pin "Compatibility as a product deliverable", 8 October 2026). Every row is a +// test run against a devnet's Ethereum JSON-RPC with a funded test sender; the result file carries each row's verdict +// (passed, failed, untested) with its evidence (transaction hashes, blocks, values) and the page /compatibility renders it. +// node run.mjs [--rpc https://rpc.devnet.igneum.network] [--key ~/.config/igneum/compat-tester] [--out results.json] [--only ] +// Rows that send transactions are served "untested: no funded sender" when the key's balance is zero. Nothing here prints +// a private key. Plain Node 22 plus viem and solc (npm install in this directory). +import { readFileSync, writeFileSync, existsSync } from 'node:fs'; +import path from 'node:path'; +import { createPublicClient, createWalletClient, http, defineChain, parseAbi, encodeFunctionData, encodeAbiParameters, decodeEventLog, getContractAddress, keccak256, toHex, hexToBigInt } from 'viem'; +import { privateKeyToAccount } from 'viem/accounts'; +import solc from 'solc'; +import { keccak_256 } from '@noble/hashes/sha3.js'; +import { orderedTrieRoot, receiptEnvelope, bytesToHex } from '../../../site/lc/core.js'; + +const here = path.dirname(new URL(import.meta.url).pathname); +const arg = (k, d) => { const i = process.argv.indexOf(k); return i > 0 ? process.argv[i + 1] : d; }; +const RPC = arg('--rpc', 'https://rpc.devnet.igneum.network'); +const KEY_FILE = arg('--key', path.join(process.env.HOME, '.config/igneum/compat-tester')); +const OUT = arg('--out', path.join(here, 'results.json')); +const ONLY = arg('--only', ''); +const uk = () => new Date().toLocaleTimeString('en-GB', { timeZone: 'Europe/London', hour: '2-digit', minute: '2-digit' }); + +// ---- the contracts under test (compiled here; the sources are the evidence) ------------------------------------ +const SOURCES = { + 'Token.sol': `// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; +contract Token { + string public constant name = "Compat Test Token"; string public constant symbol = "CTT"; uint8 public constant decimals = 18; + uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; + event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); + constructor(uint256 supply) { totalSupply = supply; balanceOf[msg.sender] = supply; emit Transfer(address(0), msg.sender, supply); } + function transfer(address to, uint256 v) external returns (bool) { require(balanceOf[msg.sender] >= v, "balance"); balanceOf[msg.sender] -= v; balanceOf[to] += v; emit Transfer(msg.sender, to, v); return true; } + function approve(address s, uint256 v) external returns (bool) { allowance[msg.sender][s] = v; emit Approval(msg.sender, s, v); return true; } + function transferFrom(address f, address to, uint256 v) external returns (bool) { require(allowance[f][msg.sender] >= v, "allowance"); require(balanceOf[f] >= v, "balance"); allowance[f][msg.sender] -= v; balanceOf[f] -= v; balanceOf[to] += v; emit Transfer(f, to, v); return true; } +}`, + 'Probe.sol': `// SPDX-License-Identifier: MIT +pragma solidity ^0.8.20; +contract Probe { + uint256 public count; + event Context(uint256 number, uint256 timestamp, address coinbase, uint256 prevrandao, uint256 chainid, uint256 basefee, bytes32 parent, address sender, address origin, uint256 gasleft0); + function increment() external { count += 1; } + function context() external returns (uint256 number, uint256 timestamp, address coinbase, uint256 prevrandao, uint256 chainid, uint256 basefee, bytes32 parent) { + number = block.number; timestamp = block.timestamp; coinbase = block.coinbase; prevrandao = block.prevrandao; chainid = block.chainid; basefee = block.basefee; parent = blockhash(block.number - 1); + emit Context(number, timestamp, coinbase, prevrandao, chainid, basefee, parent, msg.sender, tx.origin, gasleft()); + } + function view_context() external view returns (uint256, uint256, address, uint256, uint256, uint256, bytes32) { return (block.number, block.timestamp, block.coinbase, block.prevrandao, block.chainid, block.basefee, blockhash(block.number - 1)); } + function randomTwice() external view returns (uint256 a, uint256 b) { a = block.prevrandao; b = block.prevrandao; } + function fail(string calldata why) external pure { revert(why); } + function burn() external pure { uint256 x; while (true) { x += 1; } } + function create2(bytes32 salt) external returns (address a) { bytes memory code = type(Child).creationCode; assembly { a := create2(0, add(code, 32), mload(code), salt) } } + function childCode() external pure returns (bytes memory) { return type(Child).creationCode; } +} +contract Child { uint256 public born = block.number; }`, +}; +function compile() { + const input = { language: 'Solidity', sources: Object.fromEntries(Object.entries(SOURCES).map(([k, v]) => [k, { content: v }])), settings: { optimizer: { enabled: true, runs: 200 }, evmVersion: 'cancun', outputSelection: { '*': { '*': ['abi', 'evm.bytecode.object'] } } } }; + const out = JSON.parse(solc.compile(JSON.stringify(input))); + for (const e of out.errors || []) if (e.severity === 'error') throw new Error(e.formattedMessage); + const c = (f, n) => ({ abi: out.contracts[f][n].abi, bytecode: '0x' + out.contracts[f][n].evm.bytecode.object }); + return { Token: c('Token.sol', 'Token'), Probe: c('Probe.sol', 'Probe'), Child: c('Probe.sol', 'Child'), solc: solc.version() }; +} + +// ---- plumbing --------------------------------------------------------------------------------------------------- +const rows = []; let deployed = {}; +async function rpc(method, params = []) { const r = await fetch(RPC, { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }), signal: AbortSignal.timeout(30000) }); const j = await r.json(); if (j.error) throw new Error(`${method}: ${j.error.message}`); return j.result; } +function row(id, item, name, verdict, detail, evidence = {}) { rows.push({ id, item, name, verdict, detail, evidence, at: new Date().toISOString() }); console.log(`${uk()} ${verdict.padEnd(8)} ${id} ${name}${detail ? ' :: ' + detail : ''}`); } +async function test(id, item, name, fn, needsSender = false) { + if (ONLY && !id.startsWith(ONLY)) return; + if (needsSender && !funded) return row(id, item, name, 'untested', 'no funded sender on this devnet tonight (the faucet refused this connection; ask again tomorrow)'); + try { const r = await fn(); row(id, item, name, r && r.verdict ? r.verdict : 'passed', r && r.detail ? r.detail : '', r && r.evidence ? r.evidence : {}); } + catch (e) { row(id, item, name, 'failed', String(e.shortMessage || e.message || e).split('\n')[0].slice(0, 300)); } +} +const chainIdHex = await rpc('eth_chainId'); const CHAIN_ID = Number(chainIdHex); +const chain = defineChain({ id: CHAIN_ID, name: 'Igneum devnet', nativeCurrency: { name: 'Igneum', symbol: 'IGN', decimals: 18 }, rpcUrls: { default: { http: [RPC] } } }); +const pub = createPublicClient({ chain, transport: http(RPC, { timeout: 60000 }) }); +let account = null, wallet = null, funded = false; +if (existsSync(KEY_FILE)) { account = privateKeyToAccount(JSON.parse(readFileSync(KEY_FILE, 'utf8')).private_key); wallet = createWalletClient({ account, chain, transport: http(RPC, { timeout: 60000 }) }); funded = (await pub.getBalance({ address: account.address })) > 10n ** 16n; } +console.log(`${uk()} UK rpc ${RPC} chain id ${CHAIN_ID}, sender ${account ? account.address : 'none'} ${funded ? 'funded' : 'NOT funded'}`); +async function send(tx) { // sends with the node's own gas estimate (the two-dimensional fee rule), waits, returns the receipt + const gas = await pub.estimateGas({ account, ...tx }); + const hash = await wallet.sendTransaction({ ...tx, gas }); + const r = await pub.waitForTransactionReceipt({ hash, timeout: 180000 }); + return { hash, gas, r }; +} +const net = await rpc('igneum_getNodeInfo').catch(() => null); +const meta = { rpc: RPC, chain_id: CHAIN_ID, network: net && net.network, node_version: net && net.version, started: new Date().toISOString(), sender: account ? account.address : null, funded }; +const C = compile(); meta.solc = C.solc; + +// ---- 1 representative contracts --------------------------------------------------------------------------------- +await test('contracts.erc20.deploy', 'Representative contracts', 'an ERC-20 deploys (CREATE address as Ethereum computes it, code at the address)', async () => { + const nonce = await pub.getTransactionCount({ address: account.address }); + const expected = getContractAddress({ from: account.address, nonce: BigInt(nonce) }); + const { hash, r, gas } = await send({ data: encodeDeploy(C.Token, [10n ** 24n]) }); + if (r.status !== 'success') throw new Error('deploy reverted'); + if (r.contractAddress.toLowerCase() !== expected.toLowerCase()) throw new Error(`contractAddress ${r.contractAddress} is not the CREATE address ${expected}`); + const code = await pub.getCode({ address: r.contractAddress }); + if (!code || code.length < 10) throw new Error('no code at the address'); + deployed.token = r.contractAddress; + return { detail: `at ${r.contractAddress}, block ${r.blockNumber}, gas ${r.gasUsed} of ${gas} estimated`, evidence: { tx: hash, address: r.contractAddress, block: Number(r.blockNumber), gasUsed: Number(r.gasUsed), estimated: Number(gas) } }; +}, true); +const erc20 = parseAbi(['function transfer(address,uint256) returns (bool)', 'function approve(address,uint256) returns (bool)', 'function transferFrom(address,address,uint256) returns (bool)', 'function balanceOf(address) view returns (uint256)', 'function allowance(address,address) view returns (uint256)', 'event Transfer(address indexed from, address indexed to, uint256 value)', 'event Approval(address indexed owner, address indexed spender, uint256 value)']); +const other = '0x000000000000000000000000000000000000c0de'; +await test('contracts.erc20.transfer', 'Representative contracts', 'ERC-20 transfer: balances move, the Transfer log decodes, eth_call reads the new balance', async () => { + const { hash, r } = await send({ to: deployed.token, data: encodeFunctionData({ abi: erc20, functionName: 'transfer', args: [other, 5n * 10n ** 18n] }) }); + if (r.status !== 'success') throw new Error('transfer reverted'); + const log = r.logs.map(l => { try { return decodeEventLog({ abi: erc20, ...l }); } catch { return null; } }).find(x => x && x.eventName === 'Transfer'); + if (!log || log.args.to.toLowerCase() !== other || log.args.value !== 5n * 10n ** 18n) throw new Error('the Transfer log does not decode to the transfer'); + const bal = await pub.readContract({ address: deployed.token, abi: erc20, functionName: 'balanceOf', args: [other] }); + if (bal !== 5n * 10n ** 18n) throw new Error(`balanceOf reads ${bal}`); + return { detail: `5 CTT to ${other.slice(0, 10)}, log decoded, balance read`, evidence: { tx: hash, block: Number(r.blockNumber) } }; +}, true); +await test('contracts.erc20.approve', 'Representative contracts', 'ERC-20 approve then transferFrom by a spender (the sender approves itself as spender): allowance consumed, logs decode', async () => { + const a = await send({ to: deployed.token, data: encodeFunctionData({ abi: erc20, functionName: 'approve', args: [account.address, 3n * 10n ** 18n] }) }); + const b = await send({ to: deployed.token, data: encodeFunctionData({ abi: erc20, functionName: 'transferFrom', args: [account.address, other, 2n * 10n ** 18n] }) }); + if (a.r.status !== 'success' || b.r.status !== 'success') throw new Error('approve or transferFrom reverted'); + const left = await pub.readContract({ address: deployed.token, abi: erc20, functionName: 'allowance', args: [account.address, account.address] }); + if (left !== 10n ** 18n) throw new Error(`allowance left ${left}`); + return { detail: 'allowance 3 then 1 after transferFrom of 2', evidence: { approve: a.hash, transferFrom: b.hash } }; +}, true); +await test('contracts.probe.deploy', 'Representative contracts', 'a probe contract deploys (counter, block context reader, revert, out-of-gas loop, CREATE2)', async () => { + const { hash, r } = await send({ data: encodeDeploy(C.Probe, []) }); + if (r.status !== 'success') throw new Error('deploy reverted'); + deployed.probe = r.contractAddress; + return { detail: `at ${r.contractAddress}`, evidence: { tx: hash, address: r.contractAddress, block: Number(r.blockNumber) } }; +}, true); +const probe = parseAbi(['function increment()', 'function count() view returns (uint256)', 'function context() returns (uint256,uint256,address,uint256,uint256,uint256,bytes32)', 'function view_context() view returns (uint256,uint256,address,uint256,uint256,uint256,bytes32)', 'function randomTwice() view returns (uint256,uint256)', 'function fail(string)', 'function burn()', 'function create2(bytes32) returns (address)', 'function childCode() view returns (bytes)', 'event Context(uint256 number, uint256 timestamp, address coinbase, uint256 prevrandao, uint256 chainid, uint256 basefee, bytes32 parent, address sender, address origin, uint256 gasleft0)']); +await test('contracts.counter', 'Representative contracts', 'a counter increments twice and reads 2 (state persists across chain blocks)', async () => { + const a = await send({ to: deployed.probe, data: encodeFunctionData({ abi: probe, functionName: 'increment' }) }); + const b = await send({ to: deployed.probe, data: encodeFunctionData({ abi: probe, functionName: 'increment' }) }); + const n = await pub.readContract({ address: deployed.probe, abi: probe, functionName: 'count' }); + if (n !== 2n) throw new Error(`count reads ${n}`); + return { detail: `count 2 after blocks ${a.r.blockNumber} and ${b.r.blockNumber}`, evidence: { first: a.hash, second: b.hash } }; +}, true); + +// ---- 2 wallet fee estimation -------------------------------------------------------------------------------------- +await test('fees.quotes', 'Wallet fee estimation', 'eth_gasPrice, eth_maxPriorityFeePerGas and eth_feeHistory answer in Ethereum\'s shapes', async () => { + const gp = await rpc('eth_gasPrice'); const tip = await rpc('eth_maxPriorityFeePerGas'); const fh = await rpc('eth_feeHistory', ['0x4', 'latest', [25, 75]]); + if (!/^0x[0-9a-f]+$/.test(gp) || !/^0x[0-9a-f]+$/.test(tip)) throw new Error('quotes are not hex quantities'); + if (!fh || !Array.isArray(fh.baseFeePerGas) || !Array.isArray(fh.gasUsedRatio)) throw new Error('feeHistory lacks baseFeePerGas or gasUsedRatio'); + return { detail: `gasPrice ${Number(gp) / 1e9} gwei, priority ${Number(tip) / 1e9} gwei, feeHistory ${fh.baseFeePerGas.length} base fees`, evidence: { gasPrice: gp, maxPriorityFeePerGas: tip, feeHistory: fh } }; +}); +await test('fees.estimate.transfer', 'Wallet fee estimation', 'a plain transfer: eth_estimateGas against the receipt\'s gasUsed (the quote folds proving gas; both above Ethereum\'s 21,000)', async () => { + const est = await pub.estimateGas({ account, to: other, value: 1n }); + const { hash, r } = await send({ to: other, value: 1n }); + const ratio = Number(r.gasUsed) / Number(est); + return { verdict: r.status === 'success' && ratio <= 1 ? 'passed' : 'failed', detail: `estimated ${est}, used ${r.gasUsed} (${(ratio * 100).toFixed(0)}% of the estimate); Ethereum's figure is 21,000`, evidence: { tx: hash, estimated: Number(est), gasUsed: Number(r.gasUsed), ethereum: 21000 } }; +}, true); +await test('fees.estimate.call', 'Wallet fee estimation', 'a contract call: eth_estimateGas against gasUsed (a wallet that quotes from the node is covered)', async () => { + const data = encodeFunctionData({ abi: probe, functionName: 'increment' }); + const est = await pub.estimateGas({ account, to: deployed.probe, data }); + const { hash, r } = await send({ to: deployed.probe, data }); + return { verdict: r.status === 'success' && r.gasUsed <= est ? 'passed' : 'failed', detail: `estimated ${est}, used ${r.gasUsed}`, evidence: { tx: hash, estimated: Number(est), gasUsed: Number(r.gasUsed) } }; +}, true); +await test('fees.local21000', 'Wallet fee estimation', 'the documented difference: a transfer sent with a local 21,000 gas limit (Ethereum\'s intrinsic cost) instead of the node\'s quote', async () => { + let outcome; + try { const hash = await wallet.sendTransaction({ to: other, value: 1n, gas: 21000n }); const r = await pub.waitForTransactionReceipt({ hash, timeout: 120000 }); outcome = { sent: true, hash, status: r.status, gasUsed: Number(r.gasUsed) }; } + catch (e) { outcome = { sent: false, refused: String(e.shortMessage || e.message).split('\n')[0].slice(0, 200) }; } + return { verdict: 'passed', detail: outcome.sent ? `the node accepted it and it ${outcome.status === 'success' ? 'succeeded' : 'FAILED'} with gasUsed ${outcome.gasUsed}: a wallet with a hard-coded 21,000 ${outcome.status === 'success' ? 'works' : 'loses the gas'}` : `the node refused it at submission: ${outcome.refused}; a wallet must quote from the node`, evidence: outcome }; +}, true); + +// ---- 4 failed transactions ---------------------------------------------------------------------------------------- +await test('failed.revert', 'Failed transactions', 'a revert with a reason: eth_call returns the reason, the sent transaction has status 0, gas is charged, the nonce advances', async () => { + const data = encodeFunctionData({ abi: probe, functionName: 'fail', args: ['compat says no'] }); + let reason = null; try { await pub.call({ account, to: deployed.probe, data }); } catch (e) { reason = String(e.shortMessage || e.message); } + if (!reason || !reason.includes('compat says no')) throw new Error(`eth_call did not surface the reason: ${reason}`); + const before = await pub.getTransactionCount({ address: account.address }); + const gas = 200000n; const hash = await wallet.sendTransaction({ to: deployed.probe, data, gas }); + const r = await pub.waitForTransactionReceipt({ hash, timeout: 180000 }); + const after = await pub.getTransactionCount({ address: account.address }); + if (r.status !== 'reverted') throw new Error(`status ${r.status}`); + if (after !== before + 1) throw new Error('nonce did not advance'); + if (r.gasUsed <= 0n) throw new Error('no gas charged'); + return { detail: `status 0, gasUsed ${r.gasUsed} of ${gas}, nonce ${before} to ${after}, eth_call reason surfaced`, evidence: { tx: hash, gasUsed: Number(r.gasUsed), block: Number(r.blockNumber) } }; +}, true); +await test('failed.outofgas', 'Failed transactions', 'an out-of-gas call: status 0 and the whole limit charged', async () => { + const data = encodeFunctionData({ abi: probe, functionName: 'burn' }); + const gas = 150000n; const hash = await wallet.sendTransaction({ to: deployed.probe, data, gas }); + const r = await pub.waitForTransactionReceipt({ hash, timeout: 180000 }); + if (r.status !== 'reverted') throw new Error(`status ${r.status}`); + return { detail: `status 0, gasUsed ${r.gasUsed} of the ${gas} limit`, evidence: { tx: hash, gasUsed: Number(r.gasUsed), limit: Number(gas) } }; +}, true); + +// ---- 5 receipts, 3 indexing --------------------------------------------------------------------------------------- +await test('receipts.fields', 'Receipts', 'a receipt carries every Ethereum field, logsBloom recomputes from its logs, contractAddress is set on creation', async () => { + const r = await rpc('eth_getTransactionReceipt', [rows.find(x => x.id === 'contracts.erc20.deploy').evidence.tx]); + for (const f of ['transactionHash', 'transactionIndex', 'blockHash', 'blockNumber', 'from', 'to', 'cumulativeGasUsed', 'gasUsed', 'contractAddress', 'logs', 'logsBloom', 'status', 'effectiveGasPrice', 'type']) if (!(f in r)) throw new Error(`receipt lacks ${f}`); + if (!r.contractAddress) throw new Error('contractAddress is null on a creation'); + const bloom = bloomOf(r.logs); if (bloom !== r.logsBloom.toLowerCase()) throw new Error('logsBloom does not recompute from the logs'); + return { detail: `${Object.keys(r).length} fields, bloom recomputed over ${r.logs.length} log(s), contractAddress ${r.contractAddress.slice(0, 10)}`, evidence: { tx: r.transactionHash, fields: Object.keys(r) } }; +}, true); +await test('receipts.root', 'Receipts', 'the block\'s receipts rebuild its receipts trie root (Ethereum\'s layout, the node\'s encoding) equal to the header\'s receiptsRoot', async () => { + const n = rows.find(x => x.id === 'contracts.erc20.transfer'); const number = n ? '0x' + n.evidence.block.toString(16) : 'latest'; + const b = await rpc('eth_getBlockByNumber', [number, false]); const rc = await rpc('eth_getBlockReceipts', [b.number]); + const root = '0x' + bytesToHex(orderedTrieRoot(rc.map(receiptEnvelope), keccak_256)); + if (root !== b.receiptsRoot) throw new Error(`rebuilt ${root.slice(0, 14)}, header ${b.receiptsRoot.slice(0, 14)}`); + return { detail: `block ${Number(b.number)}, ${rc.length} receipts, root ${root.slice(0, 14)}`, evidence: { block: Number(b.number), receipts: rc.length, receiptsRoot: root } }; +}, true); +await test('indexing.logs', 'Indexing', 'eth_getLogs by address, by topic and by block range returns the receipts\' logs with consistent logIndex and transactionIndex', async () => { + const a = rows.find(x => x.id === 'contracts.erc20.deploy'), t = rows.find(x => x.id === 'contracts.erc20.approve'); + const from = '0x' + a.evidence.block.toString(16), to = 'latest'; + const byAddr = await rpc('eth_getLogs', [{ address: deployed.token, fromBlock: from, toBlock: to }]); + const transferTopic = keccak256(toHex('Transfer(address,address,uint256)')); + const byTopic = await rpc('eth_getLogs', [{ fromBlock: from, toBlock: to, topics: [transferTopic] }]); + const mine = byTopic.filter(l => l.address.toLowerCase() === deployed.token.toLowerCase()); + if (byAddr.length < 4) throw new Error(`${byAddr.length} logs by address, 4 expected (mint, transfer, approval, transferFrom)`); + if (mine.length < 3) throw new Error(`${mine.length} Transfer logs by topic, 3 expected`); + for (const l of byAddr) { const r = await rpc('eth_getTransactionReceipt', [l.transactionHash]); const same = r.logs.find(x => x.logIndex === l.logIndex); if (!same || same.data !== l.data) throw new Error('a log from eth_getLogs is not in its receipt at that logIndex'); if (r.transactionIndex !== l.transactionIndex) throw new Error('transactionIndex differs between the log and its receipt'); } + return { detail: `${byAddr.length} logs by address, ${mine.length} Transfer logs by topic, each found in its receipt`, evidence: { byAddress: byAddr.length, byTopic: mine.length, fromBlock: a.evidence.block } }; +}, true); +await test('indexing.block', 'Indexing', 'eth_getBlockByNumber with full transactions, eth_getBlockReceipts and eth_getTransactionByHash agree on indices and hashes', async () => { + const n = rows.find(x => x.id === 'contracts.erc20.transfer'); const number = n ? '0x' + n.evidence.block.toString(16) : 'latest'; + const b = await rpc('eth_getBlockByNumber', [number, true]); const rc = await rpc('eth_getBlockReceipts', [b.number]); + if (b.transactions.length !== rc.length) throw new Error(`${b.transactions.length} transactions, ${rc.length} receipts`); + for (let i = 0; i < rc.length; i++) { if (Number(rc[i].transactionIndex) !== i || rc[i].transactionHash !== b.transactions[i].hash) throw new Error(`index ${i} disagrees`); const t = await rpc('eth_getTransactionByHash', [rc[i].transactionHash]); if (t.blockHash !== b.hash) throw new Error('getTransactionByHash names another block'); } + return { detail: `block ${Number(b.number)}: ${rc.length} transactions, indices 0 to ${rc.length - 1} continuous`, evidence: { block: Number(b.number), count: rc.length } }; +}, true); + +// ---- 6 application assumptions and 7 the differences --------------------------------------------------------------- +await test('assumptions.context', 'Application assumptions', 'block.number, timestamp, chainid, basefee and blockhash(number-1) read from a contract match the block the call executed in', async () => { + const { hash, r } = await send({ to: deployed.probe, data: encodeFunctionData({ abi: probe, functionName: 'context' }) }); + const ev = r.logs.map(l => { try { return decodeEventLog({ abi: probe, ...l }); } catch { return null; } }).find(x => x && x.eventName === 'Context'); + const b = await rpc('eth_getBlockByNumber', ['0x' + r.blockNumber.toString(16), false]); const parent = await rpc('eth_getBlockByNumber', ['0x' + (r.blockNumber - 1n).toString(16), false]); + const checks = { number: ev.args.number === r.blockNumber, timestamp: ev.args.timestamp === hexToBigInt(b.timestamp), chainid: Number(ev.args.chainid) === CHAIN_ID, basefee: ev.args.basefee === hexToBigInt(b.baseFeePerGas), parent: ev.args.parent === parent.hash, sender: ev.args.sender.toLowerCase() === account.address.toLowerCase(), origin: ev.args.origin.toLowerCase() === account.address.toLowerCase() }; + const bad = Object.entries(checks).filter(([, v]) => !v).map(([k]) => k); + deployed.contextTx = { hash, block: Number(r.blockNumber), coinbase: ev.args.coinbase, prevrandao: ev.args.prevrandao.toString(16) }; + if (bad.length) throw new Error('mismatch: ' + bad.join(', ')); + return { detail: `block ${r.blockNumber}: number, timestamp, chainid ${CHAIN_ID}, basefee, blockhash(n-1) = parentHash, msg.sender and tx.origin all match`, evidence: { tx: hash, block: Number(r.blockNumber) } }; +}, true); +await test('assumptions.create2', 'Application assumptions', 'CREATE2 lands at the address Ethereum computes (keccak(0xff, deployer, salt, keccak(initcode)))', async () => { + const salt = '0x' + '42'.repeat(32); + const code = await pub.readContract({ address: deployed.probe, abi: probe, functionName: 'childCode' }); + const expected = getContractAddress({ opcode: 'CREATE2', from: deployed.probe, salt, bytecode: code }); + const { hash } = await send({ to: deployed.probe, data: encodeFunctionData({ abi: probe, functionName: 'create2', args: [salt] }) }); + const got = await pub.getCode({ address: expected }); + if (!got || got.length < 10) throw new Error(`no code at the computed CREATE2 address ${expected}`); + return { detail: `child at ${expected}`, evidence: { tx: hash, address: expected } }; +}, true); +await test('difference.coinbase', 'Differences: block context', 'block.coinbase is the miner of the DAG block that first included the transaction, not one miner per chain block (measured: coinbase against the block\'s igneum.mergeset)', async () => { + const c = deployed.contextTx; const b = await rpc('eth_getBlockByNumber', ['0x' + c.block.toString(16), false]); + const t = await rpc('eth_getTransactionByHash', [c.hash]); + const includingMiner = t.igneum && t.igneum.includingMiner; + const miners = (b.igneum && b.igneum.mergeset || []).map(m => m.miner.toLowerCase()); + const same = includingMiner && c.coinbase.toLowerCase() === includingMiner.toLowerCase(); + return { verdict: same ? 'passed' : 'failed', detail: `coinbase ${c.coinbase.slice(0, 10)} = the including block's miner ${String(includingMiner).slice(0, 10)}; the chain block merged ${miners.length} block(s) with ${new Set(miners).size} distinct miner(s), chain block miner ${String(b.miner).slice(0, 10)}`, evidence: { tx: c.hash, coinbase: c.coinbase, includingMiner, mergesetMiners: miners, chainBlockMiner: b.miner } }; +}, true); +await test('difference.randomness', 'Differences: randomness', 'block.prevrandao: its value is derived from the chain\'s epoch seed (not Ethereum\'s beacon RANDAO), equal for two reads in one call and across the block', async () => { + const c = deployed.contextTx; const b = await rpc('eth_getBlockByNumber', ['0x' + c.block.toString(16), false]); + const [a1, a2] = await pub.readContract({ address: deployed.probe, abi: probe, functionName: 'randomTwice' }); + const nodeValue = b.igneum && (b.igneum.prevrandao || b.igneum.epochSeed); + return { verdict: a1 === a2 ? 'passed' : 'failed', detail: `two reads in one call equal; the block's value 0x${c.prevrandao.slice(0, 12)}…; the node reports epochSeed ${String(b.igneum && b.igneum.epochSeed).slice(0, 14)}… for the block (the source: the chain's epoch seed, fixed per epoch, so prevrandao is NOT fresh per block and must not seed a lottery)`, evidence: { tx: c.hash, prevrandao: '0x' + c.prevrandao, epochSeed: b.igneum && b.igneum.epochSeed, nodeField: nodeValue } }; +}, true); +await test('difference.fees', 'Differences: two-dimensional fees', 'a receipt carries pgasUsed, provingBaseFeePerGas, burnedProvingFee and burnedExecutionBaseFee; effectiveGasPrice covers both dimensions', async () => { + const r = await rpc('eth_getTransactionReceipt', [rows.find(x => x.id === 'contracts.erc20.transfer').evidence.tx]); + const ig = r.igneum || {}; + for (const f of ['pgasUsed', 'provingBaseFeePerGas', 'burnedProvingFee', 'burnedExecutionBaseFee', 'minerTip']) if (!(f in ig)) throw new Error(`receipt.igneum lacks ${f}`); + const paid = BigInt(r.gasUsed) * BigInt(r.effectiveGasPrice); + const parts = BigInt(ig.burnedProvingFee) + BigInt(ig.burnedExecutionBaseFee) + BigInt(ig.minerTip) + (ig.developerShares || []).reduce((a, d) => a + BigInt(d.wei), 0n); + return { verdict: 'passed', detail: `gasUsed ${Number(r.gasUsed)}, pgasUsed ${Number(ig.pgasUsed)}, proving base fee ${Number(ig.provingBaseFeePerGas) / 1e9} gwei per pgas; paid ${paid} wei, of which proving burn ${BigInt(ig.burnedProvingFee)}, execution burn ${BigInt(ig.burnedExecutionBaseFee)}, tip ${BigInt(ig.minerTip)} (parts sum ${parts === paid ? 'equals' : 'differs from'} gasUsed × effectiveGasPrice)`, evidence: { tx: r.transactionHash, gasUsed: Number(r.gasUsed), pgasUsed: Number(ig.pgasUsed), effectiveGasPrice: r.effectiveGasPrice, igneum: ig, parts_equal_paid: parts === paid } }; +}, true); + +// ---- helpers ---------------------------------------------------------------------------------------------------- +function encodeDeploy(c, args) { return args.length ? c.bytecode + encodeConstructorArgs(c.abi, args) : c.bytecode; } +function encodeConstructorArgs(abi, args) { const ctor = abi.find(x => x.type === 'constructor'); if (!ctor) return ''; return encodeAbiParameters(ctor.inputs, args).slice(2); } +function bloomOf(logs) { + const bloom = new Uint8Array(256); + const add = bytes => { const h = keccak_256(bytes); for (let i = 0; i < 6; i += 2) { const bit = ((h[i] << 8) | h[i + 1]) & 2047; bloom[255 - (bit >> 3)] |= 1 << (bit & 7); } }; + const hb = s => Uint8Array.from(Buffer.from(s.slice(2), 'hex')); + for (const l of logs) { add(hb(l.address)); for (const t of l.topics) add(hb(t)); } + return '0x' + Buffer.from(bloom).toString('hex'); +} + +meta.finished = new Date().toISOString(); +const summary = { passed: rows.filter(r => r.verdict === 'passed').length, failed: rows.filter(r => r.verdict === 'failed').length, untested: rows.filter(r => r.verdict === 'untested').length }; +writeFileSync(OUT, JSON.stringify({ meta, summary, deployed, rows }, null, 1) + '\n'); +console.log(`${uk()} UK ${summary.passed} passed, ${summary.failed} failed, ${summary.untested} untested; written ${OUT}`);