Merge remote-tracking branch 'build/master' into class-v5

# Conflicts:
#	site/ledger.html
This commit is contained in:
igneum-labs 2026-10-08 02:39:20 +00:00
commit d30f74e7fa
16 changed files with 342 additions and 55 deletions

View file

@ -2698,3 +2698,63 @@ p99 / max 4.610 / 4.948 / 5.606 / 6.194 ms per warp); the worst 200 re-timed at
1,000 on the half-core at 2 reps, the worst 10 at 20: worst half-core cold max 8.708 ms (`attack-f6/87142`), then 8.629
(`attack-f6/88521`), 8.414 (`attack-f6/15781`); the genesis program 8.624. Gate 10 ms: PASS by 1.29 ms. Record
`docs/analysis/attack-pass/f6-verifier.md`; logs `/srv/builds/igneum-wt-attack/target-attack-f6/phase2b.log`, `phase2c.log`.
## 7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080 (branch ca3-v4-amend, the hash lane)
Main's question of 7 October ("profitable mining is all about efficiency, is there a solution?"): the latency-shadow work hides in the memory wait, so the core clock, and the voltage along the driver's V/F curve, can drop until the work just fits the wait, with no rate loss and the class v4 premium coming back. Measured on PC 1 (machine ae432dc7, driver 617.14, app 0.3.20) with `tools/ca3-v4-amend/pc1-v4-efficiency.ps1`: the installed CUDA worker's `--bench` on the class v4 pack `v4-devnet-epoch0` (id a785001687d8688a) and the class v3 control `mx8-devnet-epoch0` of the same seed (the two differ by the shadow block alone), the card alone through the runner's card switch, 60 s per step (the batch count sized from a 5-batch probe), the clock lock through the installed app's Power Helper task (`nvidia-smi -lgc 0,<MHz>`, a cap; no prompt), nvidia-smi at 1 Hz with the mean from 8 s in (power.draw, power.draw.instant and power.draw.average agree within 0.2 W on every row on 617.14), the 2^24 fingerprint at base 0 checked against the Mac on every step (every step matched), the clocks reset and read back at the end. Jobs: run-ca3-pc1-v4-eff-5090-20261007-b (18:40 to 19:16 UTC, 2,850 to 1,400 MHz), run-ca3-pc1-v4-eff-5090-floor-20261007 (20:21 to 20:41 UTC, 1,400 to 1,100; the steps below were lost to the helper's sequence rule, see the fud ledger), run-ca3-pc1-v4-eff-5080-20261007-d (8 October, 00:45 to 01:54 UTC, unlocked to 1,000 MHz plus 900 on v4; the 75 min budget ended it there). The memory clock stayed at the driver's default throughout (13,801 MHz on the 5090, 14,801 on the 5080).
RTX 5090 (lock MHz: class v4 MH/s / W / MH/W ; class v3 MH/s / W / MH/W; the SM clock read):
| lock | v4 MH/s | v4 W | v4 MH/W | v3 MH/s | v3 W | v3 MH/W | sm MHz |
|---|---|---|---|---|---|---|---|
| unlocked | 136.84 | 475.5 | 0.288 | 136.59 | 330.2 | 0.414 | 2,838 / 2,850 |
| 2850 | 136.89 | 478.9 | 0.286 | 136.61 | 330.3 | 0.414 | 2,833 / 2,842 |
| 2781 | 136.87 | 457.6 | 0.299 | 136.62 | 317.9 | 0.430 | 2,767 |
| 2700 | 136.85 | 443.2 | 0.309 | 136.54 | 312.4 | 0.437 | 2,692 |
| 2550 | 136.77 | 402.9 | 0.339 | 136.43 | 288.5 | 0.473 | 2,542 |
| 2472 | 136.62 | 391.2 | 0.349 | 136.38 | 276.0 | 0.494 | 2,460 |
| 2400 | 136.67 | 382.8 | 0.357 | 136.29 | 269.8 | 0.505 | 2,392 |
| 2250 | 136.43 | 366.5 | 0.372 | 136.07 | 255.0 | 0.534 | 2,242 |
| 2163 | 136.33 | 361.3 | 0.377 | 136.11 | 252.4 | 0.539 | 2,152 |
| 2100 | 136.25 | 359.3 | 0.379 | 136.04 | 251.4 | 0.541 | 2,092 |
| 1950 | 135.99 | 350.1 | 0.388 | 135.78 | 244.6 | 0.555 | 1,942 |
| 1854 | 135.85 | 341.4 | 0.398 | 135.56 | 239.6 | 0.566 | 1,845 |
| 1800 | 135.75 | 337.1 | 0.403 | 135.48 | 237.4 | 0.571 | 1,792 |
| 1650 | 135.37 | 328.1 | 0.413 | 135.10 | 235.1 | 0.575 | 1,642 |
| 1500 | 135.22 | 320.5 | 0.422 | 134.90 | 232.1 | 0.581 | 1,492 |
| 1400 | 134.98 | 316.3 | 0.427 | 134.68 | 228.0 | 0.591 | 1,387 |
| 1300 | 134.76 | 312.5 | 0.431 | 134.62 | 223.3 | 0.603 | 1,290 |
| 1200 | 133.80 | 305.1 | 0.439 | 129.54 | 215.7 | 0.601 | 1,192 |
| 1100 | 122.43 | 287.3 | 0.426 | 118.70 | 209.4 | 0.567 | 1,087 |
Reading (5090): the rate is memory-bound on the whole grid and holds within 1.5 percent of unlocked down to 1,300 MHz on both classes; it falls past 5 percent at 1,200 on class v3 and past 10 percent at 1,100 on class v4, so the knee is 1,300 MHz (42 percent of the 3,090 MHz maximum). Best MH per watt: class v4 at 1,200 MHz (133.80 MH/s at 305.1 W, 0.439 MH/W; 168.6 W recovered for 2.2 percent rate), class v3 at 1,300 MHz (134.62 at 223.3 W, 0.603; 106.6 W for 1.4 percent). The class v4 premium over class v3 is 145.3 W at the unlocked clock and 81.8 W at the best points: 63 W of the premium is the clock and comes back with the lock, 82 W is the shadow's ALU work and stays. The throttle reason reads the power governor (0x400) from unlocked to 2,163 and the clock lock itself (0x4) below. Consequence 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).
RTX 5080 (the same shape; 8 October 2026, 00:45 to 01:54 UTC):
| lock | v4 MH/s | v4 W | v4 MH/W | v3 MH/s | v3 W | v3 MH/W | sm MHz |
|---|---|---|---|---|---|---|---|
| unlocked | 71.41 | 253.1 | 0.282 | 71.28 | 169.7 | 0.420 | 2,963 / 2,977 |
| 2850 | 71.41 | 229.5 | 0.311 | 71.29 | 155.3 | 0.459 | 2,842 |
| 2781 | 71.41 | 223.9 | 0.319 | 71.29 | 150.1 | 0.475 | 2,767 |
| 2700 | 71.41 | 209.6 | 0.341 | 71.29 | 149.2 | 0.478 | 2,692 |
| 2550 | 71.41 | 193.0 | 0.370 | 71.29 | 134.4 | 0.531 | 2,542 |
| 2472 | 71.41 | 182.2 | 0.392 | 71.28 | 133.7 | 0.533 | 2,460 |
| 2400 | 71.41 | 176.0 | 0.406 | 71.29 | 128.7 | 0.554 | 2,392 |
| 2250 | 71.41 | 165.6 | 0.431 | 71.28 | 117.3 | 0.608 | 2,242 |
| 2163 | 71.39 | 161.5 | 0.442 | 71.28 | 114.1 | 0.625 | 2,147 / 2,152 |
| 2100 | 71.38 | 157.7 | 0.453 | 71.28 | 112.3 | 0.635 | 2,085 |
| 1950 | 71.37 | 154.0 | 0.463 | 71.26 | 111.6 | 0.639 | 1,942 |
| 1854 | 71.37 | 153.0 | 0.467 | 71.25 | 111.4 | 0.640 | 1,845 |
| 1800 | 71.35 | 150.3 | 0.475 | 71.24 | 113.4 | 0.628 | 1,777 / 1,785 |
| 1650 | 71.33 | 151.4 | 0.471 | 71.22 | 109.7 | 0.649 | 1,635 / 1,642 |
| 1500 | 71.30 | 149.2 | 0.478 | 71.19 | 110.6 | 0.644 | 1,492 |
| 1400 | 71.27 | 149.6 | 0.476 | 71.16 | 107.0 | 0.665 | 1,387 |
| 1300 | 71.24 | 147.9 | 0.482 | 71.14 | 107.7 | 0.661 | 1,275 / 1,282 |
| 1200 | 71.20 | 149.4 | 0.477 | 71.12 | 104.4 | 0.681 | 1,192 |
| 1100 | 71.20 | 146.6 | 0.486 | 71.11 | 105.6 | 0.673 | 1,087 |
| 1000 | 71.19 | 149.0 | 0.478 | 71.11 | 103.7 | 0.686 | 990 |
| 900 | 67.66 | 137.8 | 0.491 | not taken (the budget) | | | 893 |
Reading (5080): the rate holds within 0.3 percent of unlocked down to 1,000 MHz on both classes and falls 5.2 percent at 900 MHz on class v4, so the knee is between 1,000 and 900 MHz, a third of the 2,963 MHz boost and lower than the 5090's (the 5080's 84 SMs have more compute headroom per unit of its memory bandwidth, so the memory wait hides the shadow down to a lower clock). Best MH per watt within the 1 percent rate tolerance: class 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 rate), class v3 at 1,000 MHz (71.11 at 103.7 W, 0.686; 66.0 W for 0.25 percent). The class v4 premium is 83.4 W unlocked and 41 W at the best points (146.6 W against 105.6 W at 1,100). The draw floors from 1,500 MHz down (about 147 W on v4, 104 W on v3) with the power governor as the only throttle reason say the clock lever is spent by 1,500 MHz on this card. Consequence per tier: a 5080 owner on class v4 locked near 1,100 MHz pays 147 W instead of 253 for 0.3 percent less rate (MH per watt up 72 percent).
What the lever is and is not: nvidia-smi exposes no voltage offset (that is NVAPI's); the clock lock walks the driver's V/F curve, which is where the watts come from; the Mac has no lever (no clock cap on Apple silicon); AMD has the ADLX tune line through igneum-gpu-telemetry or nothing. The knob goes into Ember Tune for 0.3.24 (src/ember.rs: the clock ladder continues below 45 percent of the maximum in 100 MHz steps to a 20 percent floor, the search stops at the first row more than the tolerance under the cap point's rate or on a faulted row, the best MH per watt within tolerance is the point, the fingerprint checked on every step, the result stored per card as the lock_* fields). The 5080 stock rows against the rented 5080 of 7 October (71.16 MH/s at 145 W on driver 580): the rate agrees to 0.4 percent, the watts do not (253 W here); PC 1's three power fields agree, so the difference sits with the rented card's sampler or its cap, the fleet lane's re-measure owed.

View file

@ -41,7 +41,7 @@ Versions in the table: `igneum-pow` is the Rust crate at `igneum-pow/Cargo.toml`
| 14 | Ethereum bytecode runs unchanged, with the documented differences of spec 7.1 | Homepage Build card; litepaper Building | tested by the team | as row 13; fixes `F-exec-A`, `F-exec-B` (spec 7.5) | `tools/evm-smoke/smoke.mjs`: deploy via viem, `increment`, `hashLoop`, `eth_estimateGas`, `eth_getLogs`; `tools/exec-attacks` scenarios 1 and 3; bench-log "execution layer attack fixes" | Deployment, calls, reverts, logs and gas estimates behave as viem expects; chain id 4463; the prototype pgas table gives 0.0095 to 0.028 pgas per gas, below the design's band before calibration, 3 October 2026. 4 October 2026: a transaction that would cross the block's proving budget is refused by the mempool and, if forced in, aborted and charged with its nonce advanced (25 of 25 checks; 30 of 30 malformed cases). Apple M5 Max. The `Prover` precompile, proof records and the shard planner are not in the node | none yet |
| 15 | Every block is proven, with the proof landing within about a minute at launch | Homepage stats ("~60 s to a proof"); litepaper Proving; roadmap phase 3 gate | implemented | repo `d7e1f89` (GPU proof), `e01a3cc`, `292e800`, `eedd136` (`proving/igneum-prove`: shard cutter, MPT witnesses, shard and aggregator guests); SP1 6.8.1; spec 7.2, 7.6 | `proving/windows-wsl2` (SETUP-PROVER, PROVE-BLOCK) on the RTX 5090; `igneum-prove-host --mode block` on `proving/fixtures/`; bench-log "proving v0 on the RTX 5090" and "proving: devnet v4 shards" | First GPU proof of an Igneum block, 4 October 2026, RTX 5090 (WSL2, SP1 cuda, mining paused): fixture `block-78-increment` (2 transactions), core proof 1.4 s (7.3 MB, verify 0.221 s), compressed proof 2.7 s (1.27 MB, verify 0.038 s), post-state and receipts roots identical to the node's; 15.7x and 20.6x faster than a loaded M5 Max CPU. The same day on that CPU (load 38 to 47): a three-shard block proved shard by shard and aggregated by recursion, 19 min (1,139 s) end to end, 245 to 337 s per compressed shard proof, every proof verified. What is not there: no proof is produced, carried or checked on the chain (the devnet prover is a stub that signs claims), the proving pool pays nobody (row 21), the block proven is far below one shard, and the 60-second figure remains a design target; the pass mark is the standard in `docs/benchmarks/proving-e2e.md`. Second RTX 5090 run, 4 October 2026 evening (job run-20261004-173115): a full shard at the provisional S_p (6.75 M pgas, 60.8 M cycles) executed in 1.63 s, core proof 8.3 s (18.1 MB), compressed proof 10.9 s (1.27 MB, verify 0.040 s); a two-shard block (13.5 M pgas) proved shard by shard (11.7 s and 10.0 s) and aggregated in 2.2 s, 24 s of GPU stages end to end, every proof verified, six tampered witnesses rejected. The two host defects (an abort after the upload, an idle wait that turned out to be an unbuffered 18 MB proof save through the WSL2 file bridge, 24 minutes) are fixed (ledger P20) 5 October 2026, live devnet with real transactions (bench-log "real transactions, the first non-empty shard proven and paid"): block 72704 shard 0, 29 transfers, 5,800 pgas, proven on PC 2 in 34 s, verified on the Mac in 0.297 s and paid 1.7623 IGN, 53 s after the chain block executed; of about 1,400 blocks in the 20-minute window 36 were proven (the one prover takes the newest shard assigned to it), so "every block" is not yet true; a second content shard (72803, all copies skipped) failed the native-execution veto on the exporter's block structure, fixed with fixtures the same day, the node side pending the 0.3.9 rollout 5 October 2026, evening (bench-log "proving v1"): the aggregated segment record, the chain rule and the unproven rule are implemented behind `proving_v1_activation_daa` (branch proving-v1, not on the devnet before 0.3.11); on the RTX 5090 a chain of 8 consecutive live blocks proved and aggregated by recursion in 135.6 s with the miner on the card (17 s a block, one proof of 1,272,909 bytes attesting all 8, verified in 0.04 s); the 3-node fast-time harness paid a segment record 1.0 s after submission and refused a late one after its deadline (21 checks); the devnet itself, with one prover, carried proofs for 2.4% of blocks over 30 minutes at a block-to-record latency p50 44 s, p99 52 s. The "within about a minute" holds per proven block; "every block" needs 18 mining 5090s or 6 proving-only cards at empty blocks on the measured rates, and the mandatory rule stays off until the share is one | none yet |
| 16 | A 12 GB card proves one shard in about 20 s (WITHDRAWN 5 October 2026: a 24 GB card proves a full shard at the adopted size in 4.3 s; 32 GB mines and proves) | Litepaper Proving ("The proving budget"); roadmap gate 2 | designed | spec 5.1 (Target), 7.6 (`S_p` provisional, 7,500,000 pgas = `B_p` / 4) | `PROVE-SHARD.bat` on the RTX 5090 (pending); the end-to-end standard in `docs/benchmarks/proving-e2e.md`; bench-log "proving: devnet v4 shards" | Measured on a 32 GB card, not yet on a 12 GB card. A shard at the provisional `S_p` is 60.8 M SP1 cycles on the prototype pgas table (9 cycles per pgas, 44 per EVM gas; the modexp entry about 100x its SP1 cost); on an RTX 5090 (4 October 2026 evening, job run-20261004-173115) it executed in 1.63 s and its compressed proof took 10.9 s, verified in 0.040 s, so the 32 GB card is inside the 20 s target with margin. Whether a 12 GB card proves it at all, and in what time, is the next measurement (an RTX 3060 and an RTX 5060 Ti 16 GB are on order). A per-shard time can be met by shrinking the shard, so the project does not use it as a pass mark 5 October 2026, evening (bench-log "proving v1", the S_p curve): measured on the RTX 5090 with SP1 6.8.1's GPU prover, the card to itself, 1-s nvidia-smi samples: an empty shard 13,874 MiB and 2.2 s; a full shard at the ADOPTED v1 budget (30,000 pgas, 4.7 M cycles) 20,434 MiB and 4.3 s; the full prototype shard (6.75 M pgas, 60 M cycles) 28,307 MiB and 10.8 s; beside the miner 15,670 and 30,039 MiB. No environment knob of SP1 moves the 13.9 GB floor and the GPU server has no options of its own, so on this build a 12 GB card proves nothing, a 16 GB card only empty shards, a 24 GB card the adopted full shard alone and beside the miner (22,210 MiB and 13.2 s, measured on the 32 GB card: the 5090's allocation pattern, not yet a run on a 24 GB card) and a 32 GB card the prototype shard beside the miner with 2.5 GB spare. The litepaper line now says so; the 12 GB gate returns when a prover build with a smaller floor is measured on a 12 GB card | none yet |
| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (a core as good as a GPU lane, k = 1) to 3.4x (a core three times better, k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 figure claimed against a CPU core and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`, `docs/analysis/ca3-v4-uniform.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.4x, 2.8x at launch; the shadow's premium on a 5090 81.8 W at its knee (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W; class v3 at 1,300 MHz 134.62 at 223.3 W; 7 October 2026); 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026). | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and no outside review has run yet |
| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (a core as good as a GPU lane, k = 1) to 3.4x (a core three times better, k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 figure claimed against a CPU core and never measured | `docs/analysis/chip-model-v3.md` 5 and 6; `docs/analysis/latency-shadow-2026-10-06.md`; `docs/plans/counter-asic-3-status.md`; `docs/analysis/attack-pass/f8-uniform.md`, `f4-weakday.md`, `docs/analysis/ca3-v4-uniform.md`; `docs/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); the class v4 efficiency passes (bench log "7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080", measured): the 5090 at 136.84 MH/s and 475.5 W unlocked, 134.98 at 316.3 W at a 1,400 MHz core lock, the best points class v4 at 1,200 MHz (133.80 MH/s, 305.1 W, 0.439 MH/W) and class v3 at 1,300 MHz (134.62, 223.3 W, 0.603), the premium 145 W unlocked and 82 W at the best points, the knee 1,300 MHz; the RTX 5080 (8 October 2026, the dock card of the three-card Windows rig) at 71.41 MH/s and 253.1 W unlocked under class v4 against 71.28 at 169.7 W under class v3, the best points class v4 at 1,100 MHz (71.20 MH/s, 146.6 W, 0.486 MH/W) and class v3 at 1,000 MHz (71.11, 103.7 W, 0.686), the premium 83.4 W unlocked and 41 W at the best points, the knee between 1,000 and 900 MHz; per tier: a 5080 owner on class v4 locked near 1,100 MHz pays 147 W instead of 253 for 0.3 percent less rate, MH per watt up 72 percent, the lever Ember Tune's core-clock knob in 0.3.24; 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.4x, 2.8x at launch; the shadow's premium on a 5090 81.8 W at its knee (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W; class v3 at 1,300 MHz 134.62 at 223.3 W; 7 October 2026); 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026). | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and no outside review has run yet |
| 18 | The chip resistance measurements: the program is latency-bound (random reads), not bandwidth-bound, on every card we own, and sits beyond a card's on-chip cache | Litepaper Mining ("waits on memory latency, not on maths or bandwidth"), vs RandomX; the numbers page | tested by the team | readwidth e752fc7 (`docs/plans/read-width.md`), ca2-era 78c0ee4, ca2-cache 2de19e5 (`docs/plans/hot-table.md`) | The dependent-read probes at 32 to 1,024 MiB and the hash rate per class on the three cards; the latency-bound share = rate over the probe ceiling per load | Latency-bound share at the 1 GiB dataset: RTX 5090 0.96 (v2) and 1.01 (v3), RX 9070 XT 0.87 and 0.95, M5 Max 1.01 and 1.06; wider reads do not close the AMD gap (the 9070 XT does 2.4 G dependent reads per second at every width; the 5090 goes bandwidth-bound at 64 B, share 0.58); a 32 to 96 MiB hot table is not kept resident by any card while the dataset streams (g 0.80 to 0.87 in the added form). 5 October 2026 | none yet |
| 19 | The lottery hash is sound as a hash: uniform output, deterministic, no out-of-bounds read, fuzzed; class v3 bit-exact on the three vendors | Litepaper vs RandomX ("Every number above is measured and logged"), the numbers page | tested by the team | ca2-mixer 1ab8b21 (`tests/mixer.rs`, `tests/scratch.rs`), ca2-era 78c0ee4, ca2-soundness a465881 (`docs/analysis/scratch-soundness.md`), `igneum-pow/tests/packs.rs` | The crate suite (53 + 4 + 19 + 7), the Metal fuzz, edge, stats and determinism runs on the v3 construction, the pack vectors and 2^24 fingerprints on Metal, Apple OpenCL, the RTX 5090 and the RX 9070 XT, the 1,024-hash CPU re-check per card | Class v3 (mixer x8 + era): 200-program fuzz 200 of 200 on Metal, every tenth on Apple OpenCL; the pinned v3 packs 3/3 + 3/3 and 96 of 96 lanes on Metal and Apple OpenCL; the six era packs' fingerprints equal on the three vendors (PC 1 job run-ca2-era-pc1-20261005, 5 October 2026); the v2 exports byte-identical on the v3 crate; the final-class PC rows and the G2 re-check: job run-ca2-era-pc1b-20261005 (pending at the time of writing) | none yet |
| 20 | No premine, no pre-sale, no allocation: every coin is minted by the schedule and every coin goes to the block producer (80%) and the proving pool (20%) | Homepage stats and Economics tiles; litepaper Supply, Economics | implemented | repo `6ac80a3`; fork "igneum-node devnet v0"; `consensus/core/src/igneum.rs`, `coinbase.rs` | `cargo test -p kaspa-consensus-core igneum` (8 pass: subsidy table, ramp, split, cap) and `cargo test -p kaspa-consensus coinbase` (8 pass); `igneum-miner inspect 40`; bench-log "igneum-node devnet v0" | Coinbases on the devnet: 80/20 exact on 39 of 39 single-payee blocks, the 20% to the `igneum-proving-pool-v0` output; the per-second schedule sums to under the 4,000,000,000 cap by less than 100 coins; 3,168,808,781 units per DAA second in years 0 to 2, halving at 63,115,200 DAA s. 3 October 2026, Apple M5 Max. The devnet genesis carries no allocation; the mainnet genesis does not exist yet, so the claim is about the code and the stated rule, not a launch that has happened | none yet |
@ -98,6 +98,12 @@ Versions in the table: `igneum-pow` is the Rust crate at `igneum-pow/Cargo.toml`
| 17 | 136 MH/s at 350 W (class v3) | the class v4 efficiency pass added: 136.84 MH/s at 475.5 W unlocked, 134.98 MH/s at 316.3 W locked, control 134.68 MH/s at 228.0 W | the 5090 efficiency pass |
| rule 1 | "the repository is private until the public testnet" | the ceiling is stated without the repository's state | the repository links moved to git.igneum.network |
## What moved on 8 October 2026
| Row | Before | After | Why |
|---|---|---|---|
| 17 | the 5090's efficiency pass | the RTX 5080's clock-lock pass beside it (71.41 MH/s at 253.1 W unlocked, 71.20 at 146.6 W at 1,100 MHz, the premium 83.4 W to 41 W) and the per-tier reading | the bench log's efficiency-passes entry |
## What would move a row
| From | To | What it takes |

View file

@ -2512,7 +2512,7 @@ Owed (recorded, not run, by the founder's word): G2 (the CPU verifier on 1,024 h
Owed (recorded, not run, by the founder's word): G2 (the CPU verifier on 1,024 hashes per card) on the amended stream; G3 (the Metal fuzz, edge, stats and determinism runs) on the amended stream; the hash-rate ladder re-measure on the M5 Max and the RTX 5090 (the amendment changes the base program's source draws, not the op mix or the load count, so the latency-bound rows of `docs/analysis/latency-shadow-2026-10-06.md` are expected to hold within their spread; unmeasured); AMD (the RX 9070 XT, PC 1); the 2019-class verifier core (O-1.14); F8's phase E (the 64-seed dynamic census) on the amended stream, which is the attack-pass lane's and the test of the per-op table. The row reads FIXED-AND-PASSED only after phase E passes against the amended class.
Status: Fixed in part, finding bounded, stated (7 October 2026, night, the Counter ASIC lane's words): class v4 sub-version 3 (igneum-pow 017e7037, the audit-freeze tag) is frozen with the dataflow rule, the shared-operand rule, the 0.98 ratio and the total draw; the in-house pass's F8 re-gate reads 60 of 64 seeds under 1.2x with the four-seed tail accepted by the coordinator as the window model's unattributed residue (no chip consequence); the pass then attributed the class by value (eight live hot sets at 1.54x to 2.24x in the lowest 30 of 29,032 accepted programs, each about 1 MB of items at 0.3 percent of reads, 1.002x to a chip); class v5 (1c420786, frozen 21:53 UK) carries the fix as rule (c'''), the per-site distinct-index floor at 0.995 on the state flag (its census refuses 2.435 percent of accepted programs; seven of seven live hot sets refused at 0.9821 to 0.9919; the eighth's ratio owed tonight), with a named residual (three mild shadow-block-written concentrations at 0.9992 to 0.9997, about 1.0004x, a value-level test in the next class); the record is `docs/plans/counter-asic-3-status.md` section 7c and the class v5 design's section 14. The eighth live hot set (seed 122960, id 4be7393ab6c84802, the deepest found: X_f +0.111 percent, 1.54x the window model, its hottest item at 475,616 reads from an all-ones source) reads minimum site 12 at 0.9824 at the acceptance's own 2^20 sample (live 0.9822), refused by class v5's (c''') floor at 0.995; so the floor refuses eight of eight live hot sets by X_f at or above f found in the tail of 88,051 accepted programs (minimum sites 0.9821 to 0.9919) against 0 hot sets in 20 random programs; what it misses stays the three mild shadow-block-written concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x to a chip, the value-level test in the next class (22:41 BST; the logs under `docs/analysis/cryptanalysis/logs/adv-accept/` on branch adv-accept; the v5 design's section 14). The public sentence (the coordinator's wording, 7 October 2026, night; the count moved to nine at 01:13 BST on 8 October when the ninth live hot set, seed 228763 from a non-saturated source, read 0.9809 and was refused): nine of nine 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 reason, read by the in-house pass (adv-cache-2) and the class v5 lane together: the distinct-index count at 2^20 sees concentration on few word indices whatever their source, saturated or not (the hot sets put about 3 percent of a site's reads on 512 indices, so the ratio falls to 0.981 to 0.992; the final tally 9 of 9 live hot sets and both single-item programs refused, 7 clean-live programs refused among the 12 deepest, 3 mild residuals missed) and not a diffuse excess over the top 0.1 percent of items (16,384 items), which is what the era-stride low-bit law produces (13 of 27 drawn-era programs carry a site over 1.04x, 8 over 1.2x, worst 1.75x; 0 of 29 refused at the 2^20 sample, minimum sites 0.9965 to 1.0000); its chip value is about 1.0024x at the worst site read, under this row's bound by an order; the row for it is AP-F8-6. The RTX 5080 grid's knee is not in tonight; X37 keeps the 5080's stock premium only.
Status: Fixed in part, finding bounded, stated (7 October 2026, night, the Counter ASIC lane's words): class v4 sub-version 3 (igneum-pow 017e7037, the audit-freeze tag) is frozen with the dataflow rule, the shared-operand rule, the 0.98 ratio and the total draw; the in-house pass's F8 re-gate reads 60 of 64 seeds under 1.2x with the four-seed tail accepted by the coordinator as the window model's unattributed residue (no chip consequence); the pass then attributed the class by value (eight live hot sets at 1.54x to 2.24x in the lowest 30 of 29,032 accepted programs, each about 1 MB of items at 0.3 percent of reads, 1.002x to a chip); class v5 (1c420786, frozen 21:53 UK) carries the fix as rule (c'''), the per-site distinct-index floor at 0.995 on the state flag (its census refuses 2.435 percent of accepted programs; seven of seven live hot sets refused at 0.9821 to 0.9919; the eighth's ratio owed tonight), with a named residual (three mild shadow-block-written concentrations at 0.9992 to 0.9997, about 1.0004x, a value-level test in the next class); the record is `docs/plans/counter-asic-3-status.md` section 7c and the class v5 design's section 14. The eighth live hot set (seed 122960, id 4be7393ab6c84802, the deepest found: X_f +0.111 percent, 1.54x the window model, its hottest item at 475,616 reads from an all-ones source) reads minimum site 12 at 0.9824 at the acceptance's own 2^20 sample (live 0.9822), refused by class v5's (c''') floor at 0.995; so the floor refuses nine of nine live hot sets by X_f at or above f found in the tail of 269,250 accepted programs (minimum sites 0.9809 to 0.9919; the ninth, seed 228763 from a non-saturated source, at 0.9809 on 8 October 2026) against 0 hot sets in 20 random programs; what it misses stays the three mild shadow-block-written concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x to a chip, the value-level test in the next class (22:41 BST; the logs under `docs/analysis/cryptanalysis/logs/adv-accept/` on branch adv-accept; the v5 design's section 14). The public sentence (the coordinator's wording, 7 October 2026, night; the count moved to nine at 01:13 BST on 8 October when the ninth live hot set, seed 228763 from a non-saturated source, read 0.9809 and was refused): nine of nine 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 reason, read by the in-house pass (adv-cache-2) and the class v5 lane together: the distinct-index count at 2^20 sees concentration on few word indices whatever their source, saturated or not (the hot sets put about 3 percent of a site's reads on 512 indices, so the ratio falls to 0.981 to 0.992; the final tally 9 of 9 live hot sets and both single-item programs refused, 7 clean-live programs refused among the 12 deepest, 3 mild residuals missed) and not a diffuse excess over the top 0.1 percent of items (16,384 items), which is what the era-stride low-bit law produces (13 of 27 drawn-era programs carry a site over 1.04x, 8 over 1.2x, worst 1.75x; 0 of 29 refused at the 2^20 sample, minimum sites 0.9965 to 1.0000); its chip value is about 1.0024x at the worst site read, under this row's bound by an order; the row for it is AP-F8-6. The RTX 5080 grid's knee is not in tonight; X37 keeps the 5080's stock premium only.
### AP-F8-3. The deterministic last-resort program is handed to the chain unchecked, and the rule would refuse 9.0 percent of such programs
@ -2545,7 +2545,7 @@ Status: Fixed (7 October 2026, night): the id and its derivation text come from
### AP-F8-5. The public specification did not describe the shipped acceptance rule (documentary; no object change)
"An implementation written from docs/spec/01-lottery-hash.md section 1.4.6 at 017e7037 mines a different program from the node on 264 of 400 epochs." Found by the in-house pass adv-accept-3 (report-acceptance-rule-3.md at 0c150e3c, finding 3, section 6.2, 7 October 2026, night): the text described (a), (b) and (c) with a 32-attempt cap and an id without a suffix, while the code adds (a') with the shared-operand rule, (c'), (c'') at 2^20 evaluations, the 256-attempt cap keyed on the class v4 shape, the total draw with the last resort, generator 4 and the sub-version suffix, and executes the 256-instruction shadow block 27 times per iteration inside the acceptance interpreter. Measured (sweep 97, 400 seeds, 1,317 attempt verdicts): 759 verdicts differ (758 the code rejects and the text accepts: (a') 733, (c'') 15, (c) 10; 1 the other way, the shadow block changing a (c) statistic); 264 of 400 seeds choose another attempt; the parts the text did carry, (a) and (b), agree on every row.
Status: Spec fixed (7 October 2026, night, the site audit lane by main's order, branch spec-accept-23): sections 1.4.3 and 1.4.6 of `docs/spec/01-lottery-hash.md` rewritten to the shipped rule at igneum-pow 017e7037 with every constant named and every order of operations stated (1.4.3: the two per-register states of the draw, the dataflow table, the shared-operand rule, the shadow block's draw and the draw counts per class; 1.4.6.1 to 1.4.6.6: (a) cyclic over two passes, (b), (a') to the fixpoint then a checking pass, (c) with the shadow executed and its limits in a table, (c') and (c'') with the integer form of the ratio compare, the attempts and the two caps with the measured per-part rates, the last resort stated as unreachable and unverified, the program id with the generator-4 suffix, a constants table in the shape the crate's read-back test parses, the pinned ids a reader must reproduce); section 1.7 gains the shadow block's execution; section 1.13.1 names the two consumed era draws. The hash lane's `igneum-pow/tests` read-back test parses the two tables against the crate's `pub const` items and derives every pinned id (its landing is the row's check; AP-F8-4 carries the derivation-text half of the same finding).
Status: Spec fixed (7 October 2026, night, the site audit lane by main's order, branch spec-accept-23): sections 1.4.3 and 1.4.6 of `docs/spec/01-lottery-hash.md` rewritten to the shipped rule at igneum-pow 017e7037 with every constant named and every order of operations stated (1.4.3: the two per-register states of the draw, the dataflow table, the shared-operand rule, the shadow block's draw and the draw counts per class; 1.4.6.1 to 1.4.6.6: (a) cyclic over two passes, (b), (a') to the fixpoint then a checking pass, (c) with the shadow executed and its limits in a table, (c') and (c'') with the integer form of the ratio compare, the attempts and the two caps with the measured per-part rates, the last resort stated as unreachable and unverified, the program id with the generator-4 suffix, a constants table in the shape the crate's read-back test parses, the pinned ids a reader must reproduce); section 1.7 gains the shadow block's execution; section 1.13.1 names the two consumed era draws. The hash lane's `igneum-pow/tests` read-back test parses the two tables against the crate's `pub const` items and derives every pinned id (its landing is the row's check; AP-F8-4 carries the derivation-text half of the same finding). Fixed on two measurements by the finding lane: Q4c at master 8b834634, before the closed-form dataset was stated, a text-only implementation of sections 1.3, 1.4.2, 1.4.3, 1.4.6, 1.6, 1.7 and 1.13.1 re-derived the 400 epoch programs of sweep 97 under the Devnet 3 era with 0 of 400 differing on any field and one function (`dataset_elem`) taken from the crate (report section 6.5, log 983-textderive-8b834634.tsv); Q4d at master 56eebc0d, with `dataset_elem` written from 1.4.6.4 and its two pinned vectors reproduced, 0 of 400 differing with 0 crate imports (report section 6.6, log 984-textderive-56eebc0d.tsv, 8 October 2026, 01:5x UK).
Answer: Correct, and the largest divergence source the pass found was documentary. The rule the chain runs was right; the text a second implementer would read was three sub-versions behind it. The fix is the text, written to the code line by line, and a test that fails when the two drift again.

File diff suppressed because one or more lines are too long

View file

@ -174,3 +174,19 @@ The 0.3.23 node's heights move Devnet 3's digest to ba75bf6f, and the one-box-at
**The build-server lane dark (read at 01:04 BST):** the dl host's jobs file was last published at 23:05 BST and carries no 0.3.24 host job for PC 1 and no 0.3.23 take 3 for PC 2 (its last jobs there: 0.3.23's host build and upload, take 2's ISCC log read); the lane answered nothing after 00:17 BST to asks at 23:43, 00:57 and 01:04. With it sit the c9e385eb and dfbd1e10 hands, seed and Windows pairs, the 0.3.24 hive with the v5 kit, the 0.3.24 Windows chain, 0.3.23's Windows entry (and so the card), and its tooling commits (the detached-helper rule, the inline-rm check, the publisher's digest gate, the alias assertion, push-inputs' overrides). Rulings by the shipper, main asked to confirm: "slot void" to the hash lane at 01:05 BST (PC 1's lock-free queue moves: the v5 kit fetch, the 9070 XT v5 bench, the CA4 unlocked rows); the fleet moves EVERY Devnet 3 node from the node lane's dfbd1e10 pair (native glibc 2.39, the fleet's boxes' class), as dn3-g1 and g2 did at 22:30, aa8c2978 into the pack gate's list, build-1's three nodes restarted by the fleet itself on the minute; the 0.3.24 deploy publishes the Mac entry alone if no hive exists by the minute (the HiveOS alias stays on 0.3.23 and that gap is recorded; the public Mac alias moves in the same publish by main's rule); the Windows app chain waits for daylight or another builder, so tonight's 0.3.24 is Mac (and HiveOS if the shipper takes the package on main's word), with the 0.3.23 and 0.3.24 Windows entries and the card behind them. Main's word asked on three points: the shipper taking the hive and the Windows node pair through build-remote (the lease tool or plain), the Windows app chain's owner and hour, and take 3's publisher.
**The 0.3.24 class v5 kit, one line for a reader diffing kits (the Counter lane, 01:1x BST):** the 0.3.24 packs are packs-ca3-v5-20261007T183921Z.zip, sha256 e6c088bb, the kits lane's export byte-identical to the frozen igneum-pow 1c420786 the pin pairs with (the v5-dn3-epoch0 pack, program id e5a4ac5978462156, fingerprint 82b19cbde8557ea5); packs-ca3-v5-20261007T221001Z.zip (4aaf9b9e, from class-v5 7f58af97) carries the same three packs, ids, kernels and leaves and differs only in the kit host code beside them (the bench lanes' kit for the fingerprint jobs, not the miners' pack set); the next export changes the program_id_derivation TEXT field only (the "sub/" suffix wording), the ids unchanged. The fleet places e6c088bb on every Devnet 3 box; the hive carries it.
## 19. 01:41 BST: no move file, two lanes dark
**dfbd1e10 fully gated:** the fast-time SUMMARY PASS cross-0324-dfbd1e10 at 01:12:57 BST (the shipped binaries; 12 of 12 program ids equal to the CPU verifier's, the stale node refused 95 of 95, the restart across the v5 boundary resynced in 36.2 s with its own mining held, four sinks equal), on top of every box gate green at 01:01:52; the kit's fingerprint 82b19cbde8557ea5 equal on four platforms (Metal, Apple OpenCL, CUDA, and the RX 9070 XT at 01:16:14 BST on PC 1, the v4 control PASS; Intel held with PC 2); class-v5 091a0758 (text arm and page rows, ids unchanged) landed at 01:40 as a post-freeze commit and is 0.3.25's with 8ca66afa; 0.3.24 pairs with 1c420786 as published.
**The clock line (01:41 BST):** the fleet published no dfbd1e10 move file: build-1's /fleet/move.json still names commit 2720d8d2 with the 22:30 BST minute; no FETCHED count, no named minute, no 0.3.24 DAA reader for the node lane, no answer on build-1's three old-object nodes, no 22:59 or 23:59 BST proven-share line (asks at 01:05, 01:16, 01:41; the fleet lane's last line was its 22:4x report). With the build-server lane dark since 00:17, the two lanes that could move the fleet are silent, and the two that remain cannot (the node lane holds no box keys for the pods; the shipper holds the Mac). So the 02:00 BST minute cannot hold and the 02:53 ceiling (DAA 32,400) stands only if a signed move file lands within minutes and the 34 pullers fetch inside forty. Main's word asked on: (a) waking or replacing the fleet lane tonight (the puller is self-contained: a new signed move file at build-1's /fleet/ naming the node-lane pair and a minute is all the boxes need); (b) otherwise a fourth re-cut of the floor from a morning minute main names, the 0.3.24 Mac entry standing down until then (rule 5: no app alone on b1ba7822); (c) the four words from 01:06 and 01:20 (the hive and the Windows node pair by the shipper; the Windows app chain's owner and hour; take 3's publisher; "PC 2 clear" on the dark lane's ground). The attack-pass interim reads at 01:55 regardless; PC 1's lock-free queue runs (the CA4 unlocked rows from 01:17 BST). The update-return lane's PC 2 S4U proof and PC 1 re-probe stand on take 3, which never ran.
**Route (A) staged, not placed (01:50 BST):** the dfbd1e10 pair tarball on build-1 and served (fleet/dfbd1e10-node-lane.tgz, 27,495,110 B, sha256 e59ed0e6; igneumd 4870ccf2, igneum-miner aa8c2978); the move file (id mdfbd-1, commit dfbd1e10, want_version igneumd/2.1.0-dfbd1e10, want_digest b1ba7822, both pair slots on that tarball, at_epoch 0) written and signed with the fleet key in the shipper's scratch (r0324/move), the signature verified against the fleet's public key in the puller's namespace; nothing on /fleet/ changed, no box fetched. **The gap that stops (A) as the file alone:** every box's pack gate (box-dn3.sh's PAIR_MINER_SHA16 default list 07246920, c29f33bb, dfdc6883, fb147dd1) lacks aa8c2978 and the puller restarts box-dn3.sh from the box's running environment without reading the move file's miner sha into it, so a move by the file alone restarts every node on b1ba7822 with every miner refused as "not a paired miner" (the 22:31 shape on all 34 boxes at once, chain rate zero until a hand fixes the list); the fix before the minute is one line per box over ssh with the fleet's keys and tooling (on this Mac under ~/igneum-fleet; the Vast proxies limit reach), the fleet lane's work or, on main's word, the shipper's. **Rule for the puller (0.3.25 tooling):** the move file names the pair's miner sha and the puller carries it into PAIR_MINER_SHA16 for the restart, so a pair's miner is paired by the file that moved it, never by a list a hand keeps. **The node lane's three facts (01:5x BST):** a 0.3.24 reader node on build-1 (dfbd1e10's binary, loopback JSON RPC 28690, never mines) dials ten fleet nodes and follows the chain from the move, so the crossing read waits on no fleet reader; the fourth re-cut is one script run from a named minute (about 20 minutes to the pin plus 14 for the fast-time pair); a morning minute later than about 12:50 BST on 8 October puts the floor at or above 79,200 (the difficulty v3 height) and moves the three heights up with it in the same commit.
**Route (A) ready on one word (01:56 BST):** the gate script (r0324/move/pair-gate-aa8c2978.py: one line per box putting aa8c2978 into the pack gate's list in env-last and box-dn3.sh's default, dry run by default, apply on a literal argument, nothing restarted) dry-ran over the fleet's inventory with the fleet's Box helper, reads only: 33 of 35 Devnet 3 boxes reachable, every one on the old list (fb147dd1 last, 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 with each gate read back. The F9/F1 interim at 01:55 BST read zeros across the line (71,292 seeds drawn, 0 exhausted, 0 panics, max attempt 30; F1 at 2 h 23 min with 0 redundancy failures), so the move's gate clears from the attack-pass lane; the full 10^5 and F1's result land as the record lines after. On "A": the gate line 02:00, the move file placed at at_epoch 0 02:02, the last FETCHED about 02:05, the minute 02:15 BST (publish DAA about 30,100, inside the 02:53 ceiling), the Mac entry at the minute, the fleet lane stopped and respawned after. Absent the word by 02:15: the stand-down, the fourth re-cut from a morning minute before 12:50 BST, the Mac entry held.
## 20. The night's outcome (02:58 BST, 8 October)
Main's word on route (A) or (B) did not come (asked 01:41, 01:50, 01:53, 01:56 BST), so nothing applied, nothing placed, no minute: build-1's /fleet/move.json still serves the 22:30 BST 2720d8d2 move (m2720-1); every Devnet 3 node is on the 0.3.23 pin 2720d8d2, digest ba75bf6f (dn3-j1 behind its dead proxy unverified since 22:30); the 0.3.24 Mac entry stands staged (DMG 1aa301cc, both token folders) and unpublished; the live manifest is 0.3.23 (Mac and HiveOS), the 0.3.23 and 0.3.24 Windows entries and the Discord card unpublished; the shipper's stand-down at 02:15 held by default (its line was not sent at 02:15, the shipper's miss; the state was unchanged). **Finding:** build-1's Devnet 3 seed (the --go process on 26631 with JSON RPC 27632, the node lane's DAA reader) is DOWN at 02:56 BST (no process with --appdir=/home/build/dn3seed; node1-dn3 26671 and the observer 26651 run on 2720d8d2; the node lane's 0.3.24 reader on 28690 runs); the last DAA read held is 25,169 at 00:52:38 BST, and at 1.0 DAA/s the chain passed 32,400 at about 02:53 BST, so 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 in the same commit); the fleet's nodes dial 26631, so the seed's restart on the pin is part of the morning's move. **The morning's shape on main's word:** the fleet lane and the build-server lane respawned (the puller and the gate script r0324/move/pair-gate-aa8c2978.py ready; 33 of 35 boxes reachable at 01:55); build-1's seed restarted on the pin; the pin re-cut from the minute; the pairs and the hive with the v5 kit e6c088bb; the one-minute move with the gate line first; the Mac entry at the minute; the Windows chain (the 0.3.24 host on PC 1, the installer and smoke on PC 2 in the simplest shape, 0.3.23's take 3 first) and the card after; the attack-pass record lines (F9's full 10^5, F1's census) as they land. The night's clean lines: the interim zeros at 01:55 (71,292 seeds, 0 exhausted, 0 panics, max attempt 30); the kit's fingerprint equal on four platforms; PC 1's lock-free queue (the 9070 XT G1 14 of 14 and its v5 fingerprint, the family rows, the 5080 grid through the cleared helper, the CA4 rows); dfbd1e10 fully gated with the fast-time PASS. Three rules from the night for release-rules: a digest-moving release's minute is named from the pairs on the boxes, never from a clock the pairs have not met (the three lost floors); a lane that owns a gate in the critical path answers within ten minutes or its work is reassigned by main, not waited on (the two dark lanes); the move file carries the pair's miner sha into the pack gate (the puller rule above).
**build-1's seed, the reading and the repair (03:0x BST):** /home/build/dn3seed.log ends at 02:09:05 BST at DAA 29,732 mid-stream with no stop, shutdown or panic line (an igneumd stop writes "igneumd has stopped"), so it was killed abruptly; it ran under nohup from a shell, so no journal names the killer, and the OOM record needs sudo (the morning's build-server lane reads it); the datadir intact (13 GB). The node lane's DAA reads 25,169 (00:52:38) and 28,906 (01:55:09 BST) came from it while it lived; the chain read 32,659 at 02:57:50 BST from node1-dn3's JSON on 28670 (the observer 32,660), past 32,400 at about 02:53 as computed. Restarted on the shipper's word at 03:00:09 BST on the kept datadir with the 2720d8d2 hands pair (igneumd f2cf6a87; the same flags; setsid nohup with stdout appended behind a dated banner, the stop line in its own log; the restart script at /tmp/dn3seed-restart.sh for the morning's move): digest ba75bf6f, object version 7, the N15 lines (resumed from the exec snapshot at tip 11,901, the records continuous), DAA 32,905 in step with node1-dn3, 22 peers at 03:02 (20 inbound, the fleet's dials returning; 38 before the kill). A repair of the hub the fleet dials, not a release change; the DAA reads come from 27632 again. dn3-floor-cut.sh (the fourth re-cut from a named minute: the DAA from 28670, the floor = the publish DAA plus 7,200 to the next 3,600, the commit, both mirrors, the gate set, about 20 minutes plus the fast-time pair's 14; the latest minute before the heights move is about 12:50 BST) stands ready for main's minute.

View file

@ -223,10 +223,27 @@ The program is interpreted for `ACCEPT_UNITS = 64` units of 32 lanes, `ACCEPT_HA
|---|---|
| Base nonces | the first 64 values of SplitMix64 seeded with `FNV-1a-64("igneum-accept/" || seed words as little-endian bytes)`, each `low32(next()) AND NOT 31`; unit `u` runs lanes `base_u + 0 .. base_u + 31` |
| Init words `I` | the program's eight seed words (section 1.6) |
| Dataset | `dataset_elem(idx, S[0], S[1])` of `verify.rs` (the closed form of the version 0.1 packs; `S[0]`, `S[1]` are seed words 0 and 1) at `ACCEPT_DATASET_LOG2 = 28`, 2^28 words, `MASK = 0x0fffffff`, whatever the live dataset size |
| Dataset | the closed form `dataset_elem(idx, S[0], S[1])` below (the version 0.1 packs' stand-in; `S[0]`, `S[1]` are seed words 0 and 1) at `ACCEPT_DATASET_LOG2 = 28`, 2^28 words, `MASK = 0x0fffffff`, whatever the live dataset size |
| Address of a load with source value `x` | without an era `idx = x AND MASK`; under an era the form of 1.13.1 at `D = 28`: `k = min(k_off, 2)`, `y = rotl(x * M, R)`, `idx = ((y AND (MASK >> k)) OR ((o AND (2^k - 1)) << (28 - k))) AND MASK` |
| Execution | section 1.7 exactly, the shadow block included under class v4: after instruction 63 of every iteration the 256 shadow instructions run 27 times with that iteration's `sel` (sub-version 3, AP-F8-3; until it, the test ran the base instructions alone and judged a program the chain never hashes) |
The closed form, 32-bit wrapping arithmetic throughout (`verify.rs`, `dataset_elem`; the rule's only dataset, never the chain's):
```
dataset_elem(i, S0, S1):
x = i XOR S0
x = x * 0x9E3779B1
x = x XOR (x >> 15)
x = x + S1
x = x * 0x85EBCA77
x = x XOR (x >> 13)
x = x * 0xC2B2AE3D
x = x XOR (x >> 16)
return x
```
A load reads `dataset_elem(idx, S[0], S[1])` and XORs it into `dst`, as 1.4.1 reads `dataset[idx]`. Test vectors, pinned by `igneum-pow/tests/spec_readback.rs`: `dataset_elem(0x00000fed, 0x9E3779B9, 0x7F4A7C15) = 0x5c7dabd2`; `dataset_elem(0x0fffffff, 0x00000000, 0x00000000) = 0x7662c1ec`. The register initialisation is section 1.6 with `I` the seed words; `sel`, the instruction semantics and the output fold are section 1.7.
During the run: a `load` whose 32 lanes compute one address in any unit rejects the program (`LaneConstantSite`, checked at every load of every iteration and unit, the shadow block has none). After the run, over the 2,048 final register states and 2,048 outputs, in this order:
| Check | Limit | Reject |
@ -245,7 +262,7 @@ A load site is a load's ordinal within the iteration, 0 to 15, in instruction or
(c'') The distinct-index ratio. The one test that runs past the 64 units: `ACCEPT_UNITS_DISTINCT_V4 = 4,096` units, the first 4,096 base nonces of the same stream (the 64 of (c) are its first 64), so every site is evaluated `N = 2^20` times. For each site `s`, `d_s` is the number of distinct `idx` values it computed over those evaluations, `W_s = 2^28 >> min(k_off_s, 2)` is its window in words, and the expectation of a uniform source on that window is `E_s = N - N^2 / (2 W_s)` (an integer at these constants: 2^20 - 2^11, 2^20 - 2^12, 2^20 - 2^13). The site's ratio `d_s / E_s` must reach `MIN_DISTINCT_RATIO_V4 = 0.98`; the first site under it, in order, rejects the program (`LowEntropySite`). The implementation compares in f64; the integer comparison `50 d_s >= 49 E_s` gives the same verdict for every value of `d_s` at these constants (the margin is at least 0.32 of a count; adv-accept-3 section 6.1), and an implementation MAY use it. The floor sits in a measured gap: the accepted population's minimum is 0.983 to 0.989 and the rejected population's maximum 0.966 over 20,275 draws of two lanes, so a floor anywhere in 0.967 to 0.988 gives the same verdicts on every program seen (adv-accept-3 section 6.4). `MAX_SOURCE_REPEAT_V4 = 8` exists in the file and is not part of the rule.
What the parts catch: (a) the empty-list fallback of 1.4.3; (b) registers that saturate to all ones (2.4 percent of class v2 candidates); (c) zero-absorbing register sets, lane-constant load sites, output bias and value-level address repeats (2.1 percent); (a') the cross-hash hot set of a load fed by `or`, `mul` or `mulhi` through the iteration boundary (AP-F8-1); (c') the same set delivered any other way; (c'') a low-entropy index band the lineage rules cannot see (F8's p23, p18, p19, p15, p56). Why (c) uses the closed form: the test is a pure function of the program (no cache, no day), costs about 3 ms on one core for the 64 units and 2.8 s with (c'') on the chosen candidate, and the census checked on 100,000 class v2 programs that its verdict agrees with the memory-hard dataset's on all but 39 threshold-edge cases (section 7.3). Not in the rule, and why: a contraction as the last write (80 percent of programs) and the `or` count are too common and (c) already catches the cases that matter; the load critical path is a hash-rate question, not a weakness; a 2^24 stage of (c'') does not separate the open F8 tail (p4, p8, p10, p34 read the clean seeds' values there; ledger AP-F8-1).
What the parts catch: (a) the empty-list fallback of 1.4.3; (b) registers that saturate to all ones (2.4 percent of class v2 candidates, the class v2 census); (c) zero-absorbing register sets, lane-constant load sites, output bias and value-level address repeats (2.1 percent of class v2 candidates); (a') the cross-hash hot set of a load fed by `or`, `mul` or `mulhi` through the iteration boundary (AP-F8-1); (c') the same set delivered any other way; (c'') a low-entropy index band the lineage rules cannot see (F8's p23, p18, p19, p15, p56). Under the shipped rule, measured on 20,000 seeds (adv-accept's attempts census on sub-version 3, 42,711 rejected candidates, 8 October 2026): 68.1 percent of candidates are rejected, flat across attempts; of the rejections (a') takes 83.5 percent, (a) 11.6, (b) 3.0, (c'') 1.1, (c) constant bits 0.4, (c) saturated finals 0.3, (c') 0.05 and (c) the distinct sum 0.04; the accepted attempt is 2.1 on average and 28 at most, 0 seeds of 20,000 reached the cap, and 256 consecutive rejections have probability about 2 x 10^-43. Why (c) uses the closed form: the test is a pure function of the program (no cache, no day), costs about 3 ms on one core for the 64 units and 2.8 s with (c'') on the chosen candidate, and the census checked on 100,000 class v2 programs that its verdict agrees with the memory-hard dataset's on all but 39 threshold-edge cases (section 7.3). Not in the rule, and why: a contraction as the last write (80 percent of programs) and the `or` count are too common and (c) already catches the cases that matter; the load critical path is a hash-rate question, not a weakness; a 2^24 stage of (c'') does not separate the open F8 tail (p4, p8, p10, p34 read the clean seeds' values there; ledger AP-F8-1).
#### 1.4.6.6 Attempts, the cap, the last resort and the program id

View file

@ -6,6 +6,7 @@
//! row's generator (3 for "class v3", 5 for "generator 5", else 4) equals the id, and, for a class v4 row, that the
//! chain's own draw with the era seed (the same bytes unless the Note names another) accepts at that attempt.
//! The constants half is `tools/ci/spec-constants-check.mjs` (the pre-push gate; no build).
use igneum_pow::verify::dataset_elem;
use igneum_pow::generator::{attempt_words, generate_from_seed_bytes_program_class, program_id, ProgramClass, GENERATOR_VERSION_V3, GENERATOR_VERSION_V4};
use std::path::PathBuf;
@ -113,3 +114,30 @@ fn the_chain_draw_accepts_each_class_v4_row_at_its_attempt() {
}
assert!(drawn >= 1, "no class v4 row to draw");
}
/// The closed-form dataset of 1.4.6.4: every `dataset_elem(a, b, c) = d` vector the spec prints is the crate's value.
#[test]
fn the_closed_form_vectors_of_the_spec_are_the_crates() {
let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(SPEC);
let text = std::fs::read_to_string(&path).unwrap();
let mut n = 0;
for (k, line) in text.lines().enumerate() {
let mut rest = line;
while let Some(i) = rest.find("dataset_elem(0x") {
let tail = &rest[i + "dataset_elem(".len()..];
let Some(close) = tail.find(')') else { break };
let args: Vec<u32> = tail[..close].split(',').map(|a| u32::from_str_radix(a.trim().trim_start_matches("0x"), 16).unwrap_or_else(|_| panic!("{}:{}: bad vector argument {:?}", SPEC, k + 1, a))).collect();
let after = &tail[close + 1..];
if args.len() == 3 && after.trim_start().starts_with('=') {
let eq = after.find('=').unwrap();
let hex: String = after[eq + 1..].trim_start().trim_start_matches("0x").chars().take_while(|c| c.is_ascii_hexdigit()).collect();
let want = u32::from_str_radix(&hex, 16).unwrap_or_else(|_| panic!("{}:{}: bad vector value", SPEC, k + 1));
let got = dataset_elem(args[0], args[1], args[2]);
assert_eq!(got, want, "{}:{}: dataset_elem({:#010x}, {:#010x}, {:#010x}) is {:#010x} in the crate, {:#010x} in the spec", SPEC, k + 1, args[0], args[1], args[2], got, want);
n += 1;
}
rest = &rest[i + 1..];
}
}
assert!(n >= 2, "the spec prints {n} closed-form vectors; two are expected");
}

View file

@ -222,7 +222,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v
<main id="main" class="wrap">
<div class="head">
<div class="breadcrumb"><a href="/">Igneum</a><span>/</span><span>Evidence</span></div>
<div class="eyebrow"><span class="line"></span>31 claims · 5 labels · 7 Oct 2026</div>
<div class="eyebrow"><span class="line"></span>31 claims · 5 labels · 8 Oct 2026</div>
<h1>Evidence<span class="accent">.</span></h1>
</div>
<p class="note">Every claim the homepage and the litepaper make, one row each, with one of five labels: <b>designed</b> (a decision, no code), <b>implemented</b> (code with passing test vectors), <b>tested by the team</b> (measured by the project on a named machine, in the engineering log), <b>reproduced externally</b> (a third party ran the published command and got the published result) and <b>reviewed independently</b> (a named outside reviewer published a finding on that version). Nothing on this chain has been reproduced externally or reviewed independently; every row says so. A label belongs to the exact version in the row, and an audit of one version never covers a newer one. The 12-node cloud network of 4 October 2026 is the project's own, so its rows are tested by the team, not reproduced externally.</p>
@ -254,7 +254,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v
<tr data-status="tested by the team"><td class="n">14</td><td class="claim">Ethereum bytecode runs unchanged, with the documented differences of spec 7.1<div class="where">Homepage Build card; litepaper Building</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">as row 13; fixes <code>F-exec-A</code>, <code>F-exec-B</code> (spec 7.5)</td><td><code>tools/evm-smoke/smoke.mjs</code>: deploy via viem, <code>increment</code>, <code>hashLoop</code>, <code>eth_estimateGas</code>, <code>eth_getLogs</code>; <code>tools/exec-attacks</code> scenarios 1 and 3; bench-log "execution layer attack fixes"</td><td>Deployment, calls, reverts, logs and gas estimates behave as viem expects; chain id 4463; the prototype pgas table gives 0.0095 to 0.028 pgas per gas, below the design's band before calibration, 3 October 2026. 4 October 2026: a transaction that would cross the block's proving budget is refused by the mempool and, if forced in, aborted and charged with its nonce advanced (25 of 25 checks; 30 of 30 malformed cases). Apple M5 Max. The <code>Prover</code> precompile, proof records and the shard planner are not in the node</td><td class="iv">none yet</td></tr>
<tr data-status="implemented"><td class="n">15</td><td class="claim">Every block is proven, with the proof landing within about a minute at launch<div class="where">Homepage stats ("~60 s to a proof"); litepaper Proving; roadmap phase 3 gate</div></td><td><span class="st st-1">implemented</span></td><td class="mono">repo <code>d7e1f89</code> (GPU proof), <code>e01a3cc</code>, <code>292e800</code>, <code>eedd136</code> (<code>proving/igneum-prove</code>: shard cutter, MPT witnesses, shard and aggregator guests); SP1 6.8.1; spec 7.2, 7.6</td><td><code>proving/windows-wsl2</code> (SETUP-PROVER, PROVE-BLOCK) on the RTX 5090; <code>igneum-prove-host --mode block</code> on <code>proving/fixtures/</code>; bench-log "proving v0 on the RTX 5090" and "proving: devnet v4 shards"</td><td>First GPU proof of an Igneum block, 4 October 2026, RTX 5090 (WSL2, SP1 cuda, mining paused): fixture <code>block-78-increment</code> (2 transactions), core proof 1.4 s (7.3 MB, verify 0.221 s), compressed proof 2.7 s (1.27 MB, verify 0.038 s), post-state and receipts roots identical to the node's; 15.7x and 20.6x faster than a loaded M5 Max CPU. The same day on that CPU (load 38 to 47): a three-shard block proved shard by shard and aggregated by recursion, 19 min (1,139 s) end to end, 245 to 337 s per compressed shard proof, every proof verified. What is not there: no proof is produced, carried or checked on the chain (the devnet prover is a stub that signs claims), the proving pool pays nobody (row 21), the block proven is far below one shard, and the 60-second figure remains a design target; the pass mark is the standard in <code>docs/benchmarks/proving-e2e.md</code>. Second RTX 5090 run, 4 October 2026 evening (job run-20261004-173115): a full shard at the provisional S_p (6.75 M pgas, 60.8 M cycles) executed in 1.63 s, core proof 8.3 s (18.1 MB), compressed proof 10.9 s (1.27 MB, verify 0.040 s); a two-shard block (13.5 M pgas) proved shard by shard (11.7 s and 10.0 s) and aggregated in 2.2 s, 24 s of GPU stages end to end, every proof verified, six tampered witnesses rejected. The two host defects (an abort after the upload, an idle wait that turned out to be an unbuffered 18 MB proof save through the WSL2 file bridge, 24 minutes) are fixed (ledger P20) 5 October 2026, live devnet with real transactions (bench-log "real transactions, the first non-empty shard proven and paid"): block 72704 shard 0, 29 transfers, 5,800 pgas, proven on the RTX 5090 Windows rig in 34 s, verified on the Apple M5 Max in 0.297 s and paid 1.7623 IGN, 53 s after the chain block executed; of about 1,400 blocks in the 20-minute window 36 were proven (the one prover takes the newest shard assigned to it), so "every block" is not yet true; a second content shard (72803, all copies skipped) failed the native-execution veto on the exporter's block structure, fixed with fixtures the same day, the node side pending the 0.3.9 rollout 5 October 2026, evening (bench-log "proving v1"): the aggregated segment record, the chain rule and the unproven rule are implemented behind <code>proving_v1_activation_daa</code> (branch proving-v1, not on the devnet before 0.3.11); on the RTX 5090 a chain of 8 consecutive live blocks proved and aggregated by recursion in 135.6 s with the miner on the card (17 s a block, one proof of 1,272,909 bytes attesting all 8, verified in 0.04 s); the 3-node fast-time harness paid a segment record 1.0 s after submission and refused a late one after its deadline (21 checks); the devnet itself, with one prover, carried proofs for 2.4% of blocks over 30 minutes at a block-to-record latency p50 44 s, p99 52 s. The "within about a minute" holds per proven block; "every block" needs 18 mining 5090s or 6 proving-only cards at empty blocks on the measured rates, and the mandatory rule stays off until the share is one</td><td class="iv">none yet</td></tr>
<tr data-status="designed"><td class="n">16</td><td class="claim">A 12 GB card proves one shard in about 20 s (WITHDRAWN 5 October 2026: a 24 GB card proves a full shard at the adopted size in 4.3 s; 32 GB mines and proves)<div class="where">Litepaper Proving ("The proving budget"); roadmap gate 2</div></td><td><span class="st st-0">designed</span></td><td class="mono">spec 5.1 (Target), 7.6 (<code>S_p</code> provisional, 7,500,000 pgas = <code>B_p</code> / 4)</td><td><code>PROVE-SHARD.bat</code> on the RTX 5090 (pending); the end-to-end standard in <code>docs/benchmarks/proving-e2e.md</code>; bench-log "proving: devnet v4 shards"</td><td>Measured on a 32 GB card, not yet on a 12 GB card. A shard at the provisional <code>S_p</code> is 60.8 M SP1 cycles on the prototype pgas table (9 cycles per pgas, 44 per EVM gas; the modexp entry about 100x its SP1 cost); on an RTX 5090 (4 October 2026 evening, job run-20261004-173115) it executed in 1.63 s and its compressed proof took 10.9 s, verified in 0.040 s, so the 32 GB card is inside the 20 s target with margin. Whether a 12 GB card proves it at all, and in what time, is the next measurement (an RTX 3060 and an RTX 5060 Ti 16 GB are on order). A per-shard time can be met by shrinking the shard, so the project does not use it as a pass mark 5 October 2026, evening (bench-log "proving v1", the S_p curve): measured on the RTX 5090 with SP1 6.8.1's GPU prover, the card to itself, 1-s nvidia-smi samples: an empty shard 13,874 MiB and 2.2 s; a full shard at the ADOPTED v1 budget (30,000 pgas, 4.7 M cycles) 20,434 MiB and 4.3 s; the full prototype shard (6.75 M pgas, 60 M cycles) 28,307 MiB and 10.8 s; beside the miner 15,670 and 30,039 MiB. No environment knob of SP1 moves the 13.9 GB floor and the GPU server has no options of its own, so on this build a 12 GB card proves nothing, a 16 GB card only empty shards, a 24 GB card the adopted full shard alone and beside the miner (22,210 MiB and 13.2 s, measured on the 32 GB card: the 5090's allocation pattern, not yet a run on a 24 GB card) and a 32 GB card the prototype shard beside the miner with 2.5 GB spare. The litepaper line now says so; the 12 GB gate returns when a prover build with a smaller floor is measured on a 12 GB card</td><td class="iv">none yet</td></tr>
<tr data-status="designed"><td class="n">17</td><td class="claim">The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (a core as good as a GPU lane, k = 1) to 3.4x (a core three times better, k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state)<div class="where">the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line</div></td><td><span class="st st-0">tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 figure claimed against a CPU core and never measured</span></td><td class="mono"><code>docs/analysis/chip-model-v3.md</code> 5 and 6; <code>docs/analysis/latency-shadow-2026-10-06.md</code>; <code>docs/plans/counter-asic-3-status.md</code>; <code>docs/analysis/attack-pass/f8-uniform.md</code>, <code>f4-weakday.md</code>, <code>docs/analysis/ca3-v4-uniform.md</code>; <code>docs/design/class-v5-stored-state.md</code>; the H100 and market-cap rows of 7 October; <code>docs/plans/cryptanalysis/in-house-pass.md</code> (the internal adversarial pass)</td><td>the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses <code>tools/attack/f8-uniform</code> and the F4 census; the verifier by <code>igneum-pow bench</code></td><td>136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.4x, 2.8x at launch; the shadow's premium on a 5090 81.8 W at its knee (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W; class v3 at 1,300 MHz 134.62 at 223.3 W; 7 October 2026); 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, the RTX 5090 Windows rig's RTX 5090, the three-card Windows rig's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026).</td><td class="iv">none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and no outside review has run yet</td></tr>
<tr data-status="designed"><td class="n">17</td><td class="claim">The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (a core as good as a GPU lane, k = 1) to 3.4x (a core three times better, k about 0.33) per joule against an RTX 5090 under class v4, live from genesis on the testnet and the mainnet; the ladder's second rung brings it to about 2.8x; class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item; the hot-set cache is bounded at 1.067x at the ceiling and the weak-day FPGA at 12 percent on 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state)<div class="where">the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line</div></td><td><span class="st st-0">tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 figure claimed against a CPU core and never measured</span></td><td class="mono"><code>docs/analysis/chip-model-v3.md</code> 5 and 6; <code>docs/analysis/latency-shadow-2026-10-06.md</code>; <code>docs/plans/counter-asic-3-status.md</code>; <code>docs/analysis/attack-pass/f8-uniform.md</code>, <code>f4-weakday.md</code>, <code>docs/analysis/ca3-v4-uniform.md</code>; <code>docs/design/class-v5-stored-state.md</code>; the H100 and market-cap rows of 7 October; <code>docs/plans/cryptanalysis/in-house-pass.md</code> (the internal adversarial pass)</td><td>the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses <code>tools/attack/f8-uniform</code> and the F4 census; the verifier by <code>igneum-pow bench</code></td><td>136 MH/s at 350 W (5090, bench) and 290 W (app); the class v4 efficiency passes (bench log "7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080", measured): the 5090 at 136.84 MH/s and 475.5 W unlocked, 134.98 at 316.3 W at a 1,400 MHz core lock, the best points class v4 at 1,200 MHz (133.80 MH/s, 305.1 W, 0.439 MH/W) and class v3 at 1,300 MHz (134.62, 223.3 W, 0.603), the premium 145 W unlocked and 82 W at the best points, the knee 1,300 MHz; the RTX 5080 (8 October 2026, the dock card of the three-card Windows rig) at 71.41 MH/s and 253.1 W unlocked under class v4 against 71.28 at 169.7 W under class v3, the best points class v4 at 1,100 MHz (71.20 MH/s, 146.6 W, 0.486 MH/W) and class v3 at 1,000 MHz (71.11, 103.7 W, 0.686), the premium 83.4 W unlocked and 41 W at the best points, the knee between 1,000 and 900 MHz; per tier: a 5080 owner on class v4 locked near 1,100 MHz pays 147 W instead of 253 for 0.3 percent less rate, MH per watt up 72 percent, the lever Ember Tune's core-clock knob in 0.3.24; 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.4x, 2.8x at launch; the shadow's premium on a 5090 81.8 W at its knee (class v4 at the 1,200 MHz lock 133.80 MH/s at 305.1 W; class v3 at 1,300 MHz 134.62 at 223.3 W; 7 October 2026); 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, the RTX 5090 Windows rig's RTX 5090, the three-card Windows rig's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026).</td><td class="iv">none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and no outside review has run yet</td></tr>
<tr data-status="tested by the team"><td class="n">18</td><td class="claim">The chip resistance measurements: the program is latency-bound (random reads), not bandwidth-bound, on every card we own, and sits beyond a card's on-chip cache<div class="where">Litepaper Mining ("waits on memory latency, not on maths or bandwidth"), vs RandomX; the numbers page</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">readwidth e752fc7 (<code>docs/plans/read-width.md</code>), ca2-era 78c0ee4, ca2-cache 2de19e5 (<code>docs/plans/hot-table.md</code>)</td><td>The dependent-read probes at 32 to 1,024 MiB and the hash rate per class on the three cards; the latency-bound share = rate over the probe ceiling per load</td><td>Latency-bound share at the 1 GiB dataset: RTX 5090 0.96 (v2) and 1.01 (v3), RX 9070 XT 0.87 and 0.95, M5 Max 1.01 and 1.06; wider reads do not close the AMD gap (the 9070 XT does 2.4 G dependent reads per second at every width; the 5090 goes bandwidth-bound at 64 B, share 0.58); a 32 to 96 MiB hot table is not kept resident by any card while the dataset streams (g 0.80 to 0.87 in the added form). 5 October 2026</td><td class="iv">none yet</td></tr>
<tr data-status="tested by the team"><td class="n">19</td><td class="claim">The lottery hash is sound as a hash: uniform output, deterministic, no out-of-bounds read, fuzzed; class v3 bit-exact on the three vendors<div class="where">Litepaper vs RandomX ("Every number above is measured and logged"), the numbers page</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">ca2-mixer 1ab8b21 (<code>tests/mixer.rs</code>, <code>tests/scratch.rs</code>), ca2-era 78c0ee4, ca2-soundness a465881 (<code>docs/analysis/scratch-soundness.md</code>), <code>igneum-pow/tests/packs.rs</code></td><td>The crate suite (53 + 4 + 19 + 7), the Metal fuzz, edge, stats and determinism runs on the v3 construction, the pack vectors and 2^24 fingerprints on Metal, Apple OpenCL, the RTX 5090 and the RX 9070 XT, the 1,024-hash CPU re-check per card</td><td>Class v3 (mixer x8 + era): 200-program fuzz 200 of 200 on Metal, every tenth on Apple OpenCL; the pinned v3 packs 3/3 + 3/3 and 96 of 96 lanes on Metal and Apple OpenCL; the six era packs' fingerprints equal on the three vendors (the three-card Windows rig (RTX 5090, RTX 4070, RX 9070 XT) job run-ca2-era-pc1-20261005, 5 October 2026); the v2 exports byte-identical on the v3 crate; the final-class PC rows and the G2 re-check: job run-ca2-era-pc1b-20261005 (pending at the time of writing)</td><td class="iv">none yet</td></tr>
<tr data-status="implemented"><td class="n">20</td><td class="claim">No premine, no pre-sale, no allocation: every coin is minted by the schedule and every coin goes to the block producer (80%) and the proving pool (20%)<div class="where">Homepage stats and Economics tiles; litepaper Supply, Economics</div></td><td><span class="st st-1">implemented</span></td><td class="mono">repo <code>6ac80a3</code>; fork "igneum-node devnet v0"; <code>consensus/core/src/igneum.rs</code>, <code>coinbase.rs</code></td><td><code>cargo test -p kaspa-consensus-core igneum</code> (8 pass: subsidy table, ramp, split, cap) and <code>cargo test -p kaspa-consensus coinbase</code> (8 pass); <code>igneum-miner inspect 40</code>; bench-log "igneum-node devnet v0"</td><td>Coinbases on the devnet: 80/20 exact on 39 of 39 single-payee blocks, the 20% to the <code>igneum-proving-pool-v0</code> output; the per-second schedule sums to under the 4,000,000,000 cap by less than 100 coins; 3,168,808,781 units per DAA second in years 0 to 2, halving at 63,115,200 DAA s. 3 October 2026, Apple M5 Max. The devnet genesis carries no allocation; the mainnet genesis does not exist yet, so the claim is about the code and the stated rule, not a launch that has happened</td><td class="iv">none yet</td></tr>
@ -279,7 +279,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v
<tr><td>reproduced externally</td><td>reviewed independently</td><td>A named reviewer's published finding on that version. Funding for review is <code>docs/plans/funding.md</code></td></tr>
<tr><td>any</td><td>the row's status falls back</td><td>A new version of the code or rule the row names</td></tr>
</tbody></table></div>
<p class="asof">Statuses are honest as of 7 October 2026, the day this page was generated from docs/evidence.md, and change only through that file.</p>
<p class="asof">Statuses are honest as of 8 October 2026, the day this page was generated from docs/evidence.md, and change only through that file.</p>
</main>
<!-- footer:start -->
<footer class="site-footer">

View file

@ -1401,7 +1401,7 @@ blockquote{margin:10px 0;padding:10px 14px;border-left:3px solid var(--line-2);c
<article class="entry" id="AP-F8-1" data-bucket="Fixed or built">
<div class="head"><span class="id">AP-F8-1</span><h3>A load whose source was last written by <code>or</code>, <code>mul</code> or <code>mulhi</code> makes a cross-hash hot set</h3><span class="date">7 October 2026</span></div>
<blockquote>The item histogram of class v4 over 2^26 nonces is not uniform: the top 0.1 percent of items take 0.520 percent of reads against 0.115 for a uniform control (4.05x), one item takes 78,479 reads (153x the mean), and site 15 feeds 6.37 percent of its reads into that top 0.1 percent in every iteration.&quot; (attack-pass row F8, <code>a repository file</code>, 7 October 2026)</blockquote>
<div class="status"><span class="badge b-fixed-or-built">Fixed in part, finding bounded, stated</span> <span class="did">7 October 2026, night, the Counter ASIC lane's words): class v4 sub-version 3 (igneum-pow 017e7037, the audit-freeze tag) is frozen with the dataflow rule, the shared-operand rule, the 0.98 ratio and the total draw; the in-house pass's F8 re-gate reads 60 of 64 seeds under 1.2x with the four-seed tail accepted by the coordinator as the window model's unattributed residue (no chip consequence); the pass then attributed the class by value (eight live hot sets at 1.54x to 2.24x in the lowest 30 of 29,032 accepted programs, each about 1 MB of items at 0.3 percent of reads, 1.002x to a chip); class v5 (1c420786, frozen 21:53 UK) carries the fix as rule (c'''), the per-site distinct-index floor at 0.995 on the state flag (its census refuses 2.435 percent of accepted programs; seven of seven live hot sets refused at 0.9821 to 0.9919; the eighth's ratio owed tonight), with a named residual (three mild shadow-block-written concentrations at 0.9992 to 0.9997, about 1.0004x, a value-level test in the next class); the record is <code>a repository file</code> section 7c and the class v5 design's section 14. The eighth live hot set (seed 122960, id 4be7393ab6c84802, the deepest found: X_f +0.111 percent, 1.54x the window model, its hottest item at 475,616 reads from an all-ones source) reads minimum site 12 at 0.9824 at the acceptance's own 2^20 sample (live 0.9822), refused by class v5's (c''') floor at 0.995; so the floor refuses eight of eight live hot sets by X_f at or above f found in the tail of 88,051 accepted programs (minimum sites 0.9821 to 0.9919) against 0 hot sets in 20 random programs; what it misses stays the three mild shadow-block-written concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x to a chip, the value-level test in the next class (22:41 local time; the logs under <code>a repository file/</code> on branch adv-accept; the v5 design's section 14). The public sentence (the coordinator's wording, 7 October 2026, night): 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 reason, read by the in-house pass (adv-cache-2) and the class v5 lane together: the distinct-index count at 2^20 sees concentration on few word indices (the hot sets put about 3 percent of a site's reads on 512 indices, so the ratio falls to 0.98 to 0.992) and not a diffuse excess over the top 0.1 percent of items (16,384 items), which is what the era-stride low-bit law produces (13 of 27 drawn-era programs carry a site over 1.04x, 8 over 1.2x, worst 1.75x; 0 of 29 refused at the 2^20 sample, minimum sites 0.9965 to 1.0000); its chip value is about 1.0024x at the worst site read, under this row's bound by an order; the row for it is AP-F8-6. The RTX 5080 grid's knee is not in tonight; X37 keeps the 5080's stock premium only.</span></div>
<div class="status"><span class="badge b-fixed-or-built">Fixed in part, finding bounded, stated</span> <span class="did">7 October 2026, night, the Counter ASIC lane's words): class v4 sub-version 3 (igneum-pow 017e7037, the audit-freeze tag) is frozen with the dataflow rule, the shared-operand rule, the 0.98 ratio and the total draw; the in-house pass's F8 re-gate reads 60 of 64 seeds under 1.2x with the four-seed tail accepted by the coordinator as the window model's unattributed residue (no chip consequence); the pass then attributed the class by value (eight live hot sets at 1.54x to 2.24x in the lowest 30 of 29,032 accepted programs, each about 1 MB of items at 0.3 percent of reads, 1.002x to a chip); class v5 (1c420786, frozen 21:53 UK) carries the fix as rule (c'''), the per-site distinct-index floor at 0.995 on the state flag (its census refuses 2.435 percent of accepted programs; seven of seven live hot sets refused at 0.9821 to 0.9919; the eighth's ratio owed tonight), with a named residual (three mild shadow-block-written concentrations at 0.9992 to 0.9997, about 1.0004x, a value-level test in the next class); the record is <code>a repository file</code> section 7c and the class v5 design's section 14. The eighth live hot set (seed 122960, id 4be7393ab6c84802, the deepest found: X_f +0.111 percent, 1.54x the window model, its hottest item at 475,616 reads from an all-ones source) reads minimum site 12 at 0.9824 at the acceptance's own 2^20 sample (live 0.9822), refused by class v5's (c''') floor at 0.995; so the floor refuses nine of nine live hot sets by X_f at or above f found in the tail of 269,250 accepted programs (minimum sites 0.9809 to 0.9919; the ninth, seed 228763 from a non-saturated source, at 0.9809 on 8 October 2026) against 0 hot sets in 20 random programs; what it misses stays the three mild shadow-block-written concentrations at 0.9992 to 0.9997 (Devnet 3's first program among them), about 1.0004x to a chip, the value-level test in the next class (22:41 local time; the logs under <code>a repository file/</code> on branch adv-accept; the v5 design's section 14). The public sentence (the coordinator's wording, 7 October 2026, night; the count moved to nine at 01:13 local time on 8 October when the ninth live hot set, seed 228763 from a non-saturated source, read 0.9809 and was refused): nine of nine 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 reason, read by the in-house pass (adv-cache-2) and the class v5 lane together: the distinct-index count at 2^20 sees concentration on few word indices whatever their source, saturated or not (the hot sets put about 3 percent of a site's reads on 512 indices, so the ratio falls to 0.981 to 0.992; the final tally 9 of 9 live hot sets and both single-item programs refused, 7 clean-live programs refused among the 12 deepest, 3 mild residuals missed) and not a diffuse excess over the top 0.1 percent of items (16,384 items), which is what the era-stride low-bit law produces (13 of 27 drawn-era programs carry a site over 1.04x, 8 over 1.2x, worst 1.75x; 0 of 29 refused at the 2^20 sample, minimum sites 0.9965 to 1.0000); its chip value is about 1.0024x at the worst site read, under this row's bound by an order; the row for it is AP-F8-6. The RTX 5080 grid's knee is not in tonight; X37 keeps the 5080's stock premium only.</span></div>
<details><summary>The answer as first written</summary><p>Correct as a fault, wrong as a null. The window layer (spec 01 1.13.1 as proposed, <code>a repository file</code> 1.4) moves the uniform null from 0.115 to 0.160 percent at the top 0.1 percent (1.39x, not 4.05x) and explains every per-site row of F8's attribution except site 15. Site 15's source r6 was last written by <code>or r6, r4</code> (instruction 61, the load at 63), a non-injective op whose output bits are 1 with probability 3/4, so the all-ones source recurs with probability (3/4)^32 per read; the era map sends it to item 0xca5b92, F8's hottest item exactly, and F8's next seven items are exactly the seven one-zero-bit sources whose zero survives the window mask. The popcount model at the measured bias (p = 0.7585) predicts 77,348 all-ones reads against 78,479, and the program's top-0.1-percent share at 0.58 against 0.52. The acceptance rule's part (a) takes any write as a fresh source and part (c) counts saturation on final register values only, so the class of fault passes it: of 1,024 chain-shaped class v4 programs 96.6 percent carry a load whose source's last writer is <code>or</code>, <code>mul</code> or <code>mulhi</code>, 48.5 percent an <code>or</code>-sourced one (0.30 percent of all reads per site), 4.9 percent an <code>or</code>-of-<code>or</code> chain (p3's class: 72 percent of that site's reads, 4.6 percent of all reads, on 0.1 percent of items). The ceiling under rule (c)'s 120-of-128 floor is one site repeating its item in all 8 iterations, 6.25 percent of reads, a chip edge of at most 1.067x in 64 bytes of SRAM; the public claim's 2x margin stands, and the public line says &quot;bounded&quot;, not &quot;uniform&quot; (<code>a repository file</code> sections 1 to 4).</p></details>
</article>
<article class="entry" id="AP-F8-3" data-bucket="Fixed or built">

View file

@ -227,7 +227,7 @@
{
"card": "Apple M5 Max (40 GPU cores, Metal)",
"generator": "v2",
"mh_s": 27.0,
"mh_s": 27,
"watts": 21,
"mh_per_w": 1.29,
"miner": "igneum-miner Metal worker, class v3 program",
@ -250,7 +250,7 @@
{
"card": "Intel Arc B580 (12 GB)",
"generator": "v2",
"mh_s": 11.0,
"mh_s": 11,
"watts": null,
"mh_per_w": null,
"miner": "igneum-worker-opencl bench, class v4 program",
@ -294,24 +294,27 @@
{
"card": "NVIDIA RTX 5080 (16 GB)",
"generator": "v2",
"mh_s": 71.16,
"watts": 143.4,
"mh_per_w": 0.496,
"miner": "hive package 0.3.20 igneum-worker-cuda, class v4 program",
"date": "2026-10-07",
"source": "bench log: 7 October 2026, every rentable card on the hash (the fleet's sweep on rented cards; hive package 0.3.20, Ubuntu 24.04)",
"by": "measured by the fleet",
"note": "148.6 W maximum; the team's own 5080 on a dock reads 60 MH/s warming and gets its full Ember Tune on 7 October",
"v4_cost": "not measured (class v4 program only)",
"tuned": "stock, bench only (rented, not tuned)",
"driver_os": "NVIDIA driver 580.65.06, Ubuntu 24.04",
"mh_s": 71.2,
"watts": 146.6,
"mh_per_w": 0.486,
"miner": "the runner's card switch, class v4 program (job run-ca3-pc1-v4-eff-5080-20261007-d)",
"date": "2026-10-08",
"source": "bench log: 7 to 8 October 2026, the class v4 efficiency passes: the core clock lock on the RTX 5090 and the RTX 5080",
"by": "measured by the team",
"note": "the knee sits between 1,000 and 900 MHz (the rate within 0.3 percent of unlocked down to 1,000 MHz, 5.2 percent off at 900 on class v4); the draw floors from 1,500 MHz down. The rented fleet's 5080 read 71.16 MH/s at 143.4 W stock (hive package 0.3.20, Ubuntu 24.04, 7 October 2026), 110 W under this card's stock draw: the method differs per row (nvidia-smi on Linux, the runner's card switch on Windows) and neither is taken as the card's figure until the fleet re-measures",
"v4_cost": "83.4 W unlocked and 41 W at the best points for 0.2 percent of rate (class v4 71.41 MH/s at 253.1 W against class v3 71.28 at 169.7 W unlocked; measured 8 October 2026)",
"tuned": "core lock 1,100 MHz (the efficiency pass's best point: 71.20 MH/s at 146.6 W, 0.486 MH/W, 106.5 W recovered for 0.29 percent of rate), memory 14,801 MHz, the driver's power limit untouched",
"driver_os": "NVIDIA driver 617.14, Windows 11",
"hive": {
"core_mhz": null,
"core_mhz": 1100,
"mem_mhz": null,
"pl_w": null,
"label": "stock (no measured tune point; the 5080 and 9070 XT passes and the class v4 efficiency pass land theirs when read)"
"label": "core lock 1,100 MHz, memory stock, power limit untouched (measured 8 October 2026, the efficiency pass)"
},
"group": "buy"
"group": "buy",
"mh_s_display": "71.4 stock (71.2 tuned)",
"watts_display": "146.6 tuned (253 stock)",
"v4_short": "+83 W unlocked, +41 W at the best points"
},
{
"card": "NVIDIA RTX 3070 Ti (8 GB)",

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,111 @@
# Counter ASIC 4 research (8 October 2026, the research lane's tail item; the coordinator's order): the 3.0 layer-5 hot table re-run with the
# streaming hint on PC 1's RTX 5090, the card alone through the RUNNER's --cards-off, no prompt. The kit (fetch job fetch-ca4-hot-packs-20261008):
# the eight 5 October hot-table packs of proto-cuda/packs-ca2-hot (hot32k4, hot32k4a, hot64k2, hot64k4, hot64k4a, hot64k8, hot96k4, hot96k4a: a
# second table of 32, 64 or 96 MiB sized to the L2, k loads per hash from it) and mx8-genesis as the control. The INSTALLED igneum-worker-cuda.exe
# --bench on every pack twice: base, and `--variant ldcs` (the worker's existing variant: __ldcs, streaming / evict-first, on every DATASET load,
# so the hot-table loads stay plain and L2-resident; the 5 October rows without the hint read g 0.84 to 0.87). 250 batches of 2^24 per run at
# --block-warps 1, nvidia-smi at 1 Hz (the three power fields, the mean from 8 s in): MH/s, watts, SM MHz, the fingerprint (base and ldcs must
# agree: the hint changes no byte) and check=PASS; once unlocked and once at the 1,300 MHz knee through the Power Helper task (the cleared
# sequence; rgc in finally; a silent helper skips the locked state and says so). Rows: `RESULT ca4-research pack= dir= program_id= class=
# variant=<base|ldcs> state= mhs= watts= ... fingerprint= check=`, the worker's own RESULT and race lines verbatim. Never quits, pauses, resumes
# or updates the app.
$ErrorActionPreference = 'Continue'
$jobName = 'pc1-ca4-hot-ldcs'
$started = Get-Date
function Stamp { (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ') }
function Summary([string] $status, [hashtable] $extra) { $o = [ordered]@{ job = $jobName; status = $status; duration_s = [int]((Get-Date) - $started).TotalSeconds; finished_at = (Stamp) }; foreach ($k in $extra.Keys) { $o[$k] = $extra[$k] }; 'SUMMARY ' + ($o | ConvertTo-Json -Compress -Depth 4) }
$jobDir = $env:IGNEUM_JOB_DIR; if (-not $jobDir) { $jobDir = Join-Path $env:TEMP 'igneum-ca4-mb' }
New-Item -ItemType Directory -Force -Path $jobDir | Out-Null
$jobs = Split-Path $jobDir
$packs = Join-Path (Join-Path $jobs 'fetch-ca4-hot-packs-20261008') 'packs'
if (-not (Test-Path $packs)) { "RESULT error packs missing at $packs (the fetch job fetch-ca4-hot-packs-20261008 runs first)"; Summary 'failed' @{ error = 'packs missing' }; exit 2 }
$inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum Miner") | Where-Object { Test-Path (Join-Path $_ 'igneum-worker-cuda.exe') } | Select-Object -First 1
if (-not $inst) { 'RESULT error no installed igneum-worker-cuda.exe'; Summary 'failed' @{ error = 'no worker' }; exit 2 }
$exe = Join-Path $inst 'igneum-worker-cuda.exe'
$packOrder = @('mx8-genesis', 'hot32k4', 'hot32k4a', 'hot64k2', 'hot64k4', 'hot64k4a', 'hot64k8', 'hot96k4', 'hot96k4a')
$variants = @('base', 'ldcs')
foreach ($pk in $packOrder) { $d = Join-Path $packs $pk; if (-not (Test-Path $d)) { "RESULT error pack missing at $d"; Summary 'failed' @{ error = "pack $pk missing" }; exit 2 }; foreach ($f in (Get-ChildItem $d -File | Sort-Object Name)) { "RESULT kitfile $pk/$($f.Name) sha256 $((Get-FileHash -Algorithm SHA256 $f.FullName).Hash.ToLower())" } }
"RESULT start $(Stamp) job=$jobName exe=$exe sha256=$((Get-FileHash -Algorithm SHA256 $exe).Hash.ToLower()) label=ca4-research"
$smi = (Get-Command nvidia-smi -ErrorAction SilentlyContinue).Source
if (-not $smi) { foreach ($p in @((Join-Path $env:ProgramFiles 'NVIDIA Corporation\NVSMI\nvidia-smi.exe'), (Join-Path $env:SystemRoot 'System32\nvidia-smi.exe'))) { if (Test-Path $p) { $smi = $p; break } } }
$row = @(& $smi --query-gpu=index,name,uuid,pci.bus_id --format=csv,noheader 2>&1 | ForEach-Object { "$_" }) | Where-Object { $_ -match 'RTX 5090' } | Select-Object -First 1
if (-not $row) { 'RESULT error no RTX 5090'; Summary 'failed' @{ error = 'no 5090' }; exit 2 }
$fld = $row -split ',\s*'; $idx = $fld[0].Trim(); $uuid = $fld[2].Trim(); $bus = $fld[3].Trim()
"RESULT card index=$idx uuid=$uuid bus=$bus"
$apps = @(& $smi --query-compute-apps=gpu_bus_id,pid,process_name --format=csv,noheader 2>$null | ForEach-Object { "$_" } | Where-Object { $_ -match [regex]::Escape($bus) -and $_ -match 'igneum' })
$t = 0; while ($t -lt 150 -and $apps.Count -gt 0) { Start-Sleep -Seconds 5; $t += 5; $apps = @(& $smi --query-compute-apps=gpu_bus_id,pid,process_name --format=csv,noheader 2>$null | ForEach-Object { "$_" } | Where-Object { $_ -match [regex]::Escape($bus) -and $_ -match 'igneum' }) }
"RESULT card $(Stamp) $(if ($apps.Count -eq 0) { "quiet after $t s (the runner's --cards-off took)" } else { "UNCONFIRMED: $($apps -join '; ')" })"
# ---- the helper (the lock path), as pc1-v4-efficiency.ps1 ----
$helperDir = Join-Path $env:LOCALAPPDATA 'igneum\app\sweep'; $cmdFile = Join-Path $helperDir 'cmd.txt'; $helperLog = Join-Path $helperDir 'helper.log'
function HelperAliveAge() { $a = Join-Path $helperDir 'helper.alive'; if (-not (Test-Path -LiteralPath $a)) { return 9999 }; try { $v = [int64]((Get-Content -LiteralPath $a -Raw).Trim()); return ([int64][double]::Parse((Get-Date -UFormat %s)) - $v) } catch { return 9999 } }
# the 0.3.20 helper's skip rule (update-return lane, 8 October 2026, 01:17 BST): it skips the first N lines of cmd.txt, N = the line count
# when it started, for its whole life; so every job starts it over an EMPTY file (skip 0), waits for helper.alive within 4 s, and repeats
# the sequence whenever helper.alive is stale (the helper idle-exits 20 min after its last command). A refused start (0x800710E0) or no fresh
# heartbeat within 60 s stops the lock path: nothing escalates, nothing not set is restored, the text goes on a RESULT line.
function HelperReset() {
Set-Content -LiteralPath $cmdFile -Value '' -NoNewline -Encoding ascii
try { Stop-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue } catch { }
Start-Sleep -Seconds 2
try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop } catch { $t = "$_" -replace '\s+', ' '; "RESULT helper start refused: $t"; if ($t -match '800710E0') { 'RESULT helper STOP: the scheduler refused the elevated instance (0x800710E0); nothing escalates' }; return $false }
$t = 0
while ($t -lt 60) { Start-Sleep -Seconds 1; $t++; if ((HelperAliveAge) -le 4) { "RESULT helper fresh after $t s (helper.alive within 4 s; started over an empty cmd.txt)"; return $true } }
'RESULT helper STOP: helper.alive never freshened within 60 s of the start; nothing escalates'
return $false
}
function HelperSeqBase() { $m = 0; foreach ($f in @($cmdFile, $helperLog)) { if (Test-Path $f) { foreach ($l in (Get-Content -LiteralPath $f -ErrorAction SilentlyContinue)) { if ($l -match '(?:^|\s)(\d{1,6}) (?:dev|pl|lgc|rgc|lmc|rmc|nvidia-smi|reregister)\b') { $v = [int]$Matches[1]; if ($v -gt $m) { $m = $v } } } } }; return $m + 100 }
function HelperSend([string] $verb) {
$s0 = HelperSeqBase; $s1 = $s0 + 1
$mark = 0; if (Test-Path $helperLog) { $mark = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue).Count }
if ((HelperAliveAge) -gt 10) { if (-not (HelperReset)) { return "no helper (the reset failed)" } }; Set-Content -LiteralPath $cmdFile -Value "$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
$t = 0; while ($t -lt 30) { Start-Sleep -Seconds 1; $t++; $new = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue); if ($new.Count -gt $mark) { $hit = $new[$mark..($new.Count - 1)] | Where-Object { $_ -match "\b$s1 nvidia-smi " } | Select-Object -First 1; if ($hit) { return ($hit -replace '^\d+\s+', '') } } }
return "no helper.log line for seq $s1 within 30 s"
}
$viaHelper = $false
if (Get-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue) { $viaHelper = (HelperReset); if ($viaHelper) { 'RESULT helper task up over an empty cmd.txt' } } else { 'RESULT helper task not registered: the locked state is skipped' }
# ---- the sampler ----
$samples = Join-Path $jobDir 'nv-samples.csv'; if (Test-Path $samples) { Remove-Item -LiteralPath $samples -Force }
$sampler = Start-Process -FilePath $smi -ArgumentList @('-i', $idx, '--query-gpu=timestamp,power.draw,clocks.sm,clocks.mem,temperature.gpu,utilization.gpu,power.draw.instant,power.draw.average', '--format=csv,noheader,nounits', '-lms', '1000') -RedirectStandardOutput $samples -WindowStyle Hidden -PassThru
Start-Sleep -Seconds 5
"RESULT sampler pid=$($sampler.Id) first=[$((Get-Content -LiteralPath $samples -ErrorAction SilentlyContinue | Select-Object -First 1))]"
function Mean($vals) { $v = @($vals | ForEach-Object { [double]$_ }); if ($v.Count -eq 0) { return $null }; return [math]::Round((($v | Measure-Object -Sum).Sum / $v.Count), 1) }
function Window([datetime] $t0, [datetime] $t1) { $sel = @(); if (Test-Path $samples) { foreach ($l in (Get-Content -LiteralPath $samples -ErrorAction SilentlyContinue)) { $p = $l -split ',\s*'; if ($p.Count -lt 6) { continue }; try { $ts = [datetime]::ParseExact($p[0].Trim(), 'yyyy/MM/dd HH:mm:ss.fff', [cultureinfo]::InvariantCulture) } catch { continue }; if ($ts -ge $t0 -and $ts -le $t1) { $sel += ,$p } } }; return ,$sel }
function ParseUtc([string] $s) { try { return [datetime]::Parse($s, [cultureinfo]::InvariantCulture, [System.Globalization.DateTimeStyles]::AdjustToUniversal).ToLocalTime() } catch { return $null } }
function RunState([string] $state) {
$env:CUDA_VISIBLE_DEVICES = $uuid
"RESULT packs-state $state start $(Stamp) $((& $smi -i $idx --query-gpu=clocks.sm,clocks.applications.graphics,power.draw --format=csv,noheader 2>&1 | Out-String).Trim())"
foreach ($pk in $packOrder) { foreach ($variant in $variants) {
$d = Join-Path $packs $pk
$cls = ''; $pid = ''; try { $pj = Get-Content -LiteralPath (Join-Path $d 'program.json') -Raw | ConvertFrom-Json; $cls = [string] $pj.load_class; $pid = [string] $pj.program_id } catch { }
$t0 = Get-Date
$extra = @(); if ($variant -ne 'base') { $extra = @('--variant', $variant) }
$lines = @(& $exe --bench --pack $d --batches 250 --batch-log2 24 --block-warps 1 @extra --device 0 2>&1 | ForEach-Object { "$_" })
$race = (($lines | Where-Object { $_ -match 'race' }) -join ' / ') -replace '\s+', ' '
$rc = $LASTEXITCODE
$t1 = Get-Date
$res = $lines | Where-Object { $_ -match '^RESULT pack=' } | Select-Object -First 1
foreach ($l in $lines) { if ($l -match '^RESULT pack=|error|FAIL|MISMATCH|compile|nvrtc|vector|lane|self-test|checksum|race' ) { "RESULT worker pack=$pk variant=$variant state=$state $l" } }
$fp = ''; $mhs = ''; $check = ''
if ($res -and $res -match 'fingerprint=([0-9a-f]{16})') { $fp = $Matches[1] }; if ($res -and $res -match 'mhs=([\d.]+)') { $mhs = $Matches[1] }; if ($res -and $res -match 'check=(\S+)') { $check = $Matches[1] }
$w = Window $t0.AddSeconds(8) $t1
$watts = Mean ($w | ForEach-Object { $_[1] }); $sm = Mean ($w | ForEach-Object { $_[2] }); $mem = Mean ($w | ForEach-Object { $_[3] }); $util = Mean ($w | ForEach-Object { $_[5] })
$wi = Mean ($w | Where-Object { $_.Count -ge 8 -and $_[6] -match '^\s*[\d.]+\s*$' } | ForEach-Object { $_[6] }); $wa = Mean ($w | Where-Object { $_.Count -ge 8 -and $_[7] -match '^\s*[\d.]+\s*$' } | ForEach-Object { $_[7] })
$eff = if ($watts -and $mhs) { [math]::Round([double]$mhs / $watts, 4) } else { '' }
$err = ''; if (-not $res -or $rc -ne 0) { $e = ($lines | Where-Object { $_ -match 'FAIL|error|MISMATCH|compile' } | Select-Object -First 1); $err = if ($e) { ($e -replace '\s+', ' ') } else { "exit $rc, no RESULT line" } }
"RESULT ca4-research pack=$pk dir=$d program_id=$pid class=$cls variant=$variant state=$state mhs=$mhs watts=$watts watts_instant=$wi watts_average=$wa mh_per_w=$eff sm_mhz=$sm mem_mhz=$mem util=$util fingerprint=$fp check=$check exit=$rc wall_s=$([int]($t1 - $t0).TotalSeconds) samples=$($w.Count) error=$err race=[$race]"
Start-Sleep -Seconds 3
} }
"RESULT packs-state $state end $(Stamp)"
}
$locked = $false
try {
RunState 'unlocked'
if ($viaHelper) {
$r = HelperSend 'lgc 1300'
if ($r -match 'no helper.log') { "RESULT lock1300 skipped: the helper gave no answer ($r)" } else { "RESULT lock1300 set: $r"; $locked = $true; Start-Sleep -Seconds 3; RunState 'lock1300' }
} else { 'RESULT lock1300 skipped: no helper path' }
Summary 'done' @{ locked_state_ran = $locked }
exit 0
} finally {
if ($locked) { $r = HelperSend 'rgc'; "RESULT restore rgc: $r ; applications clock: $((& $smi -i $idx --query-gpu=clocks.applications.graphics --format=csv,noheader 2>&1 | Out-String).Trim())" }
if ($sampler -and -not $sampler.HasExited) { Stop-Process -Id $sampler.Id -Force -ErrorAction SilentlyContinue; 'RESULT restore sampler stopped' }
}

View file

@ -30,16 +30,31 @@ $t = 0; while ($t -lt 150 -and $apps.Count -gt 0) { Start-Sleep -Seconds 5; $t +
"RESULT card $(Stamp) $(if ($apps.Count -eq 0) { "quiet after $t s (the runner's --cards-off took)" } else { "UNCONFIRMED: $($apps -join '; ')" })"
# ---- the helper (the lock path), as pc1-v4-efficiency.ps1 ----
$helperDir = Join-Path $env:LOCALAPPDATA 'igneum\app\sweep'; $cmdFile = Join-Path $helperDir 'cmd.txt'; $helperLog = Join-Path $helperDir 'helper.log'
function HelperAliveAge() { $a = Join-Path $helperDir 'helper.alive'; if (-not (Test-Path -LiteralPath $a)) { return 9999 }; try { $v = [int64]((Get-Content -LiteralPath $a -Raw).Trim()); return ([int64][double]::Parse((Get-Date -UFormat %s)) - $v) } catch { return 9999 } }
# the 0.3.20 helper's skip rule (update-return lane, 8 October 2026, 01:17 BST): it skips the first N lines of cmd.txt, N = the line count
# when it started, for its whole life; so every job starts it over an EMPTY file (skip 0), waits for helper.alive within 4 s, and repeats
# the sequence whenever helper.alive is stale (the helper idle-exits 20 min after its last command). A refused start (0x800710E0) or no fresh
# heartbeat within 60 s stops the lock path: nothing escalates, nothing not set is restored, the text goes on a RESULT line.
function HelperReset() {
Set-Content -LiteralPath $cmdFile -Value '' -NoNewline -Encoding ascii
try { Stop-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue } catch { }
Start-Sleep -Seconds 2
try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop } catch { $t = "$_" -replace '\s+', ' '; "RESULT helper start refused: $t"; if ($t -match '800710E0') { 'RESULT helper STOP: the scheduler refused the elevated instance (0x800710E0); nothing escalates' }; return $false }
$t = 0
while ($t -lt 60) { Start-Sleep -Seconds 1; $t++; if ((HelperAliveAge) -le 4) { "RESULT helper fresh after $t s (helper.alive within 4 s; started over an empty cmd.txt)"; return $true } }
'RESULT helper STOP: helper.alive never freshened within 60 s of the start; nothing escalates'
return $false
}
function HelperSeqBase() { $m = 0; foreach ($f in @($cmdFile, $helperLog)) { if (Test-Path $f) { foreach ($l in (Get-Content -LiteralPath $f -ErrorAction SilentlyContinue)) { if ($l -match '(?:^|\s)(\d{1,6}) (?:dev|pl|lgc|rgc|lmc|rmc|nvidia-smi|reregister)\b') { $v = [int]$Matches[1]; if ($v -gt $m) { $m = $v } } } } }; return $m + 100 }
function HelperSend([string] $verb) {
$s0 = HelperSeqBase; $s1 = $s0 + 1
$mark = 0; if (Test-Path $helperLog) { $mark = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue).Count }
$pad = ((0..3) | ForEach-Object { "$($s0 - 8 + 2 * $_) dev $idx" }) -join "`n"; Set-Content -LiteralPath $cmdFile -Value "$pad`n$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
if ((HelperAliveAge) -gt 10) { if (-not (HelperReset)) { return "no helper (the reset failed)" } }; Set-Content -LiteralPath $cmdFile -Value "$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
$t = 0; while ($t -lt 30) { Start-Sleep -Seconds 1; $t++; $new = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue); if ($new.Count -gt $mark) { $hit = $new[$mark..($new.Count - 1)] | Where-Object { $_ -match "\b$s1 nvidia-smi " } | Select-Object -First 1; if ($hit) { return ($hit -replace '^\d+\s+', '') } } }
return "no helper.log line for seq $s1 within 30 s"
}
$viaHelper = $false
if (Get-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue) { try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop; Start-Sleep -Seconds 3; $viaHelper = $true; 'RESULT helper task started' } catch { "RESULT helper start failed: $_" } } else { 'RESULT helper task not registered: the locked state is skipped' }
if (Get-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue) { $viaHelper = (HelperReset); if ($viaHelper) { 'RESULT helper task up over an empty cmd.txt' } } else { 'RESULT helper task not registered: the locked state is skipped' }
# ---- the sampler ----
$samples = Join-Path $jobDir 'nv-samples.csv'; if (Test-Path $samples) { Remove-Item -LiteralPath $samples -Force }
$sampler = Start-Process -FilePath $smi -ArgumentList @('-i', $idx, '--query-gpu=timestamp,power.draw,clocks.sm,clocks.mem,temperature.gpu,utilization.gpu,power.draw.instant,power.draw.average', '--format=csv,noheader,nounits', '-lms', '1000') -RedirectStandardOutput $samples -WindowStyle Hidden -PassThru

View file

@ -24,7 +24,9 @@ if (-not $inst) { 'RESULT error no installed igneum-worker-cuda.exe'; Summary 'f
$exe = Join-Path $inst 'igneum-worker-cuda.exe'
# mx8_shl256x27 is the research lane's first per-load export (id 854050a4293f0615, the known-failed record: 11 percent duplicate reads from a lossy
# base writer under the sub-blocks) and mx8_shl256x27_v2 its fix (counter-asic-4 2f718001, attempt 3, id bd64b207a30413fb); both run and every row
# names its pack directory and the program id read from its program.json
# names its pack directory and the program id read from its program.json. 22:44 UTC: the research lane's acceptance rule, judging the per-load
# class in execution order, refuses the 16 x 27 construction on every attempt, so neither per-load export is a candidate class; both rows
# still run as the energy reading of the placement and carry construction=unsound-energy-reading-only
$packOrder = @('mx8-genesis', 'mx8_sh256x27', 'mx8_shl256x27', 'mx8_shl256x27_v2', 'mx8_mm128', 'mx8_mm512', 'mx8_mm1430')
foreach ($pk in $packOrder) { $d = Join-Path $packs $pk; if (-not (Test-Path $d)) { "RESULT error pack missing at $d"; Summary 'failed' @{ error = "pack $pk missing" }; exit 2 }; foreach ($f in (Get-ChildItem $d -File | Sort-Object Name)) { "RESULT kitfile $pk/$($f.Name) sha256 $((Get-FileHash -Algorithm SHA256 $f.FullName).Hash.ToLower())" } }
"RESULT start $(Stamp) job=$jobName exe=$exe sha256=$((Get-FileHash -Algorithm SHA256 $exe).Hash.ToLower()) label=ca4-research"
@ -39,16 +41,31 @@ $t = 0; while ($t -lt 150 -and $apps.Count -gt 0) { Start-Sleep -Seconds 5; $t +
"RESULT card $(Stamp) $(if ($apps.Count -eq 0) { "quiet after $t s (the runner's --cards-off took)" } else { "UNCONFIRMED: $($apps -join '; ')" })"
# ---- the helper (the lock path), as pc1-v4-efficiency.ps1 ----
$helperDir = Join-Path $env:LOCALAPPDATA 'igneum\app\sweep'; $cmdFile = Join-Path $helperDir 'cmd.txt'; $helperLog = Join-Path $helperDir 'helper.log'
function HelperAliveAge() { $a = Join-Path $helperDir 'helper.alive'; if (-not (Test-Path -LiteralPath $a)) { return 9999 }; try { $v = [int64]((Get-Content -LiteralPath $a -Raw).Trim()); return ([int64][double]::Parse((Get-Date -UFormat %s)) - $v) } catch { return 9999 } }
# the 0.3.20 helper's skip rule (update-return lane, 8 October 2026, 01:17 BST): it skips the first N lines of cmd.txt, N = the line count
# when it started, for its whole life; so every job starts it over an EMPTY file (skip 0), waits for helper.alive within 4 s, and repeats
# the sequence whenever helper.alive is stale (the helper idle-exits 20 min after its last command). A refused start (0x800710E0) or no fresh
# heartbeat within 60 s stops the lock path: nothing escalates, nothing not set is restored, the text goes on a RESULT line.
function HelperReset() {
Set-Content -LiteralPath $cmdFile -Value '' -NoNewline -Encoding ascii
try { Stop-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue } catch { }
Start-Sleep -Seconds 2
try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop } catch { $t = "$_" -replace '\s+', ' '; "RESULT helper start refused: $t"; if ($t -match '800710E0') { 'RESULT helper STOP: the scheduler refused the elevated instance (0x800710E0); nothing escalates' }; return $false }
$t = 0
while ($t -lt 60) { Start-Sleep -Seconds 1; $t++; if ((HelperAliveAge) -le 4) { "RESULT helper fresh after $t s (helper.alive within 4 s; started over an empty cmd.txt)"; return $true } }
'RESULT helper STOP: helper.alive never freshened within 60 s of the start; nothing escalates'
return $false
}
function HelperSeqBase() { $m = 0; foreach ($f in @($cmdFile, $helperLog)) { if (Test-Path $f) { foreach ($l in (Get-Content -LiteralPath $f -ErrorAction SilentlyContinue)) { if ($l -match '(?:^|\s)(\d{1,6}) (?:dev|pl|lgc|rgc|lmc|rmc|nvidia-smi|reregister)\b') { $v = [int]$Matches[1]; if ($v -gt $m) { $m = $v } } } } }; return $m + 100 }
function HelperSend([string] $verb) {
$s0 = HelperSeqBase; $s1 = $s0 + 1
$mark = 0; if (Test-Path $helperLog) { $mark = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue).Count }
$pad = ((0..3) | ForEach-Object { "$($s0 - 8 + 2 * $_) dev $idx" }) -join "`n"; Set-Content -LiteralPath $cmdFile -Value "$pad`n$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
if ((HelperAliveAge) -gt 10) { if (-not (HelperReset)) { return "no helper (the reset failed)" } }; Set-Content -LiteralPath $cmdFile -Value "$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
$t = 0; while ($t -lt 30) { Start-Sleep -Seconds 1; $t++; $new = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue); if ($new.Count -gt $mark) { $hit = $new[$mark..($new.Count - 1)] | Where-Object { $_ -match "\b$s1 nvidia-smi " } | Select-Object -First 1; if ($hit) { return ($hit -replace '^\d+\s+', '') } } }
return "no helper.log line for seq $s1 within 30 s"
}
$viaHelper = $false
if (Get-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue) { try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop; Start-Sleep -Seconds 3; $viaHelper = $true; 'RESULT helper task started' } catch { "RESULT helper start failed: $_" } } else { 'RESULT helper task not registered: the locked state is skipped' }
if (Get-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue) { $viaHelper = (HelperReset); if ($viaHelper) { 'RESULT helper task up over an empty cmd.txt' } } else { 'RESULT helper task not registered: the locked state is skipped' }
# ---- the sampler ----
$samples = Join-Path $jobDir 'nv-samples.csv'; if (Test-Path $samples) { Remove-Item -LiteralPath $samples -Force }
$sampler = Start-Process -FilePath $smi -ArgumentList @('-i', $idx, '--query-gpu=timestamp,power.draw,clocks.sm,clocks.mem,temperature.gpu,utilization.gpu,power.draw.instant,power.draw.average', '--format=csv,noheader,nounits', '-lms', '1000') -RedirectStandardOutput $samples -WindowStyle Hidden -PassThru
@ -76,7 +93,8 @@ function RunState([string] $state) {
$wi = Mean ($w | Where-Object { $_.Count -ge 8 -and $_[6] -match '^\s*[\d.]+\s*$' } | ForEach-Object { $_[6] }); $wa = Mean ($w | Where-Object { $_.Count -ge 8 -and $_[7] -match '^\s*[\d.]+\s*$' } | ForEach-Object { $_[7] })
$eff = if ($watts -and $mhs) { [math]::Round([double]$mhs / $watts, 4) } else { '' }
$err = ''; if (-not $res -or $rc -ne 0) { $e = ($lines | Where-Object { $_ -match 'FAIL|error|MISMATCH|compile' } | Select-Object -First 1); $err = if ($e) { ($e -replace '\s+', ' ') } else { "exit $rc, no RESULT line" } }
"RESULT ca4-research pack=$pk dir=$d program_id=$pid class=$cls state=$state mhs=$mhs watts=$watts watts_instant=$wi watts_average=$wa mh_per_w=$eff sm_mhz=$sm mem_mhz=$mem util=$util fingerprint=$fp check=$check exit=$rc wall_s=$([int]($t1 - $t0).TotalSeconds) samples=$($w.Count) error=$err"
$tag = if ($pk -like 'mx8_shl256x27*') { ' construction=unsound-energy-reading-only' } else { '' }
"RESULT ca4-research pack=$pk dir=$d program_id=$pid class=$cls$tag state=$state mhs=$mhs watts=$watts watts_instant=$wi watts_average=$wa mh_per_w=$eff sm_mhz=$sm mem_mhz=$mem util=$util fingerprint=$fp check=$check exit=$rc wall_s=$([int]($t1 - $t0).TotalSeconds) samples=$($w.Count) error=$err"
Start-Sleep -Seconds 3
}
"RESULT packs-state $state end $(Stamp)"

View file

@ -26,18 +26,20 @@ case "$STEP" in
family-kit) $P add --kind fetch --target ae432dc7 --id fetch-ca3-pc1-amd-family-20261007 --file "$KITS/igneum-ca3-pc1-amd-family-kit-20261007.zip" --dir jobs --extract --title "CA3 PC 1: the family probe kit (7 Oct)" --expires-hours 36 $DEPLOY ;;
eff-5090) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-eff-5090-20261007-b --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 75 --title "CA3 PC 1: class v4 efficiency pass on the RTX 5090 (clock locks, v4 against v3, the card alone)" --expires-hours 36 $DEPLOY ;;
eff-5090-floor) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-eff-5090-floor-20261007 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 60 --title "CA3 PC 1: class v4 efficiency pass 2 on the RTX 5090 (1,400 MHz down to the driver floor, v4 against v3, the card alone)" --expires-hours 36 $DEPLOY ;;
ca4-exe) $P add --kind fetch --target ae432dc7 --id fetch-ca4-sparse-exe-20261007 --file "$KITS/ca4/igneum-worker-cuda-ca4sparse.exe" --dir jobs --title "CA4 research: the SM-sparse worker exe (scratch build, counter-asic-4)" --expires-hours 36 $DEPLOY ;;
ca4-sparse) $P add --kind run --target ae432dc7 --id run-ca4-pc1-ca4sparse-5090-20261007 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 70 --title "CA4 research: SM-sparse worker variants on the RTX 5090, unlocked and at the 1,300 MHz knee, v4 and v3 (the card alone)" --expires-hours 36 $DEPLOY ;;
ca4-exe) $P add --kind fetch --target ae432dc7 --id fetch-ca4-sparse3-exe-20261008 --file "$KITS/ca4/igneum-worker-cuda-ca4sparse3.exe" --dir jobs --title "CA4 research: the SM-sparse worker exe with the race fix (scratch build, counter-asic-4, 00:46 UTC)" --expires-hours 36 $DEPLOY ;;
ca4-sparse) $P add --kind run --target ae432dc7 --id run-ca4-pc1-ca4sparse-5090-20261008 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 70 --title "CA4 research: SM-sparse worker variants on the RTX 5090, unlocked and at the 1,300 MHz knee, v4 and v3 (the card alone)" --expires-hours 36 $DEPLOY ;;
eff-5090-floor2) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-eff-5090-floor2-20261007 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 45 --title "CA3 PC 1: class v4 efficiency pass 3 on the RTX 5090 (1,100 MHz down to the driver floor, v4 against v3, the card alone)" --expires-hours 36 $DEPLOY ;;
eff-5080) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-eff-5080-20261007-c --cards-off "nvidia:NVIDIA GeForce RTX 5080" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 75 --title "CA3 PC 1: class v4 efficiency pass on the RTX 5080 (clock locks, v4 against v3, the card alone)" --expires-hours 36 $DEPLOY ;;
eff-5080) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-eff-5080-20261007-d --cards-off "nvidia:NVIDIA GeForce RTX 5080" --script tools/ca3-v4-amend/pc1-v4-efficiency.ps1 --timeout-minutes 75 --title "CA3 PC 1: class v4 efficiency pass on the RTX 5080 (clock locks, v4 against v3, the card alone)" --expires-hours 36 $DEPLOY ;;
helper-diag2) $P add --kind run --target ae432dc7 --id run-ca3-pc1-helper-diag2-20261007 --script tools/ca3-v4-amend/pc1-helper-diag2.ps1 --timeout-minutes 5 --title "PC 1: Power Helper diagnostic 2 (the task exe against the running app, scheduler history, crash log, a 20 s unelevated helper probe)" --expires-hours 12 $DEPLOY ;;
ca4-mb-exe) $P add --kind fetch --target ae432dc7 --id fetch-ca4-microbench-exe-20261007 --file "$KITS/ca4/igneum-worker-cuda-ca4mb.exe" --dir jobs --title "CA4 research: the microbench worker exe (scratch build)" --expires-hours 36 $DEPLOY ;;
ca4-mb) $P add --kind run --target ae432dc7 --id run-ca4-pc1-microbench-5090-20261007 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-ca4-microbench.ps1 --timeout-minutes 60 --title "CA4 research: per-block micro-benchmark on the RTX 5090, unlocked and at the 1,300 MHz knee (the card alone)" --expires-hours 36 $DEPLOY ;;
ca4-packs-kit) $P add --kind fetch --target ae432dc7 --id fetch-ca4-packs-20261007 --file "$KITS/igneum-ca4-packs-20261007.zip" --dir jobs --extract --title "CA4 research: the two prototype classes' packs (both per-load exports) plus the mx8 control\" --expires-hours 36 $DEPLOY ;;
ca4-packs-kit) $P add --kind fetch --target ae432dc7 --id fetch-ca4-packs-20261007 --file "$KITS/igneum-ca4-packs-20261007.zip" --dir jobs --extract --title "CA4 research: the two prototype classes, both per-load exports, plus the mx8 control" --expires-hours 36 $DEPLOY ;;
ca4-packs) $P add --kind run --target ae432dc7 --id run-ca4-pc1-packs-5090-20261007 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-ca4-packs.ps1 --timeout-minutes 60 --title "CA4 research: the per-load shadow and the int8 tile prototypes against mx8 and sh256x27 on the RTX 5090 (the card alone)" --expires-hours 36 $DEPLOY ;;
v5-kit) $P add --kind fetch --target ae432dc7,1ccfe586 --id fetch-ca3-v5-kit-20261007 --file "$KITS/v5kit/packs-ca3-v5-20261007T221001Z.zip" --dir jobs --extract --title "Class v5 kit (the v5 lane, 7f58af97): packs, workers, SHA256SUMS" --expires-hours 36 $DEPLOY ;;
v5-amd) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v5-amd-bench-20261007 --script tools/ca3-v4-amend/pc1-v5-amd-bench-20261007.ps1 --timeout-minutes 12 --title "Class v5 kit fingerprint on the RX 9070 XT (beside the miners; the v5 lane's script)" --expires-hours 36 $DEPLOY ;;
v5-intel) $P add --kind run --target 1ccfe586 --id run-ca3-pc2-v5-intel-bench-20261007 --script tools/ca3-v4-amend/pc1-v5-intel-bench-20261007.ps1 --timeout-minutes 12 --title "Class v5 kit fingerprint on PC 2's Arc B580 eGPU (the v5 lane's script, class-v5 a4b08245; beside the miners; only on the shipper's PC 2 clear)" --expires-hours 36 $DEPLOY ;;
hot-kit) $P add --kind fetch --target ae432dc7 --id fetch-ca4-hot-packs-20261008 --file "$KITS/igneum-ca4-hot-packs-20261008.zip" --dir jobs --extract --title "CA4 research: the eight 5 October hot-table packs plus the mx8 control" --expires-hours 36 $DEPLOY ;;
hot-ldcs) $P add --kind run --target ae432dc7 --id run-ca4-pc1-hot-ldcs-5090-20261008 --cards-off "nvidia:NVIDIA GeForce RTX 5090" --script tools/ca3-v4-amend/pc1-ca4-hot-ldcs.ps1 --timeout-minutes 75 --title "CA4 research: the hot table with the streaming hint (base against ldcs) on the RTX 5090, unlocked and at the knee (the card alone)" --expires-hours 36 $DEPLOY ;;
amd-g1) $P add --kind run --target ae432dc7 --id run-ca3-pc1-v4-sub3-amd-g1-20261007 --cards-off amd:gfx1201 --script tools/ca3-v4-amend/pc1-v4-sub3-amd-g1.ps1 --timeout-minutes 45 --title "CA3 PC 1: G1 on the sub-version 3 kit and the AMD ladder on the 9070 XT (the card alone)" --expires-hours 36 $DEPLOY ;;
family) $P add --kind run --target ae432dc7 --id run-ca3-pc1-amd-family-20261007-e --cards-off amd:gfx1201 --script tools/ca3-v4-amend/pc1-amd-family-20261007.ps1 --timeout-minutes 20 --title "CA3 PC 1: item 6 family step costs on the 9070 XT (run e, the card alone)" --expires-hours 36 $DEPLOY ;;
tune-5080) $P add --kind run --target ae432dc7 --id run-ca3-pc1-ember-5080-20261007 --script tools/ca3-v4-amend/pc1-ember-card.ps1 --timeout-minutes 35 --title "CA3 PC 1: Ember Tune on the RTX 5080 (the installed app tunes the one card)" --expires-hours 36 $DEPLOY ;;

View file

@ -68,8 +68,10 @@ $inst = @("$env:LOCALAPPDATA\Programs\Igneum Miner", "$env:ProgramFiles\Igneum M
if (-not $inst) { 'RESULT error no installed igneum-worker-cuda.exe'; Summary 'failed' @{ error = 'no worker' }; exit 2 }
$exe = Join-Path $inst 'igneum-worker-cuda.exe'
if ($ca4) {
$exe = Join-Path (Join-Path $jobs 'fetch-ca4-sparse-exe-20261007') 'igneum-worker-cuda-ca4sparse.exe'
if (-not (Test-Path $exe)) { "RESULT error the research worker is missing at $exe (the fetch job fetch-ca4-sparse-exe-20261007 runs first)"; Summary 'failed' @{ error = 'research worker missing' }; exit 2 }
# the research lane's exe with the race fix (counter-asic-4 after 2d0013d1, 00:46 UTC; the first exe parsed --variant and never applied it:
# every row of the 00:22Z run read "variant base"); the rows carry its variant= and sparse_blocks= fields and any variant_not_installed line
$exe = Join-Path (Join-Path $jobs 'fetch-ca4-sparse3-exe-20261008') 'igneum-worker-cuda-ca4sparse3.exe'
if (-not (Test-Path $exe)) { "RESULT error the research worker is missing at $exe (the fetch job fetch-ca4-sparse3-exe-20261008 runs first)"; Summary 'failed' @{ error = 'research worker missing' }; exit 2 }
}
"RESULT worker $exe sha256 $((Get-FileHash -Algorithm SHA256 $exe).Hash.ToLower()) bytes $((Get-Item $exe).Length)"
$appExe = Join-Path $inst 'igneum-app.exe'
@ -128,6 +130,21 @@ $helperLog = Join-Path $helperDir 'helper.log'
# tuned the 5080 at seqs 423596 to 423598 while this script wrote 419500 to 419527, so every lock from 1,000 MHz down and the
# closing reset were skipped as stale and the card stayed locked); the base is therefore the maximum over cmd.txt AND helper.log,
# re-read after every timeout
function HelperAliveAge() { $a = Join-Path $helperDir 'helper.alive'; if (-not (Test-Path -LiteralPath $a)) { return 9999 }; try { $v = [int64]((Get-Content -LiteralPath $a -Raw).Trim()); return ([int64][double]::Parse((Get-Date -UFormat %s)) - $v) } catch { return 9999 } }
# the 0.3.20 helper's skip rule (update-return lane, 8 October 2026, 01:17 BST): it skips the first N lines of cmd.txt, N = the line count
# when it started, for its whole life; so every job starts it over an EMPTY file (skip 0), waits for helper.alive within 4 s, and repeats
# the sequence whenever helper.alive is stale (the helper idle-exits 20 min after its last command). A refused start (0x800710E0) or no fresh
# heartbeat within 60 s stops the lock path: nothing escalates, nothing not set is restored, the text goes on a RESULT line.
function HelperReset() {
Set-Content -LiteralPath $cmdFile -Value '' -NoNewline -Encoding ascii
try { Stop-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue } catch { }
Start-Sleep -Seconds 2
try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop } catch { $t = "$_" -replace '\s+', ' '; "RESULT helper start refused: $t"; if ($t -match '800710E0') { 'RESULT helper STOP: the scheduler refused the elevated instance (0x800710E0); nothing escalates' }; return $false }
$t = 0
while ($t -lt 60) { Start-Sleep -Seconds 1; $t++; if ((HelperAliveAge) -le 4) { "RESULT helper fresh after $t s (helper.alive within 4 s; started over an empty cmd.txt)"; return $true } }
'RESULT helper STOP: helper.alive never freshened within 60 s of the start; nothing escalates'
return $false
}
function HelperSeqBase() {
$m = 0
foreach ($f in @($cmdFile, $helperLog)) { if (Test-Path $f) { foreach ($l in (Get-Content -LiteralPath $f -ErrorAction SilentlyContinue)) { if ($l -match '(?:^|\s)(\d{1,6}) (?:dev|pl|lgc|rgc|lmc|rmc|nvidia-smi|reregister)\b') { $v = [int]$Matches[1]; if ($v -gt $m) { $m = $v } } } } }
@ -140,8 +157,7 @@ if (-not $elevated) {
if ($task) {
try {
$seq = HelperSeqBase
Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop
Start-Sleep -Seconds 3
if (-not (HelperReset)) { throw 'the helper did not come up (see the RESULT helper lines)' }
$viaHelper = $true
"RESULT helper task 'Igneum Power Helper' state=$((Get-ScheduledTask -TaskName 'Igneum Power Helper').State) started; commands through $cmdFile from seq $seq; results from $helperLog"
} catch { "RESULT helper task present but Start-ScheduledTask failed: $_" }
@ -151,7 +167,7 @@ function HelperSend([string] $verb) {
$script:seq += 2
$s0 = $script:seq; $s1 = $script:seq + 1; $script:seq = $s1
$mark = 0; if (Test-Path $helperLog) { $mark = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue).Count }
$pad = ((0..3) | ForEach-Object { "$($s0 - 8 + 2 * $_) dev $idx" }) -join "`n"; Set-Content -LiteralPath $cmdFile -Value "$pad`n$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
if ((HelperAliveAge) -gt 10) { if (-not (HelperReset)) { return "no helper (the reset failed)" } }; Set-Content -LiteralPath $cmdFile -Value "$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
$t = 0
while ($t -lt 30) {
Start-Sleep -Seconds 1; $t++
@ -168,7 +184,7 @@ function HelperSend([string] $verb) {
$script:seq = $base
$s0 = $script:seq; $s1 = $script:seq + 1; $script:seq = $s1
$mark = 0; if (Test-Path $helperLog) { $mark = @(Get-Content -LiteralPath $helperLog -ErrorAction SilentlyContinue).Count }
$pad = ((0..3) | ForEach-Object { "$($s0 - 8 + 2 * $_) dev $idx" }) -join "`n"; Set-Content -LiteralPath $cmdFile -Value "$pad`n$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
if ((HelperAliveAge) -gt 10) { if (-not (HelperReset)) { return "no helper (the reset failed)" } }; Set-Content -LiteralPath $cmdFile -Value "$s0 dev $idx`n$s1 $verb`n" -NoNewline -Encoding ascii
$t = 0
while ($t -lt 30) {
Start-Sleep -Seconds 1; $t++
@ -186,19 +202,12 @@ function SetLock([int] $mhz) {
}
if ($viaHelper) {
$out = HelperSend "lgc $mhz"
if ($out -match 'not have permission|No permission|Insufficient|not supported|Unable|ERROR|no helper.log') { return "refused: $out" }
if ($out -match 'not have permission|No permission|Insufficient|not supported|Unable|ERROR|no helper') { return "refused: $out" }
return "ok (helper, -lgc 0,$mhz): $out"
}
return 'refused: not elevated and no helper task'
}
function RestartHelper() {
# the floor pass of 20:21Z lost the helper at its 1,000 MHz step (no helper.log answer for that and every later command, the
# lock most likely hanging inside the helper's nvidia-smi call) and its closing reset never ran: before a reset the task is
# stopped and started again (the owning user may do both without a prompt), so a stuck helper never holds the card locked
try { Stop-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction SilentlyContinue } catch { }
Start-Sleep -Seconds 3
try { Start-ScheduledTask -TaskName 'Igneum Power Helper' -ErrorAction Stop; Start-Sleep -Seconds 3; return $true } catch { "RESULT helper restart failed: $_"; return $false }
}
function RestartHelper() { return (HelperReset) }
function AppClock() { $a = @(& $smi -i $idx --query-gpu=clocks.applications.graphics --format=csv,noheader 2>&1 | ForEach-Object { "$_" }) | Select-Object -First 1; return "$a" }
function ResetClocks() {
if ($elevated) { return ((& $smi -i $idx -rgc 2>&1 | Out-String).Trim() -replace '\s+', ' ') }
@ -215,10 +224,11 @@ function Bench([string] $pk, [int] $n, [string] $variant = 'base') {
$t0 = Get-Date
$extra = @(); if ($variant -ne 'base') { $extra = @('--block-warps', '32', '--variant', $variant) } else { $extra = @('--block-warps', '1') }
$lines = @(& $exe --bench --pack $d --batches $n --batch-log2 24 @extra --device 0 2>&1 | ForEach-Object { "$_" })
$race = (($lines | Where-Object { $_ -match 'race' }) -join ' / ') -replace '\s+', ' '
$race = (($lines | Where-Object { $_ -match 'race|variant_not_installed|compile:' }) -join ' / ') -replace '\s+', ' '
$rc = $LASTEXITCODE
$t1 = Get-Date
$res = $lines | Where-Object { $_ -match '^RESULT pack=' } | Select-Object -First 1
$served = ''; if ($res -and $res -match 'variant=(\S+)') { $served = $Matches[1] }; $sparse = ''; if ($res -and $res -match 'sparse_blocks=(\d+)') { $sparse = $Matches[1] }
$fp = ''; $mhs = $null; $check = ''; $dev = ''
if ($res -and $res -match 'device=(.*?) arch=') { $dev = $Matches[1] }
if ($res -and $res -match 'fingerprint=([0-9a-f]{16})') { $fp = $Matches[1] }
@ -226,7 +236,7 @@ function Bench([string] $pk, [int] $n, [string] $variant = 'base') {
if ($res -and $res -match 'check=(\S+)') { $check = $Matches[1] }
$err = ''
if (-not $res -or $rc -ne 0) { $e = ($lines | Where-Object { $_ -match 'FAIL|error|MISMATCH' } | Select-Object -First 1); $err = if ($e) { ($e -replace '\s+', ' ') } else { "exit $rc, no RESULT line" } }
return [pscustomobject]@{ pack = $pk; t0 = $t0; t1 = $t1; rc = $rc; fp = $fp; mhs = $mhs; check = $check; err = $err; res = $res; batches = $n; dev = $dev; variant = $variant; race = $race }
return [pscustomobject]@{ pack = $pk; t0 = $t0; t1 = $t1; rc = $rc; fp = $fp; mhs = $mhs; check = $check; err = $err; res = $res; batches = $n; dev = $dev; variant = $variant; race = $race; served = $served; sparse = $sparse }
}
function Step([string] $label, [string] $lockNote) {
foreach ($pk in $packOrder) { foreach ($variant in $variants) {
@ -247,7 +257,8 @@ function Step([string] $label, [string] $lockNote) {
$match = if ($want -and $b.fp -eq $want) { 'yes' } elseif ($want) { 'no' } else { 'unknown' }
$wall = [int]($b.t1 - $b.t0).TotalSeconds
$lab = if ($ca4) { 'ca4-research' } else { 'efficiency' }
"RESULT STEP card=$cardName pack=$pk lock=$label variant=$variant label=$lab sm_mhz=$sm mem_mhz=$mem watts=$watts watts_instant=$wInst watts_average=$wAvg temp_max=$tmax throttle=$thr mhs=$($b.mhs) mh_per_w=$eff fingerprint=$($b.fp) match=$match expected=$want check=$($b.check) batches=$n wall_s=$wall samples=$($w.Count) device=$($b.dev) lock_note=$lockNote alone=$alone race=[$($b.race)]"
$vfail = if ($ca4 -and $variant -ne 'base' -and ($b.served -eq 'base' -or $b.race -match 'variant_not_installed')) { ' variant_row=FAILED' } else { '' }
"RESULT STEP card=$cardName pack=$pk lock=$label variant=$variant served=$($b.served) sparse_blocks=$($b.sparse)$vfail label=$lab sm_mhz=$sm mem_mhz=$mem watts=$watts watts_instant=$wInst watts_average=$wAvg temp_max=$tmax throttle=$thr mhs=$($b.mhs) mh_per_w=$eff fingerprint=$($b.fp) match=$match expected=$want check=$($b.check) batches=$n wall_s=$wall samples=$($w.Count) device=$($b.dev) lock_note=$lockNote alone=$alone race=[$($b.race)]"
if ($variant -eq 'base') { $script:rows += [pscustomobject]@{ pack = $pk; lock = $label; sm = $sm; watts = $watts; mhs = $b.mhs; eff = $eff; match = $match } }
} }
}