diff --git a/docs/evidence.md b/docs/evidence.md index f564650f8..f73d68670 100644 --- a/docs/evidence.md +++ b/docs/evidence.md @@ -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: the strongest chip in the public model reaches 5x to 9x per joule against an RTX 5090 today (modelled); class v4 brings it to 2.1x (k = 1) to 3.9x (k about 0.33, claimed by a withdrawn product) and its second rung to about 2.8x (modelled on measured watts); class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item (designed, +0.2 ms verifier); the hot-set cache bounded at 1.067x at the ceiling (measured census of 1,024 programs) and the weak-day FPGA at most 12 percent on 12 days a century (measured census) are bounded and routed to the next class; datacentre silicon (H100 SXM, measured 7 October) does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years (modelled) | The home page's chip line, the litepaper's chip model section, the miner page's line (the texts of `docs/plans/counter-asic-3-public-text-2026-10-07.md`) | tested by the team (every card, the verifier, the two attack-pass censuses, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed 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/design/class-v5-stored-state.md`; the H100 and market-cap rows of 7 October; `docs/plans/funding.md` (the three lots) | The chip model re-run on the measured class v3 and v4 rates, watts and verifier times; the hot-set census of 1,024 programs and the weak-day census of 2^24 days on the attack-pass branch; the H100 SXM bench row | 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; 5.1x to 9.2x; 2.1x, 3.9x, 2.8x; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 6 and 7 October 2026 | none yet; the three cryptanalysis lots are the next test | +| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (k = 1) to 3.9x (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 12 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 core claimed 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/funding.md` (the three lots) | 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.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 12 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 | none yet; the three cryptanalysis lots are the next test | | 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 | diff --git a/docs/plans/site-ui-5-shots/404__1440-dark.png b/docs/plans/site-ui-5-shots/404__1440-dark.png index 971b69d1a..c36a01e7a 100644 Binary files a/docs/plans/site-ui-5-shots/404__1440-dark.png and b/docs/plans/site-ui-5-shots/404__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/404__1440-light.png b/docs/plans/site-ui-5-shots/404__1440-light.png deleted file mode 100644 index 0cad44dfd..000000000 Binary files a/docs/plans/site-ui-5-shots/404__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/404__390-dark.png b/docs/plans/site-ui-5-shots/404__390-dark.png index 98b0561c2..8c165e332 100644 Binary files a/docs/plans/site-ui-5-shots/404__390-dark.png and b/docs/plans/site-ui-5-shots/404__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/404__390-light.png b/docs/plans/site-ui-5-shots/404__390-light.png deleted file mode 100644 index e69e7f1ae..000000000 Binary files a/docs/plans/site-ui-5-shots/404__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/app-band__1440-dark.png b/docs/plans/site-ui-5-shots/app-band__1440-dark.png new file mode 100644 index 000000000..3a17362a7 Binary files /dev/null and b/docs/plans/site-ui-5-shots/app-band__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/app__1440-dark.png b/docs/plans/site-ui-5-shots/app__1440-dark.png index 829bd2714..84ff889a2 100644 Binary files a/docs/plans/site-ui-5-shots/app__1440-dark.png and b/docs/plans/site-ui-5-shots/app__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/app__1440-light.png b/docs/plans/site-ui-5-shots/app__1440-light.png deleted file mode 100644 index 7c9077a76..000000000 Binary files a/docs/plans/site-ui-5-shots/app__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/app__390-dark.png b/docs/plans/site-ui-5-shots/app__390-dark.png index 50c7f103e..786d47070 100644 Binary files a/docs/plans/site-ui-5-shots/app__390-dark.png and b/docs/plans/site-ui-5-shots/app__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/app__390-light.png b/docs/plans/site-ui-5-shots/app__390-light.png deleted file mode 100644 index f5d933676..000000000 Binary files a/docs/plans/site-ui-5-shots/app__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/bench__1440-dark.png b/docs/plans/site-ui-5-shots/bench__1440-dark.png index 8d59fa565..e10c8d8d1 100644 Binary files a/docs/plans/site-ui-5-shots/bench__1440-dark.png and b/docs/plans/site-ui-5-shots/bench__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/bench__1440-light.png b/docs/plans/site-ui-5-shots/bench__1440-light.png deleted file mode 100644 index 46f5a0cd7..000000000 Binary files a/docs/plans/site-ui-5-shots/bench__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/bench__390-dark.png b/docs/plans/site-ui-5-shots/bench__390-dark.png index e57969e49..e7fa60a7a 100644 Binary files a/docs/plans/site-ui-5-shots/bench__390-dark.png and b/docs/plans/site-ui-5-shots/bench__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/bench__390-light.png b/docs/plans/site-ui-5-shots/bench__390-light.png deleted file mode 100644 index 02835baf2..000000000 Binary files a/docs/plans/site-ui-5-shots/bench__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/claims__1440-dark.png b/docs/plans/site-ui-5-shots/claims__1440-dark.png index a62362bf7..51de593f2 100644 Binary files a/docs/plans/site-ui-5-shots/claims__1440-dark.png and b/docs/plans/site-ui-5-shots/claims__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/claims__1440-light.png b/docs/plans/site-ui-5-shots/claims__1440-light.png deleted file mode 100644 index 16d76a319..000000000 Binary files a/docs/plans/site-ui-5-shots/claims__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/claims__390-dark.png b/docs/plans/site-ui-5-shots/claims__390-dark.png index aca29af59..d59a0394c 100644 Binary files a/docs/plans/site-ui-5-shots/claims__390-dark.png and b/docs/plans/site-ui-5-shots/claims__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/claims__390-light.png b/docs/plans/site-ui-5-shots/claims__390-light.png deleted file mode 100644 index 23e20bf0d..000000000 Binary files a/docs/plans/site-ui-5-shots/claims__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/dev-fee__1440-dark.png b/docs/plans/site-ui-5-shots/dev-fee__1440-dark.png index 5411bc7ed..ff181f158 100644 Binary files a/docs/plans/site-ui-5-shots/dev-fee__1440-dark.png and b/docs/plans/site-ui-5-shots/dev-fee__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/dev-fee__1440-light.png b/docs/plans/site-ui-5-shots/dev-fee__1440-light.png deleted file mode 100644 index 11d21d3a2..000000000 Binary files a/docs/plans/site-ui-5-shots/dev-fee__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/dev-fee__390-dark.png b/docs/plans/site-ui-5-shots/dev-fee__390-dark.png index 8967d6365..579f11b28 100644 Binary files a/docs/plans/site-ui-5-shots/dev-fee__390-dark.png and b/docs/plans/site-ui-5-shots/dev-fee__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/dev-fee__390-light.png b/docs/plans/site-ui-5-shots/dev-fee__390-light.png deleted file mode 100644 index 623a2c994..000000000 Binary files a/docs/plans/site-ui-5-shots/dev-fee__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/download__1440-dark.png b/docs/plans/site-ui-5-shots/download__1440-dark.png index a652840b1..ac1bd8efd 100644 Binary files a/docs/plans/site-ui-5-shots/download__1440-dark.png and b/docs/plans/site-ui-5-shots/download__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/download__1440-light.png b/docs/plans/site-ui-5-shots/download__1440-light.png deleted file mode 100644 index d67650d82..000000000 Binary files a/docs/plans/site-ui-5-shots/download__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/download__390-dark.png b/docs/plans/site-ui-5-shots/download__390-dark.png index bac29b767..ddb18130a 100644 Binary files a/docs/plans/site-ui-5-shots/download__390-dark.png and b/docs/plans/site-ui-5-shots/download__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/download__390-light.png b/docs/plans/site-ui-5-shots/download__390-light.png deleted file mode 100644 index 1eff43072..000000000 Binary files a/docs/plans/site-ui-5-shots/download__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/evidence__1440-dark.png b/docs/plans/site-ui-5-shots/evidence__1440-dark.png index 90527b73c..10e9ba10d 100644 Binary files a/docs/plans/site-ui-5-shots/evidence__1440-dark.png and b/docs/plans/site-ui-5-shots/evidence__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/evidence__1440-light.png b/docs/plans/site-ui-5-shots/evidence__1440-light.png deleted file mode 100644 index 7d8f26f6c..000000000 Binary files a/docs/plans/site-ui-5-shots/evidence__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/evidence__390-dark.png b/docs/plans/site-ui-5-shots/evidence__390-dark.png index 648b592ba..105fbd6bf 100644 Binary files a/docs/plans/site-ui-5-shots/evidence__390-dark.png and b/docs/plans/site-ui-5-shots/evidence__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/evidence__390-light.png b/docs/plans/site-ui-5-shots/evidence__390-light.png deleted file mode 100644 index b9f505133..000000000 Binary files a/docs/plans/site-ui-5-shots/evidence__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/explorer__1440-dark.png b/docs/plans/site-ui-5-shots/explorer__1440-dark.png index 3f2027499..10ae9b205 100644 Binary files a/docs/plans/site-ui-5-shots/explorer__1440-dark.png and b/docs/plans/site-ui-5-shots/explorer__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/explorer__1440-light.png b/docs/plans/site-ui-5-shots/explorer__1440-light.png deleted file mode 100644 index b45ba48e3..000000000 Binary files a/docs/plans/site-ui-5-shots/explorer__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/explorer__390-dark.png b/docs/plans/site-ui-5-shots/explorer__390-dark.png index 0d19ae844..d4a7c6443 100644 Binary files a/docs/plans/site-ui-5-shots/explorer__390-dark.png and b/docs/plans/site-ui-5-shots/explorer__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/explorer__390-light.png b/docs/plans/site-ui-5-shots/explorer__390-light.png deleted file mode 100644 index 44e94cf42..000000000 Binary files a/docs/plans/site-ui-5-shots/explorer__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/faucet__1440-dark.png b/docs/plans/site-ui-5-shots/faucet__1440-dark.png index 04df2a373..aa7e06aca 100644 Binary files a/docs/plans/site-ui-5-shots/faucet__1440-dark.png and b/docs/plans/site-ui-5-shots/faucet__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/faucet__1440-light.png b/docs/plans/site-ui-5-shots/faucet__1440-light.png deleted file mode 100644 index 131cfb8c7..000000000 Binary files a/docs/plans/site-ui-5-shots/faucet__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/faucet__390-dark.png b/docs/plans/site-ui-5-shots/faucet__390-dark.png index 37546d498..0a8e0a18d 100644 Binary files a/docs/plans/site-ui-5-shots/faucet__390-dark.png and b/docs/plans/site-ui-5-shots/faucet__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/faucet__390-light.png b/docs/plans/site-ui-5-shots/faucet__390-light.png deleted file mode 100644 index 7f4a26885..000000000 Binary files a/docs/plans/site-ui-5-shots/faucet__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/home-pending__375-dark.png b/docs/plans/site-ui-5-shots/home-pending__375-dark.png deleted file mode 100644 index 21ebc891f..000000000 Binary files a/docs/plans/site-ui-5-shots/home-pending__375-dark.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/home-sheet-open__390-dark.png b/docs/plans/site-ui-5-shots/home-sheet-open__390-dark.png deleted file mode 100644 index 93030221f..000000000 Binary files a/docs/plans/site-ui-5-shots/home-sheet-open__390-dark.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/home__1440-dark.png b/docs/plans/site-ui-5-shots/home__1440-dark.png index 5f930b25d..19ca9444c 100644 Binary files a/docs/plans/site-ui-5-shots/home__1440-dark.png and b/docs/plans/site-ui-5-shots/home__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/home__1440-light.png b/docs/plans/site-ui-5-shots/home__1440-light.png deleted file mode 100644 index 0bc50436c..000000000 Binary files a/docs/plans/site-ui-5-shots/home__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/home__390-dark.png b/docs/plans/site-ui-5-shots/home__390-dark.png index 7432a7732..58a306e2b 100644 Binary files a/docs/plans/site-ui-5-shots/home__390-dark.png and b/docs/plans/site-ui-5-shots/home__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/home__390-light.png b/docs/plans/site-ui-5-shots/home__390-light.png deleted file mode 100644 index 01fb4e32c..000000000 Binary files a/docs/plans/site-ui-5-shots/home__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/journey__1440-dark.png b/docs/plans/site-ui-5-shots/journey__1440-dark.png index d96b43fa7..785a74f3d 100644 Binary files a/docs/plans/site-ui-5-shots/journey__1440-dark.png and b/docs/plans/site-ui-5-shots/journey__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/journey__1440-light.png b/docs/plans/site-ui-5-shots/journey__1440-light.png deleted file mode 100644 index 0a41c221f..000000000 Binary files a/docs/plans/site-ui-5-shots/journey__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/journey__390-dark.png b/docs/plans/site-ui-5-shots/journey__390-dark.png index 9da013cf1..8c38275ca 100644 Binary files a/docs/plans/site-ui-5-shots/journey__390-dark.png and b/docs/plans/site-ui-5-shots/journey__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/journey__390-light.png b/docs/plans/site-ui-5-shots/journey__390-light.png deleted file mode 100644 index 4090b9093..000000000 Binary files a/docs/plans/site-ui-5-shots/journey__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/ledger__1440-dark.png b/docs/plans/site-ui-5-shots/ledger__1440-dark.png index 86947cc9b..a4ee3593c 100644 Binary files a/docs/plans/site-ui-5-shots/ledger__1440-dark.png and b/docs/plans/site-ui-5-shots/ledger__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/ledger__1440-light.png b/docs/plans/site-ui-5-shots/ledger__1440-light.png deleted file mode 100644 index 390440826..000000000 Binary files a/docs/plans/site-ui-5-shots/ledger__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/ledger__390-dark.png b/docs/plans/site-ui-5-shots/ledger__390-dark.png index d12a8a75f..17c6bd475 100644 Binary files a/docs/plans/site-ui-5-shots/ledger__390-dark.png and b/docs/plans/site-ui-5-shots/ledger__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/ledger__390-light.png b/docs/plans/site-ui-5-shots/ledger__390-light.png deleted file mode 100644 index 53c4cab66..000000000 Binary files a/docs/plans/site-ui-5-shots/ledger__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/litepaper__1440-dark.png b/docs/plans/site-ui-5-shots/litepaper__1440-dark.png index 6c93b25fd..e50028aa0 100644 Binary files a/docs/plans/site-ui-5-shots/litepaper__1440-dark.png and b/docs/plans/site-ui-5-shots/litepaper__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/litepaper__1440-light.png b/docs/plans/site-ui-5-shots/litepaper__1440-light.png deleted file mode 100644 index c33d1a6a7..000000000 Binary files a/docs/plans/site-ui-5-shots/litepaper__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/litepaper__390-dark.png b/docs/plans/site-ui-5-shots/litepaper__390-dark.png index 3ed56dcdf..162256784 100644 Binary files a/docs/plans/site-ui-5-shots/litepaper__390-dark.png and b/docs/plans/site-ui-5-shots/litepaper__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/litepaper__390-light.png b/docs/plans/site-ui-5-shots/litepaper__390-light.png deleted file mode 100644 index 9ff24e939..000000000 Binary files a/docs/plans/site-ui-5-shots/litepaper__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/live__1440-dark.png b/docs/plans/site-ui-5-shots/live__1440-dark.png index 321a90fe8..21ce3f2e2 100644 Binary files a/docs/plans/site-ui-5-shots/live__1440-dark.png and b/docs/plans/site-ui-5-shots/live__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/live__1440-light.png b/docs/plans/site-ui-5-shots/live__1440-light.png deleted file mode 100644 index a9c10c9c3..000000000 Binary files a/docs/plans/site-ui-5-shots/live__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/live__390-dark.png b/docs/plans/site-ui-5-shots/live__390-dark.png index e0690b5fe..247b5c989 100644 Binary files a/docs/plans/site-ui-5-shots/live__390-dark.png and b/docs/plans/site-ui-5-shots/live__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/live__390-light.png b/docs/plans/site-ui-5-shots/live__390-light.png deleted file mode 100644 index c44435d46..000000000 Binary files a/docs/plans/site-ui-5-shots/live__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/metamask__1440-dark.png b/docs/plans/site-ui-5-shots/metamask__1440-dark.png index 67fb30318..0995a0c44 100644 Binary files a/docs/plans/site-ui-5-shots/metamask__1440-dark.png and b/docs/plans/site-ui-5-shots/metamask__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/metamask__1440-light.png b/docs/plans/site-ui-5-shots/metamask__1440-light.png deleted file mode 100644 index 6e38772da..000000000 Binary files a/docs/plans/site-ui-5-shots/metamask__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/metamask__390-dark.png b/docs/plans/site-ui-5-shots/metamask__390-dark.png index 60249a6d8..ba7e784a7 100644 Binary files a/docs/plans/site-ui-5-shots/metamask__390-dark.png and b/docs/plans/site-ui-5-shots/metamask__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/metamask__390-light.png b/docs/plans/site-ui-5-shots/metamask__390-light.png deleted file mode 100644 index a9e81934e..000000000 Binary files a/docs/plans/site-ui-5-shots/metamask__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/miner-band__1440-dark.png b/docs/plans/site-ui-5-shots/miner-band__1440-dark.png new file mode 100644 index 000000000..e903c5adb Binary files /dev/null and b/docs/plans/site-ui-5-shots/miner-band__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/miner__1440-dark.png b/docs/plans/site-ui-5-shots/miner__1440-dark.png index fb5d9d7b8..cbd0425e0 100644 Binary files a/docs/plans/site-ui-5-shots/miner__1440-dark.png and b/docs/plans/site-ui-5-shots/miner__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/miner__1440-light.png b/docs/plans/site-ui-5-shots/miner__1440-light.png deleted file mode 100644 index af4a39a80..000000000 Binary files a/docs/plans/site-ui-5-shots/miner__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/miner__390-dark.png b/docs/plans/site-ui-5-shots/miner__390-dark.png index 5bf95ee07..11e21cae2 100644 Binary files a/docs/plans/site-ui-5-shots/miner__390-dark.png and b/docs/plans/site-ui-5-shots/miner__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/miner__390-light.png b/docs/plans/site-ui-5-shots/miner__390-light.png deleted file mode 100644 index cf97e1da8..000000000 Binary files a/docs/plans/site-ui-5-shots/miner__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/miners__1440-dark.png b/docs/plans/site-ui-5-shots/miners__1440-dark.png index 1d50e22de..891eab2c8 100644 Binary files a/docs/plans/site-ui-5-shots/miners__1440-dark.png and b/docs/plans/site-ui-5-shots/miners__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/miners__1440-light.png b/docs/plans/site-ui-5-shots/miners__1440-light.png deleted file mode 100644 index 84acf77da..000000000 Binary files a/docs/plans/site-ui-5-shots/miners__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/miners__390-dark.png b/docs/plans/site-ui-5-shots/miners__390-dark.png index d3b30ac6a..7746a69c9 100644 Binary files a/docs/plans/site-ui-5-shots/miners__390-dark.png and b/docs/plans/site-ui-5-shots/miners__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/miners__390-light.png b/docs/plans/site-ui-5-shots/miners__390-light.png deleted file mode 100644 index 9755c6956..000000000 Binary files a/docs/plans/site-ui-5-shots/miners__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/provenance__1440-dark.png b/docs/plans/site-ui-5-shots/provenance__1440-dark.png index 17b4a63ff..21a06fa7f 100644 Binary files a/docs/plans/site-ui-5-shots/provenance__1440-dark.png and b/docs/plans/site-ui-5-shots/provenance__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/provenance__1440-light.png b/docs/plans/site-ui-5-shots/provenance__1440-light.png deleted file mode 100644 index eb435bbfc..000000000 Binary files a/docs/plans/site-ui-5-shots/provenance__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/provenance__390-dark.png b/docs/plans/site-ui-5-shots/provenance__390-dark.png index 1bc9ec68f..da664bb4c 100644 Binary files a/docs/plans/site-ui-5-shots/provenance__390-dark.png and b/docs/plans/site-ui-5-shots/provenance__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/provenance__390-light.png b/docs/plans/site-ui-5-shots/provenance__390-light.png deleted file mode 100644 index e3ccd5226..000000000 Binary files a/docs/plans/site-ui-5-shots/provenance__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/randomx__1440-dark.png b/docs/plans/site-ui-5-shots/randomx__1440-dark.png index 30775bcb9..7db0ae531 100644 Binary files a/docs/plans/site-ui-5-shots/randomx__1440-dark.png and b/docs/plans/site-ui-5-shots/randomx__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/randomx__1440-light.png b/docs/plans/site-ui-5-shots/randomx__1440-light.png deleted file mode 100644 index 6657940e6..000000000 Binary files a/docs/plans/site-ui-5-shots/randomx__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/randomx__390-dark.png b/docs/plans/site-ui-5-shots/randomx__390-dark.png index d72a607ca..ae64547be 100644 Binary files a/docs/plans/site-ui-5-shots/randomx__390-dark.png and b/docs/plans/site-ui-5-shots/randomx__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/randomx__390-light.png b/docs/plans/site-ui-5-shots/randomx__390-light.png deleted file mode 100644 index 1d2243a3d..000000000 Binary files a/docs/plans/site-ui-5-shots/randomx__390-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/wallet-band__1440-dark.png b/docs/plans/site-ui-5-shots/wallet-band__1440-dark.png new file mode 100644 index 000000000..e57644903 Binary files /dev/null and b/docs/plans/site-ui-5-shots/wallet-band__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet-band__390-dark.png b/docs/plans/site-ui-5-shots/wallet-band__390-dark.png new file mode 100644 index 000000000..cb301b10b Binary files /dev/null and b/docs/plans/site-ui-5-shots/wallet-band__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet-full__1440-dark.png b/docs/plans/site-ui-5-shots/wallet-full__1440-dark.png new file mode 100644 index 000000000..a7fc584ea Binary files /dev/null and b/docs/plans/site-ui-5-shots/wallet-full__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet-full__390-dark.png b/docs/plans/site-ui-5-shots/wallet-full__390-dark.png new file mode 100644 index 000000000..aaa93617e Binary files /dev/null and b/docs/plans/site-ui-5-shots/wallet-full__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet__1440-dark.png b/docs/plans/site-ui-5-shots/wallet__1440-dark.png index dcb482e64..2c2a102c3 100644 Binary files a/docs/plans/site-ui-5-shots/wallet__1440-dark.png and b/docs/plans/site-ui-5-shots/wallet__1440-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet__1440-light.png b/docs/plans/site-ui-5-shots/wallet__1440-light.png deleted file mode 100644 index 13bad7c83..000000000 Binary files a/docs/plans/site-ui-5-shots/wallet__1440-light.png and /dev/null differ diff --git a/docs/plans/site-ui-5-shots/wallet__390-dark.png b/docs/plans/site-ui-5-shots/wallet__390-dark.png index 80643f6d0..385f01746 100644 Binary files a/docs/plans/site-ui-5-shots/wallet__390-dark.png and b/docs/plans/site-ui-5-shots/wallet__390-dark.png differ diff --git a/docs/plans/site-ui-5-shots/wallet__390-light.png b/docs/plans/site-ui-5-shots/wallet__390-light.png deleted file mode 100644 index c1e9d0202..000000000 Binary files a/docs/plans/site-ui-5-shots/wallet__390-light.png and /dev/null differ diff --git a/site/bench.html b/site/bench.html index a8ee089c2..cf81529f7 100644 --- a/site/bench.html +++ b/site/bench.html @@ -209,7 +209,7 @@ table{min-width:560px}
-
93 entries, newest at the bottom
+
94 entries, newest at the bottom

Engineering log

Every measurement the project has made, newest at the bottom, written by the people and agents who ran it, with the commands and hardware. Prototype numbers are not mining numbers and say so.

@@ -217,7 +217,7 @@ table{min-width:560px}
- +

Igneum bench log

Append-only. Every number here was measured on the machine named, on the date given.

@@ -942,7 +942,17 @@ table{min-width:560px}

The rented fleet is the devnet's finality, 6 October 2026 (branch gpu-fleet)

Measured at 21:57Z from the hub's last 2,000 blocks: the 38 wave pods held 77.8 percent of the voter weight (mean 2.05 percent a pod), the 14 standing boxes most of the rest, the hands and the hub the remainder; the last lock signed 93.5 percent of the active voters and 89.9 percent of the frozen table (53 of 84 voters on the first certificate). Earlier the same evening the fleet removed 13 miners' GPUs inside three minutes and finality paused for two hours five minutes (18:39:36Z to 20:44:44Z, 42.7 percent of the table gone with earlier leavers; rule v3 holds a full window). From that came the 10 percent rule (never remove more than 10 percent of the live devnet's weight in an hour, tools/fleet/lib/standing.py weight_check) and the wave's wind-down by hourly slices (tools/fleet/winddown.py: slice 1 at 21:58Z took 12 pods and the 8x rig at 8.6 percent of weight).

When the wave is gone the 14 standing boxes hold about 95 percent of the weight, so from then until public hash arrives the fleet alone is the devnet's finality: a home miner's lock lands only while the fleet is up. What holds it up: every standing box runs under box-standing.sh, which restarts a dead node within one of its 60-second passes (the hub's three deaths tonight: 63 s, 41 s and 56 s to the restart line), restarts the miner with the node, prunes the prover's exports and trims the node log, and runs the exec recovery recipe when the state layer reads zero; lib/standing.py loop re-rents a dead host in the same shape and reports a box behind its wanted binary.

-
TierWhat it means
Home mineryour lock depends on 14 rented cards staying up and mining; a finality pause is not your node's fault and nothing you can fix; the rule above is what keeps it from recurring on the fleet's side
Rigthe same, and a rig that leaves is itself a weight removal: at 459 MH/s on tonight's devnet it is about 20 percent of the weight, over the hour's budget by itself
Poola pool node is one voter carrying its members' whole weight; a pool restart is the largest single removal on the network and must be sliced like the fleet's
The networkfinality by miner weight is only as steady as the miners' uptime; until public hash dwarfs the fleet, the fleet's supervisor is a consensus component
+
TierWhat it means
Home mineryour lock depends on 14 rented cards staying up and mining; a finality pause is not your node's fault and nothing you can fix; the rule above is what keeps it from recurring on the fleet's side
Rigthe same, and a rig that leaves is itself a weight removal: at 459 MH/s on tonight's devnet it is about 20 percent of the weight, over the hour's budget by itself
Poola pool node is one voter carrying its members' whole weight; a pool restart is the largest single removal on the network and must be sliced like the fleet's
The networkfinality by miner weight is only as steady as the miners' uptime; until public hash dwarfs the fleet, the fleet's supervisor is a consensus component
+
+

7 October 2026, the first 16 GB card: an RTX 5060 Ti in a Thunderbolt enclosure on the RTX 5090 Windows rig (branch bench-5060ti)

+

Machine: the RTX 5090 Windows rig (1ccfe586, Windows 11), an ASUS Dual GeForce RTX 5060 Ti (16 GB GDDR7, Blackwell sm_120, PnP PCI\VEN_10DE&DEV_2D04&SUBSYS_8A111043) in a Razer Core X V2 Thunderbolt enclosure ("USB4 Router (2.0), Razer - Core X V2", bus 0B:00.0), beside the RTX 5090 on its own supply; NVIDIA driver 610.47 (WDDM 32.0.16.1047, the 5090's driver, nothing installed for the new card); the installed app 0.3.19 and its own igneum-worker-cuda.exe (NVRTC 12.8). Jobs fetch-5060ti-packs-20261007 (the kit: tools/bench-5060ti/make-kit.sh, the class v4 pack at sub-version 1 and the v3 control, sha256 fd8393ed..., 105,892 bytes) and run-5060ti-bench-20261007-b (tools/bench-5060ti/pc2-5060ti-bench.ps1, 14:44:19Z, ran 14:45:05 to 14:58:11Z, exit 0; the 5060 Ti alone through the runner's --cards-off, the 5090 mining throughout; run -a died in 1 s on an argument-binding fault in the nvidia-smi query and is void). the RTX 5090 Windows rig lost power twice that day, so the job WRITES NO POWER LIMIT: it reads power.limit against power.default_limit (180 W = 180 W, range 150 to 198 W) and the row says limit_is_stock=yes. Read back with node tools/jobs.mjs run-5060ti-bench-20261007-b.

+

Detection (the app's first poll after the restart, run win-1ccfe586-20261007-143611, 14:36:16Z): GPUs: NVIDIA GeForce RTX 5090 (CUDA); NVIDIA GeForce RTX 5060 Ti (CUDA); AMD Radeon(TM) Graphics (OpenCL, gfx1036) and cards: NVIDIA GeForce RTX 5090 [discrete, off] | NVIDIA GeForce RTX 5060 Ti [discrete, off] | ...; the app started a miner on it by itself (nvidia-1ccfe586-2, --device 1, 8 identities, the default). The kind reads discrete, not external: the app does not know it is an eGPU. nvidia-smi in the job: index 1, 16,311 MiB, PCIe link gen 4 x4 current against gen 4 x16 maximum (the Thunderbolt link: a quarter of the slot's lanes), 43 C idle. The freeze lane's cause class for the 15:10 UK hang on the first boot with the card: not the card (no TDR, no Thunderbolt or PCIe link event; Kernel-Power 41 + 6008, no bugcheck, the power shape again).

+

G1 and the window (the installed CUDA worker, --bench --batch-log2 24 --block-warps 1, the card alone, CUDA_VISIBLE_DEVICES on its UUID so every row names the device; nvidia-smi every 2 s on the card, the loaded samples at utilisation 90 percent and over):

+
PackDispatches of 2^24Self-testFingerprint 2^24 at base 0MH/s
mx8-devnet-epoch0 (the class v3 control)5PASS90f794dd556f7a3b (= the control everywhere)30.895
v4-devnet-epoch0 (class v4, sub-version 1, program id 1a4230699a6b9c60)5PASS867dbc45cfb36b4d (= Metal, Apple OpenCL, the RTX 5090)30.879
v4-devnet-epoch0, the 10-minute window at the stock limit1,105 (602 s)PASS867dbc45cfb36b4d30.882
+
RowValue
NVIDIA RTX 5060 Ti 16 GB, class v4, CUDA (NVRTC), driver 610.47, PCIe 4.0 x4 through the enclosure30.9 MH/s over 10 minutes on the card alone
Watts at the stock limit (180 W default, unchanged)114.8 W mean, 115 W p50 over the window; 0.269 MH/W; SM 2,753 MHz, memory 13,801 MHz, 60 C maximum
The class v4 shadow against the control0.1 percent (the 5090 paid 0.2, the 9070 XT 3, the B580 0.1)
The efficient pointOWED to the app's Ember Tune: nothing set by the job; the RTX 5090 Windows rig's Power Helper refused every request since the restart ("the helper did not run sequence 0 within 15 s", 14:39Z), so no ladder ran on either card
Prove beside the miner (16 GB tier)BLOCKED, not measured: the shipped WSL2 host (sha 71bc2438...) carries no IGNEUM_CUDA_DEVICE selector, so aimed at anything it proves on CUDA device 0 (the 5090) through the app's own socket /tmp/sp1-cuda-0.sock; the selector lives in the prover-floor host (proof_system.rs, branch prover-floor) and is the owed cut. The job's inventory: the floor server IS on the RTX 5090 Windows rig (<server path>, 6.8.1 build e911facb..., 166,665,880 bytes) beside the stock one (~/.sp1/bin, c2642ad1...), WSL sees the card as CUDA device 1
Card-picker entry (site/yourcard.js)['NVIDIA RTX 5060 Ti', 30.9], added; the public table row in site/miner-bench.json
+

Against the 5090 on the same PC (122 MH/s at 308 W, 0.396 MH/W): 25.3 percent of its hash at 37 percent of its draw, 68 percent of its hash per watt. The dependent-read ceiling was not probed (the memprobe step is not in this job); at 128 loads a hash 30.9 MH/s is 3.95 G dependent reads a second, between the 9070 XT (2.4 to 2.7 G) and the 5090 (16 to 18 G).

+

Consequences per tier (the rule of 5 October 2026): a 5060 Ti owner (16 GB, Windows) mines at 30.9 MH/s and 115 W from the box with nothing to set: about 5,100 blocks a day at the 522 MH/s the devnet showed at 14:44Z (one every 17 s, approximate: the network rate moves), about a quarter of a 5090 owner's 20,200, for 2.76 kWh a day (£0.79 at 28.5 p against the 5090's £2.11); through a Thunderbolt enclosure the x4 link costs nothing measurable (the hash is bound by the card's own memory latency, not the link; the 5090's PCIe-slot rows are the comparison), so a laptop with a Thunderbolt 4 port and this enclosure is a 31 MH/s miner. The 8 GB 5060 Ti: the same hash is the expectation (the 1 GiB dataset fits), a line owed. Proving on the 16 GB tier: the fleet's 4060 Ti 16 GB row (9.0 GB peak beside the miner on the patched server) says this card would mine and prove with about 7 GB spare, approximate until the host with the device selector ships; today the app's prover default leaves it off ("a full shard needs a 24 GB card") and the measured read is owed to the prover-floor host cut. Linux and HiveOS take the same CUDA worker (owed a line). What the lane does next: the prover-floor host's selector into the shipped WSL2 bundle, then the prove-beside read on this card; the Power Helper fault on the RTX 5090 Windows rig to the Ember lane (no efficient point on any the RTX 5090 Windows rig card until it answers).

+

Found on the way: inside a PowerShell @( ... ) the comma binds before +, so '--query-gpu=' + $f, '--format=csv' is one argument (run a, void in 1 s; the query string is built first now); a bare string inside a function that also returns a value is swallowed into the caller's variable (the sampler line; [Console]::Out.WriteLine now); the app's kind for a Thunderbolt card reads discrete (a word for the Cards page to earn: external, which the state already names).

Generated from the repository at build time. Times are UTC. Machine names are model names.

diff --git a/site/evidence.html b/site/evidence.html index 3185156fc..2d4f2b8b7 100644 --- a/site/evidence.html +++ b/site/evidence.html @@ -250,7 +250,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v 14Ethereum bytecode runs unchanged, with the documented differences of spec 7.1
Homepage Build card; litepaper Building
tested by the teamas 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 nodenone yet 15Every 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
implementedrepo 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.6proving/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 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 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 onenone yet 16A 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
designedspec 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 cardnone yet -17The chip resistance claim: the strongest chip in the public model reaches 5x to 9x per joule against an RTX 5090 today (modelled); class v4 brings it to 2.1x (k = 1) to 3.9x (k about 0.33, claimed by a withdrawn product) and its second rung to about 2.8x (modelled on measured watts); class v5 makes the dataset the chain's state so a stateless or stale chip is wrong on every item (designed, +0.2 ms verifier); the hot-set cache bounded at 1.067x at the ceiling (measured census of 1,024 programs) and the weak-day FPGA at most 12 percent on 12 days a century (measured census) are bounded and routed to the next class; datacentre silicon (H100 SXM, measured 7 October) does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years (modelled)
The home page's chip line, the litepaper's chip model section, the miner page's line (the texts of docs/plans/counter-asic-3-public-text-2026-10-07.md)
tested by the team (every card, the verifier, the two attack-pass censuses, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measureddocs/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/design/class-v5-stored-state.md; the H100 and market-cap rows of 7 October; docs/plans/funding.md (the three lots)The chip model re-run on the measured class v3 and v4 rates, watts and verifier times; the hot-set census of 1,024 programs and the weak-day census of 2^24 days on the attack-pass branch; the H100 SXM bench row136 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; 5.1x to 9.2x; 2.1x, 3.9x, 2.8x; 1.067x at the ceiling; 12 percent on 12 days a century; 10.85 ms at rung 3; USD 100 M; 6 and 7 October 2026none yet; the three cryptanalysis lots are the next test +17The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (k = 1) to 3.9x (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 12 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 core claimed and never measureddocs/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/funding.md (the three lots)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 bench136 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.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 12 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-1none yet; the three cryptanalysis lots are the next test 18The 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 teamreadwidth 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 loadLatency-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 2026none yet 19The 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 teamca2-mixer 1ab8b21 (tests/mixer.rs, tests/scratch.rs), ca2-era 78c0ee4, ca2-soundness a465881 (docs/analysis/scratch-soundness.md), igneum-pow/tests/packs.rsThe 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 cardClass 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)none yet 20No 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
implementedrepo 6ac80a3; fork "igneum-node devnet v0"; consensus/core/src/igneum.rs, coinbase.rscargo 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 happenednone yet diff --git a/site/index.html b/site/index.html index 097147471..4d75718af 100644 --- a/site/index.html +++ b/site/index.html @@ -219,7 +219,7 @@
01
The same card finds the block and proves it.

Both jobs pay. When you stop, the card still games.

02
A fair start.

Nobody holds a coin before block one. The protocol carries no fee. The one payment to the project is the Ember software’s optional 1% dev fee, like other GPU miners, off with one flag.

-
03
Built for graphics cards.

A new mining program every hour, so no chip is built for it. In our public model the strongest chip reaches 5x to 9x per joule against an RTX 5090 today; class v4, now on the vote, brings that to 2.1x to 3.9x. The model and every measurement are public.

+
03
Built for graphics cards.

At launch the strongest chip in our public model reaches 2.1x to 3.9x per joule against an RTX 5090, under class v4 from the first block. Class v5 then makes the dataset the chain’s own state, so a chip that stores it or recomputes it is wrong on every item. Without class v4 the same chip would reach 5x to 9x. The model and every measurement are public.

diff --git a/site/journey.html b/site/journey.html index 24b824955..9e1a8d4a4 100644 --- a/site/journey.html +++ b/site/journey.html @@ -208,7 +208,7 @@
-
Six phases · updated 6 Oct 2026
+
Six phases · updated 7 Oct 2026

The journey.

Six phases from the specification to a fair launch. Each closes at its gate, a measurement published whether it passes or fails, so there is no date to slip. Below the phases, the latest entries of the engineering log.

@@ -222,7 +222,8 @@
The log, newest first

Lately, in the log.

-
log

Counter ASIC 3.0

Counter ASIC 3.0: the class v4 rehearsal

+
log

The first 16 GB card

The first 16 GB card: an RTX 5060 Ti in a Thunderbolt enclosure on the RTX 5090 Windows rig

+
log

Counter ASIC 3.0

Counter ASIC 3.0: the class v4 rehearsal

log

16:01Z: Ember run 6 on the three-card Windows rig

log

Counter ASIC 3.0 item 2

Counter ASIC 3.0 item 2: the per-day derivation

log

Counter ASIC 3.0 item 8

Counter ASIC 3.0 item 8: program work in the latency shadow

@@ -255,13 +256,12 @@
log

The program id split

The program id split: why the Apple M5 Max rejected the RTX 5090 Windows rig's proofs, and the verifier at 114 s

log

Live devnet: the first shards proven, verified and paid

log

One-click Windows workers

One-click Windows workers: what the Apple M5 Max could measure

+
log

First live hourly swap: no pause on Mac, NVIDIA or AMD

First hourly program swap on the live devnet: compile-ahead, no pause, two cards

log

Proving: devnet v4 shards on the Apple M5 Max CPU, loaded machine

log

First live finality lock: 77.4% of weight, 17 voters

First finality lock on the live devnet: checkpoint 242 at 77.4% of all weight, two hours after genesis

log

The gfx1036 worker fault and what the Apple M5 Max could and could…

The gfx1036 worker fault and what the Apple M5 Max could and could not reproduce

log

A node 60 s behind the clock is silently dead

-
log

First machine on the one-click app: a 5090 at 118 MH/s

First machine on the Igneum Miner app: the RTX 5090 Windows rig's RTX 5090 at 118 MH/s, via Setup.exe

-
log

Difficulty rule v2

Difficulty rule v2: the live oscillation, its cause, the DAG replay, the fix behind a height switch

-
log

The observer stored nothing for 78 minutes, then 7,022 blocks in two…

The observer stored nothing for 78 minutes, then 7,022 blocks in two minutes

+
log

First machine on the one-click app: a 5090 at 118 MH/s

First machine on the Igneum Miner app: the RTX 5090 Windows rig's RTX 5090 at 118 MH/s, via Setup.exe

Every entry is a dated heading of the engineering log, where the commands and the hardware are. The phases and their gates are the litepaper’s roadmap.

diff --git a/site/journey.json b/site/journey.json index 0b30cc1b7..9f32d2ab0 100644 --- a/site/journey.json +++ b/site/journey.json @@ -1,5 +1,5 @@ { - "updated": "2026-10-06", + "updated": "2026-10-07", "stage": "phase-3", "phases": [ { @@ -50,6 +50,11 @@ } ], "log": [ + { + "date": "2026-10-07", + "text": "The first 16 GB card: an RTX 5060 Ti in a Thunderbolt enclosure on the RTX 5090 Windows rig", + "short": "The first 16 GB card" + }, { "date": "2026-10-06", "text": "Counter ASIC 3.0: the class v4 rehearsal", @@ -215,6 +220,11 @@ "text": "One-click Windows workers: what the Apple M5 Max could measure", "short": "One-click Windows workers" }, + { + "date": "2026-10-04", + "text": "First hourly program swap on the live devnet: compile-ahead, no pause, two cards", + "short": "First live hourly swap: no pause on Mac, NVIDIA or AMD" + }, { "date": "2026-10-04", "text": "Proving: devnet v4 shards on the Apple M5 Max CPU, loaded machine", @@ -239,16 +249,6 @@ "date": "2026-10-04", "text": "First machine on the Igneum Miner app: the RTX 5090 Windows rig's RTX 5090 at 118 MH/s, via Setup.exe", "short": "First machine on the one-click app: a 5090 at 118 MH/s" - }, - { - "date": "2026-10-04", - "text": "Difficulty rule v2: the live oscillation, its cause, the DAG replay, the fix behind a height switch", - "short": "Difficulty rule v2" - }, - { - "date": "2026-10-04", - "text": "The observer stored nothing for 78 minutes, then 7,022 blocks in two minutes", - "short": "The observer stored nothing for 78 minutes, then 7,022 blocks in two…" } ] } diff --git a/site/litepaper.html b/site/litepaper.html index c44f1b3ff..4b69a6e46 100644 --- a/site/litepaper.html +++ b/site/litepaper.html @@ -310,7 +310,7 @@ body.all .pager{display:none}

Abstract

-

Igneum is a proof-of-work blockchain built for graphics cards, where NVIDIA cards also prove every block with zero-knowledge proofs and sell proving to other chains. The strongest chip in our public model reaches 5x to 9x per joule against an RTX 5090 today; class v4, now on the vote, brings that to 2.1x to 3.9x, and class v5 makes the dataset the chain’s own state, so a chip that stores it or recomputes it is wrong on every item: the chip model, every number labelled measured, modelled, claimed or designed.

+

Igneum is a proof-of-work blockchain built for graphics cards, where NVIDIA cards also prove every block with zero-knowledge proofs and sell proving to other chains. At launch the strongest chip in our public model reaches 2.1x to 3.9x per joule against an RTX 5090, under class v4 from the first block; class v5 makes the dataset the chain’s own state, so a chip that stores it or recomputes it is wrong on every item; without class v4 the same chip would reach 5x to 9x: the chip model, every number labelled measured, modelled, claimed or designed.

It runs the Ethereum virtual machine, so anything built for Ethereum runs on Igneum unchanged. Transactions are included in about one second, proven within about a minute at launch, and locked by miners within about two. There is no premine, no pre-sale, no treasury taken from emission, no stake anywhere in consensus, and no dependence on any other chain. Mining stays open to anyone with a GPU because the mining program changes every hour, so a chip built for one program is useless for the next, and a chip for the whole program space is a GPU without the graphics parts. No scheduled human release is needed to keep it that way. Writing new code, including an emergency fix to the proof system, is the one thing that takes a person, and it activates only on miner signalling.

1 / s
blocks, rising to 10
@@ -435,17 +435,17 @@ body.all .pager{display:none}

Three ideas carry the chip resistance. The hash rewrites itself. A new program every hour, drawn from the chain. Its memory pattern changes with it. The rules change on a schedule fixed at launch. No release, no vote. These are automatic schedule changes: they defeat a chip wired for one datapath and they need no human fork. Against a chip that stores the dataset every drawn parameter is firmware, and what meets that chip is the latency-shadow work (class v4) and the price per joule (the Horizon lane analysis, 6 October 2026, section 5.4; ledger M32). It waits on memory, not maths. Every hash is a chain of random reads into a table too big for a chip to carry. The wait is the same physics for everyone. Miners hold the switch. Spare defences are written into the rules, switched off. A miner signal turns one on, at the class-change threshold: miners signal three things at three thresholds, 60 percent of blue blocks over two weeks for a parameter genesis leaves open, 90 percent for an upgrade (new code), and 95 percent with a floor height for a class change. No fork.

The work that waits can grow. Class v4 adds a block of latency-shadow arithmetic to every hash, about 100,000 integer operations that run while the memory reads are in flight, so a chip that stores the whole dataset still has to pay for a core. That size sits on a ladder fixed at genesis, six rungs from about 100,000 to about 1,000,000 operations, and it moves one rung at a time only when 90 percent of blue blocks in each of seven consecutive days ask for it; it can never move two rungs inside a week and never past a rung the reference verifier cannot check under 10 ms with its sibling thread busy (measured on the build server, 6 October 2026: the first three rungs pass at 8.8, 8.9 and 9.2 ms, the fourth misses by 0.08 ms on a loaded box and stays out until a quiet re-measurement, the two doublings are out at 12.4 and 15.0 ms). What it buys, on the measured cards: against a dataset-storing chip whose core costs what an RTX 5090's does per operation, the chip's per-joule edge falls from 2.1x at the first rung to 1.3x at the third; against a core as good as the one Bitmain claimed for its withdrawn Antminer X9 (about 3x per joule over a desktop CPU, never measured), from 3.9x to 2.8x. What it costs, per rung, is measured too: the Apple tier gives up 3 points of rate at the first step and 6 more at the second, the RTX 5090 nothing until the second; so the miners who pay for a step are the ones who take it (ledger M34).

The chip model

-

We price the strongest chip we can design against an RTX 5090 and publish the arithmetic. The honest card: an RTX 5090 mines class v3 at 136 MH/s on 350 W in the bench and 290 W in the app (measured, 6 October 2026); an Apple M5 Max at 27 MH/s on 21 W (measured, 6 October 2026); an H100 SXM at 249 MH/s, 98 percent of its random-read ceiling like the 5090, 1.78x the 5090’s hash at 1.15x the tuned 5090’s hash per watt and a third of the hash per rented dollar (measured, 7 October 2026), so datacentre silicon does not change the chip question. The CPU verifier takes 2.33 ms per warp of 32 hashes on one M5 Max core under class v4 (measured, 6 October 2026), against a gate of 10 ms.

+

We price the strongest chip we can design against an RTX 5090 and publish the arithmetic. Class v4 is live from the first block on the testnet and the mainnet (the ladder’s rung 0 at genesis), so the launch number is the class v4 row. The honest card: an RTX 5090 mines class v3 at 136 MH/s on 350 W in the bench and 290 W in the app (measured, 6 October 2026); an Apple M5 Max at 27 MH/s on 21 W (measured, 6 October 2026); an H100 SXM at 249 MH/s, 98 percent of its random-read ceiling like the 5090, 1.78x the 5090’s hash at 1.15x the tuned 5090’s hash per watt and a third of the hash per rented dollar (measured, 7 October 2026), so datacentre silicon does not change the chip question. The CPU verifier takes 2.33 ms per warp of 32 hashes on one M5 Max core under class v4 (measured, 6 October 2026), against a gate of 10 ms.

- - - + + +
The chip and the classEdge over an RTX 5090 per jouleLabel and date
A memory-controller chip that stores the whole dataset (the Ethash class), class v35x to 9x (5.1x on GDDR7, 9.2x on eight HBM3 stacks; the Ethash chips of this class reached 2.1x to 4.8x)modelled, 6 October 2026; the precedent measured by others, 2020 to 2022
The same chip under class v4 (about 100,000 integer ops per hash in the latency shadow, so the chip carries a GPU-class datapath beside its memory)2.1x with a core as costly per op as the GPU’s (k = 1); 3.9x with the core Bitmain claimed for its Antminer X9 (k about 0.33), a product withdrawn before any unit shippedmodelled on measured card watts, 6 October 2026; the X9 figure claimed, never measured
The same chip at the ladder’s second rung (about 200,000 ops per hash)about 2.8xmodelled, 7 October 2026
At launch: a memory-controller chip that stores the whole dataset, under class v4 (about 100,000 integer ops per hash in the latency shadow, so the chip carries a GPU-class datapath beside its memory)2.1x with a core as costly per op as the GPU’s (k = 1); 3.9x with the core Bitmain claimed for its Antminer X9 (k about 0.33), a product withdrawn before any unit shippedmodelled on measured card watts, 6 October 2026; the X9 figure claimed, never measured
The same chip at the ladder’s second rung (about 200,000 ops per hash), reached by miner signalabout 2.8xmodelled, 7 October 2026
Any chip under class v5, where the dataset is the chain’s own statea stateless or stale chip is wrong on every item, so the stored-dataset chip and the recompute chip are removed as categories; the verifier pays 0.2 ms more per warpdesigned, 7 October 2026
A chip caching the hottest 0.1 percent of items (about 1 MB of SRAM)bounded at 1.067x at the ceiling, 1.005x on about half the hours and 1.048x on 5 percentmeasured census of 1,024 programs, 7 October 2026; the source rule in the next class
A per-day FPGA that recomputes the dataset with cheap multipliers on a weak dayat most 12 percent more hash rate on 12 days a century, nothing on the other days and nothing for any chipmeasured census of 2^24 days, 7 October 2026; the rule in the next class
When a stored-dataset chip pays for itselfat about USD 100 M of market cap in the first two years, not beforemodelled, 7 October 2026
The baseline the work started from: the same chip under class v3, without the shadow (the Ethash class)5x to 9x (5.1x on GDDR7, 9.2x on eight HBM3 stacks; the Ethash chips of this class reached 2.1x to 4.8x)modelled, 6 October 2026; the precedent measured by others, 2020 to 2022; never the launch state
-

What a miner sees from this. Class v4 costs a 5090 about 80 W more for 0.2 percent of rate, an M5 Max 16 W more for 1.5 percent, an RX 9070 XT and an RTX 4070 nothing (all measured, 6 October 2026). The ladder that sets how much work rides in the shadow starts at rung 0 at the testnet genesis and climbs by miner signal; its third rung is inadmissible today because a server core verifies it in 10.85 ms, over the gate (measured, 7 October 2026). The next test of the model is not ours: the cryptanalysis plan buys three external lots against the mixer, the chained cache and the acceptance rule.

+

What a miner sees from this. Class v4 costs a 5090 about 80 W more for 0.2 percent of rate, an M5 Max 16 W more for 1.5 percent, an RX 9070 XT and an RTX 4070 nothing (all measured, 6 October 2026). The ladder that sets how much work rides in the shadow starts at rung 0 at genesis and climbs by miner signal; its third rung is inadmissible today because a server core verifies it in 10.85 ms, over the gate (measured, 7 October 2026). On the devnet, which started on class v3, class v4 arrives by miner signal at a published height (a devnet fact, not a launch one). The next test of the model is not ours: the cryptanalysis plan buys three external lots against the mixer, the chained cache and the acceptance rule.

No hash has stayed free of chips forever. Igneum does not claim to. It states the gain its own model finds, the response takes a week, and both are measured. The model is public: the numbers; the claim is tested by paid independent cryptanalysis and the public benchmark. Monero has run on RandomX since 2019 (approximate) with no chip shipped. Bitmain opened Antminer X9 pre-orders on 26 December 2025 for July 2026 delivery, then withdrew the product in mid-May 2026 and refunded buyers before any unit shipped; none has been independently benchmarked. A box with about a 2x per joule edge over the best CPUs, and about 3x over a desktop, was withdrawn rather than face a RandomX re-tune of 1.5x or more. That is the band Igneum’s class v4 model sits in (2.1x to 3.9x over an RTX 5090), and the defence that held was a maintained algorithm with a credible upgrade path, which is what the ladder is.

One thing takes a person, here and on every chain that exists: writing new code. A chain cannot safely write its own generator, and it cannot safely tell a chip from a wave of honest new cards by hashrate alone. If the design above ever failed, anyone could publish a new generator and miners would switch it on by signalling, as Monero's community can fork. Igneum is built to make that day unlikely, and does not depend on avoiding it.

diff --git a/site/miner.html b/site/miner.html index 567f5c0cb..9c2470043 100644 --- a/site/miner.html +++ b/site/miner.html @@ -302,7 +302,7 @@ pre b{color:var(--molten-text);font-weight:500}

Graphics cards only. A new mining program every hour, so no chip is built for it. 80% of every block to the card that finds it, 20% to the cards that prove it. No premine, no stake, no fee to any team. Every number above has a row in the bench table.

-

Your card against the strongest chip we can price: an RTX 5090 at 136 MH/s on 350 W (measured 6 October 2026), the chip 5x to 9x per joule in the public model today, 2.1x to 3.9x under class v4 (modelled on measured watts), and under class v5 wrong on every item because the dataset is the chain’s own state (designed); the model and the measurements are public.

+

Your card against the strongest chip we can price: an RTX 5090 at 136 MH/s on 350 W (measured 6 October 2026); at launch the chip reaches 2.1x to 3.9x per joule under class v4 (modelled on measured watts), and under class v5 it is wrong on every item because the dataset is the chain’s own state (designed). Without class v4 it would be 5x to 9x. The model and the measurements are public.

diff --git a/site/miners.html b/site/miners.html index 58bc33551..3f9c74794 100644 --- a/site/miners.html +++ b/site/miners.html @@ -209,7 +209,7 @@ table{min-width:560px}
-
6 measured rows, 0 fleet tuning models
+
7 measured rows, 0 fleet tuning models

GPU bench table

Measured hash rates per card on the Igneum lottery hash, with the generator version, the miner version, the date and the log entry behind each number.

@@ -220,13 +220,13 @@ table{min-width:560px}

The table

One row per card, generator version and miner version. The rate is the best one measured. Integrated GPUs are not listed. Prototype rows are bench numbers from before the devnet and say so in the miner column.

-
CardGeneratorBest MH/sMH per wattMinerDateSourceWho measured it
Apple M5 Max (40 GPU cores, Metal)
v145.2not measuredproto-metal bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090 first run (the Apple row of the same table)measured by the team. genesis program, 1 GiB dataset
Apple M5 Max (40 GPU cores, Metal)
v226.7not measuredigneum-miner devnet v4, Metal worker with prepare2026-10-04bench log: 4 October 2026, first hourly program swap on the live devnet: compile-ahead, no pause, two cardsmeasured by the team. live devnet v4, unbroken through the hour boundary
Apple silicon laptop (model not reported)
v224.3not measuredIgneum Miner 0.3.1 (DMG)2026-10-04bench log: 4 October 2026, first outside machine on the devnet: an Apple silicon laptop through the Igneum Miner appreported by the fleet. 21.0 MH/s average over 7 minutes, 24.3 MH/s at the moment of the report, 33 accepted blocks
NVIDIA RTX 5090 (32 GB)
v1229not measuredproto-cuda bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090, memory-hard dataset (pack igneum-genesis-mh)measured by the team. genesis program, 104 loads per hash, 1 GiB dataset
NVIDIA RTX 5090 (32 GB)
v1185.3not measuredproto-cuda bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090 first run, dataset sweep and second programmeasured by the team. hourly program, 128 loads per hash, 1 GiB dataset
NVIDIA RTX 5090 (32 GB)
v2124.2not measuredIgneum Miner 0.3.0 package, prebuilt NVRTC worker2026-10-04bench log: 4 October 2026, the gfx1036 worker fault and what the Apple M5 Max could and could not reproducemeasured by the team. live devnet v4, 128 loads per hash, CPU re-check clean, 0 rejected
+
CardGeneratorBest MH/sMH per wattMinerDateSourceWho measured it
Apple M5 Max (40 GPU cores, Metal)
v145.2not measuredproto-metal bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090 first run (the Apple row of the same table)measured by the team. genesis program, 1 GiB dataset
Apple M5 Max (40 GPU cores, Metal)
v226.7not measuredigneum-miner devnet v4, Metal worker with prepare2026-10-04bench log: 4 October 2026, first hourly program swap on the live devnet: compile-ahead, no pause, two cardsmeasured by the team. live devnet v4, unbroken through the hour boundary
Apple silicon laptop (model not reported)
v224.3not measuredIgneum Miner 0.3.1 (DMG)2026-10-04bench log: 4 October 2026, first outside machine on the devnet: an Apple silicon laptop through the Igneum Miner appreported by the fleet. 21.0 MH/s average over 7 minutes, 24.3 MH/s at the moment of the report, 33 accepted blocks
NVIDIA RTX 5060 Ti (16 GB)
v230.90.3Igneum Miner 0.3.19 package, prebuilt NVRTC worker (bench mode, class v4 program)2026-10-07bench log: 7 October 2026, the first 16 GB card: an RTX 5060 Ti in a Thunderbolt enclosure (run b)measured by the team. class v4 program, 128 loads per hash, 1 GiB dataset, 10-minute window on the card alone at the stock 180 W limit: 114.8 W mean; PCIe 4.0 x4 through the enclosure
NVIDIA RTX 5090 (32 GB)
v1229not measuredproto-cuda bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090, memory-hard dataset (pack igneum-genesis-mh)measured by the team. genesis program, 104 loads per hash, 1 GiB dataset
NVIDIA RTX 5090 (32 GB)
v1185.3not measuredproto-cuda bench (prototype, not mining)2026-10-03bench log: 3 October 2026, RTX 5090 first run, dataset sweep and second programmeasured by the team. hourly program, 128 loads per hash, 1 GiB dataset
NVIDIA RTX 5090 (32 GB)
v2124.2not measuredIgneum Miner 0.3.0 package, prebuilt NVRTC worker2026-10-04bench log: 4 October 2026, the gfx1036 worker fault and what the Apple M5 Max could and could not reproducemeasured by the team. live devnet v4, 128 loads per hash, CPU re-check clean, 0 rejected

How a row gets here

Every row names the engineering log entry or the job it came from. "Measured by the team" means our own hardware and our own log. "Reported by the fleet" means a machine we do not own, read from the status lines its miner uploads.

MH per watt needs the card's power draw during the run. The app reads it on NVIDIA cards through the driver. Rows get the figure when a run records it.

There is no other Igneum miner to compare with yet, so this table compares cards, not miners. The app that produces these rows: the miner page.

-

Rows: 6. Each row names the engineering log entry it came from.

+

Rows: 7. Each row names the engineering log entry it came from.

Fleet tuning priors

Ember Tune runs on every card the app mines with: the power limit and the core clock are stepped on the live program and the card keeps the point with the best MH per watt within 1% of its top rate. Every finished tune is reported back without anything that identifies the owner, and the fleet's median point per card model, driver major and program class comes back down inside the signed update manifest as the starting point for the next card of that model. A model needs 5 reports before its prior is used.

diff --git a/site/site.css b/site/site.css index fa8413f38..e39897a96 100644 --- a/site/site.css +++ b/site/site.css @@ -213,7 +213,8 @@ p.notice{display:block;margin:14px 0 0;font-size:13px;line-height:1.7} .dl-bar{display:none} @media (max-width:720px){.dl-bar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:30;justify-content:space-between;align-items:center;gap:var(--s-3);padding:10px var(--gutter) calc(10px + env(safe-area-inset-bottom));background:var(--top-bg);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);border-top:1px solid var(--line)}.dl-bar span{font:400 var(--t-sm)/1.4 var(--f-mono);color:var(--ash);min-width:0}body.has-dl-bar{padding-bottom:72px}} .band{background:var(--ember);color:var(--ember-ink)} -.band .wrap{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-5);padding-top:56px;padding-bottom:56px} +.band .wrap,.band .container{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--s-5);padding-top:56px;padding-bottom:56px} +@media (max-width:560px){.band .wrap,.band .container{padding-top:40px;padding-bottom:40px}} .band h2{color:var(--ember-ink);font-weight:900;margin-bottom:var(--s-2)} .band p{margin:0;max-width:56ch} .btn.dark{background:var(--obsidian);color:var(--bone);border-color:var(--obsidian)} @@ -497,9 +498,62 @@ article .status{white-space:normal;flex-wrap:wrap;overflow:visible} article .status .badge:not([data-mark]){white-space:normal;overflow-wrap:anywhere;line-height:1.5;max-width:100%} /* data tables size to their content and scroll inside their frame, never squeeze a column to a sliver (site-ui-5) */ .tbl table,.table-wrap table{width:100%;min-width:720px;table-layout:auto} -.tbl td,.table-wrap td{white-space:normal;overflow-wrap:anywhere;vertical-align:top;min-width:9ch} +.tbl td,.table-wrap td{white-space:normal;overflow-wrap:break-word;vertical-align:top;min-width:9ch} .tbl td .cardname,.table-wrap td .cardname{white-space:nowrap} .phero .os span{display:inline-flex;align-items:center} .download-platform{display:flex;align-items:center;gap:14px} /* the evidence table's status pills wrap inside their cell (overlap sweep, 7 Oct 2026) */ table#claims .st{white-space:normal;display:inline-block;line-height:1.4;max-width:100%} +/* the padding sweep (tools/ci/padding-check.mjs, 7 Oct 2026): every section's vertical padding on the scale (a multiple of 4 + from 24), every card's inner padding 24, so no text or control sits under 24 px from a filled edge */ +.page-hero,main .obs-head,.lost{padding-top:64px;padding-bottom:48px} +@media (max-width:560px){.page-hero{padding:24px 0}} +.site-footer{padding-bottom:24px} +.footer-bottom{padding-top:24px} +.doc-section,article section{padding-bottom:40px;margin-bottom:40px} +@media (max-width:860px){.sec{padding:72px 0}} +.lost{padding-bottom:96px} +.grid>section.card{padding-top:36px;padding-bottom:36px} +.motion{padding:24px} +.lab{padding-top:48px} +.dl-card,.home-tile,.tiles6>div,.mstats>div,.label,.card,.feature,.tool-card,.stat{padding:24px} +.dl-card{gap:14px 16px} +.dl-card .body{grid-column:1/-1} +.footer-bottom{padding-bottom:0} +@media (max-width:560px){.footer-bottom{padding-bottom:0}} +/* the ledger's count table keeps each status badge whole: the table scrolls, the word never breaks */ +.counts .badge:not([data-mark]){white-space:nowrap;overflow-wrap:normal} +/* the same scale and 24 px rule where a page's own style block sits later in the cascade (the sweep's second round) */ +main .layout article section{padding-bottom:40px;margin-bottom:40px} +main .lost{padding-top:64px;padding-bottom:96px} +main .motion{padding:24px} +main .lab{padding-top:48px} +main .tiles6>div,main .mstats>div{padding:24px 25px} +main .labels .label{padding:24px} +main .state-card,main .milestone{padding:24px} +main .strip{padding-top:24px;padding-bottom:24px} +/* the sweep's third round: the live inspector and toolbar at 24, the band and the download card 24 from their edges on phones */ +main .icol{padding:24px} +main .toolbar{padding:24px 25px} +@media (max-width:560px){.band .wrap,.band .container{padding-left:24px;padding-right:24px}.download-card{padding:24px}} +/* the journey's phases are cards in this system: the old timeline rail and marker (drawn for an unboxed list) go, the badge says the state; the when column keeps clear of the body */ +main .milestone:before,main .milestone:after{display:none} +main .milestone .when{padding-right:12px;padding-top:2px} +@media (max-width:560px){main .milestone{padding:24px}} +/* the litepaper's body paragraphs share one measure (the eye pass: the first paragraph sat narrower than the second) */ +main .layout article section>p{max-width:76ch} +/* the ledger's count table: a filter chip stays on one line, the table scrolls before a pill wraps */ +main table .chip{white-space:nowrap} +/* no orphan word on its own line (copy law 18): the browser's pretty wrapping on body text; headings already balance */ +p,li,dd,figcaption,.lead,.d,.sub{text-wrap:pretty} +/* a comparison table's label column holds a short phrase on one or two lines, never one word per line */ +main .tbl td:first-child,main .table-wrap td:first-child{min-width:14ch} +/* a section lifted into a derived page keeps its own .container: the inner one adds no second gutter; a card's table clears the text above it */ +main .container .container,main .wrap .wrap{padding-left:0;padding-right:0} +.feecard .tbl,.feecard .table-wrap{margin-top:16px} +/* the eye pass on /faucet and /metamask: the headline keeps a gap above its lead, two cards in a grid line up at the top, the page ends 72 px above the footer */ +main.wrap h1+p,main.wrap h1+.lead,.page-hero h1+.lead{margin-top:16px} +main.wrap>.grid{align-items:start} +main.wrap{padding-bottom:72px} +@media (max-width:560px){main.wrap{padding-bottom:48px}} +main.wrap>.grid{margin-bottom:40px} diff --git a/tools/ci/ledger-text-check.mjs b/tools/ci/ledger-text-check.mjs index cf24b8a19..09a97fae7 100644 --- a/tools/ci/ledger-text-check.mjs +++ b/tools/ci/ledger-text-check.mjs @@ -14,8 +14,8 @@ const REQUIRED = { ['X2', 'Public testnet: not yet open; the devnet build is here for people who want to look'], ['X7', 'hello@igneum.network'], ['X31', 'The public testnet is weeks away: three seed nodes and the public RPC are up, and it opens when the go checklist closes.'], - // 7 Oct 2026, 14:3x: the chip line of docs/plans/counter-asic-3-public-text-2026-10-07.md (the X9 label now lives on the litepaper) - ['X35', 'class v4, now on the vote, brings that to 2.1x to 3.9x'], + // 7 Oct 2026, 18:3x: the launch-first chip line of docs/plans/counter-asic-3-public-text-2026-10-07.md section 1 + ['X35', 'At launch the strongest chip in our public model reaches 2.1x to 3.9x per joule against an RTX 5090, under class v4 from the first block'], ], 'litepaper.html': [ ['X3', 'Live rows arrive with the public testnet.'], @@ -25,7 +25,7 @@ const REQUIRED = { ['C2', '2019 (approximate)'], ['X34', 'was withdrawn in mid-May 2026 before any unit shipped; RandomX 2.0 shipped on 25 March 2026'], ['X36', 'Bitmain opened Antminer X9 pre-orders on 26 December 2025 for July 2026 delivery, then withdrew the product in mid-May 2026 and refunded buyers before any unit shipped; none has been independently benchmarked.'], - ['X35', 'class v4, now on the vote, brings that to 2.1x to 3.9x'], + ['X35', 'so the launch number is the class v4 row'], ['X35', '3.9x with the core Bitmain claimed for its Antminer X9 (k about 0.33), a product withdrawn before any unit shipped'], ['X36', 'the X9 figure claimed, never measured'], ['M34', 'The work that waits can grow.'], diff --git a/tools/ci/padding-check.mjs b/tools/ci/padding-check.mjs new file mode 100644 index 000000000..ec34e4076 --- /dev/null +++ b/tools/ci/padding-check.mjs @@ -0,0 +1,170 @@ +#!/usr/bin/env node +// The padding and visuals sweep (site-ui-5, 7 October 2026; the project lead's /wallet band whose heading touched the band's top edge and +// whose button touched its bottom). Renders every served page at five widths in both themes and flags what a reader sees as +// cramped or broken, five classes: +// TIGHT text or a control closer than 24 px to the edge of the filled band, card or section that holds it +// SCALE a section whose vertical padding is off the design system's scale (0, or a multiple of 4 from 24 up) +// TOUCH two controls (buttons, links styled as buttons, inputs, selects) that touch or nearly touch (under 6 px apart) +// OVERRUN an image or canvas that runs out of its frame (the nearest .frame, .app-window, .scene, .panel or figure) +// UNDER-BAR a heading that renders under the sticky bar on load, or an anchor target the bar would cover on arrival +// The things that are small and filled by design (buttons, pills, badges, chips, tabs, table cells, the bar, tooltips) are +// containers whose own padding is theirs, so they are never the container of a TIGHT finding; segmented controls (.tabs, +// .theme-group, .zoom, [role=tablist]) are exempt from TOUCH. +// +// node tools/ci/padding-check.mjs --self-test the fixture (the exact /wallet band with its padding lost, a +// touching pair, an image over its frame, a heading under the bar) +// must fail with one finding of each class; the clean fixture passes +// node tools/ci/padding-check.mjs --site [dir] every *.html of the site (default site/) +// options: --widths 390,768,1024,1440,1600 --themes dark,light --only --json --jobs 3 +// +// Needs a browser: Playwright from $IGNEUM_PLAYWRIGHT_DIR, /srv/builds/_bin/overlap (the box) or this tree's node_modules. +// Without one it says so and exits 0 (CI installs Playwright; the box has it; the Mac renders nothing). Pages are served by +// tools/site/serve.mjs with /api answering 502, so every page renders its rest state; ?theme= and ?motion=off are passed. +import { readdirSync, readFileSync, writeFileSync, mkdtempSync, rmSync, existsSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import { join, dirname } from 'node:path'; +import { tmpdir } from 'node:os'; +import { fileURLToPath } from 'node:url'; +import { spawn } from 'node:child_process'; +import http from 'node:http'; +const here = dirname(fileURLToPath(import.meta.url)), repo = join(here, '..', '..'); +const args = process.argv.slice(2); +const opt = (k, d) => { const i = args.indexOf(k); return i >= 0 && args[i + 1] ? args[i + 1] : d; }; +const WIDTHS = opt('--widths', '390,768,1024,1440,1600').split(',').map(Number); +const THEMES = opt('--themes', 'dark,light').split(','); +const ONLY = opt('--only', ''), JSON_OUT = opt('--json', ''), JOBS = Number(opt('--jobs', '3')); +function playwright() { + for (const root of [process.env.IGNEUM_PLAYWRIGHT_DIR, '/srv/builds/_bin/overlap', repo].filter(Boolean)) { + try { return createRequire(join(root, 'package.json'))('playwright'); } catch (e) { /* next */ } + } + return null; +} +const pw = playwright(); +if (!pw) { console.log('padding-check: no Playwright here (the box and CI have it); nothing checked'); process.exit(0); } + +// what runs inside the page: returns the findings for this render +const INSPECT = `(() => { + const MIN = 24, GAP = 6, out = []; + const vis = el => { const r = el.getBoundingClientRect(); const cs = getComputedStyle(el); return r.width > 0 && r.height > 0 && cs.visibility !== 'hidden' && cs.display !== 'none' && Number(cs.opacity) > 0.05; }; + const txt = el => (el.textContent || '').replace(/\\s+/g, ' ').trim().slice(0, 60); + const path = el => { const parts = []; for (let e = el; e && e !== document.body && parts.length < 4; e = e.parentElement) parts.unshift(e.tagName.toLowerCase() + (e.id ? '#' + e.id : '') + (e.classList.length ? '.' + [...e.classList].slice(0, 2).join('.') : '')); return parts.join(' > '); }; + const alpha = c => { const m = /rgba?\\(([^)]+)\\)/.exec(c); if (!m) return c === 'transparent' ? 0 : 1; const p = m[1].split(',').map(s => parseFloat(s)); return p.length > 3 ? p[3] : 1; }; + // a filled container has a background, or a border on every side (a framed box); a rule above or below a block is not a box + const filled = el => { const cs = getComputedStyle(el); const bordered = ['Top','Right','Bottom','Left'].every(s => parseFloat(cs['border' + s + 'Width']) > 0 && alpha(cs['border' + s + 'Color']) > 0.02); return alpha(cs.backgroundColor) > 0.02 || cs.backgroundImage !== 'none' || bordered; }; + const SMALL = el => el.matches('a,button,input,select,textarea,label,td,th,.pill,.badge,.osmark,.chip,.tag,.tab,.tb,.state,.kind,.st,.sw,.lgi,.dot,code,kbd,summary,[role=tab],.nav,nav,.tip,.chip-zoom,.gen,.step-index,.n,.number,.num,.dev-label,.devnet,.hash-btn,.linkish,.switch,.track,.record-top .badge,.mini'); + // 1. TIGHT: the nearest filled, sizeable container of each text or control, and the distance to its edges + const containerOf = el => { for (let e = el.parentElement; e && e !== document.body; e = e.parentElement) { if (SMALL(e)) return null; if (filled(e)) { const r = e.getBoundingClientRect(); const radius = parseFloat(getComputedStyle(e).borderTopLeftRadius) || 0; /* a row (radius 12 or under) is the app's compact row, its own padding is its own; a card is 14 and up */ if (r.height >= 72 && r.width >= 200 && !(radius > 0 && radius <= 12)) return e; return null; } } return null; }; + const seen = new Set(); + for (const el of document.querySelectorAll('h1,h2,h3,h4,p,li,a.btn,button,input,select,.eyebrow,.lead,figcaption,dt,dd,.k,.v,.d,.mk,.mv,.mf,.key,strong.v')) { + if (!vis(el) || !txt(el) && !el.matches('a,button,input,select')) continue; + if (el.closest('.nav,.tip,.chip-zoom,table,.tabs,.theme-group,.zoom,.mode,.nav-sheet,.panels,figcaption,.frame .bar,.window-top,.hive-sheet,.footer-dl,.sheet-social,.social')) continue; + if (el.matches('figcaption')) continue; + const c = containerOf(el); if (!c) continue; + const r = el.getBoundingClientRect(), cr = c.getBoundingClientRect(), cs = getComputedStyle(c); + const inset = { top: r.top - cr.top, bottom: cr.bottom - r.bottom, left: r.left - cr.left, right: cr.right - r.right }; + // a container that scrolls or clips (a table frame, a window) is judged by what is inside its padding box only + const bad = Object.entries(inset).filter(([k, v]) => v >= -1 && v < MIN).map(([k, v]) => k + ' ' + Math.round(v) + 'px'); + if (bad.length) { const key = path(c) + '|' + bad.join(','); if (!seen.has(key)) { seen.add(key); out.push({ kind: 'TIGHT', what: txt(el) || el.tagName.toLowerCase(), where: path(el), container: path(c), detail: bad.join(', ') }); } } + } + // 2. SCALE: section paddings on the scale + for (const el of document.querySelectorAll('section,.sec,.band,.page-hero,.fold,.site-footer,.cta-band,main > .obs-head')) { + if (!vis(el)) continue; const cs = getComputedStyle(el); + for (const side of ['paddingTop', 'paddingBottom']) { const v = Math.round(parseFloat(cs[side])); if (v !== 0 && (v < 24 || v % 4 !== 0)) out.push({ kind: 'SCALE', what: side + ' ' + v + 'px', where: path(el), detail: 'not 0 and not a multiple of 4 from 24 up' }); } + } + // 3. TOUCH: controls that touch + const ctrls = [...document.querySelectorAll('a.btn,button,input,select,.community a,.dl-list a,.dl-row a,.footer-dl a')].filter(e => vis(e) && !e.closest('.tabs,.theme-group,.zoom,.mode,[role=tablist],.nav,.nav-sheet,.panels,table')); + for (let i = 0; i < ctrls.length; i++) for (let j = i + 1; j < ctrls.length; j++) { + const a = ctrls[i].getBoundingClientRect(), b = ctrls[j].getBoundingClientRect(); if (ctrls[i].contains(ctrls[j]) || ctrls[j].contains(ctrls[i])) continue; + const dx = Math.max(a.left, b.left) - Math.min(a.right, b.right), dy = Math.max(a.top, b.top) - Math.min(a.bottom, b.bottom); + if ((dx < GAP && dy < 0) || (dy < GAP && dx < 0)) out.push({ kind: 'TOUCH', what: (txt(ctrls[i]) || ctrls[i].tagName) + ' / ' + (txt(ctrls[j]) || ctrls[j].tagName), where: path(ctrls[i]), detail: 'gap ' + Math.round(Math.max(dx, dy)) + 'px' }); + } + // 4. OVERRUN: media out of its frame + for (const el of document.querySelectorAll('img,canvas,video')) { + if (!vis(el)) continue; const f = el.closest('.frame,.app-window,.scene,.panel,.fold-scene,.proof-scene,figure,.wallet-card'); if (!f) continue; + const r = el.getBoundingClientRect(), fr = f.getBoundingClientRect(), over = Math.max(r.right - fr.right, r.bottom - fr.bottom, fr.left - r.left, fr.top - r.top); + if (over > 2 && getComputedStyle(f).overflow === 'visible') out.push({ kind: 'OVERRUN', what: el.tagName.toLowerCase() + ' ' + (el.getAttribute('src') || el.id || '').split('/').pop(), where: path(f), detail: Math.round(over) + 'px past the frame' }); + } + // 5. UNDER-BAR: the bar covers a heading on load, or an anchor the bar would cover on arrival + const nav = document.querySelector('.nav'); const navH = nav ? nav.getBoundingClientRect().height : 0; + const h1 = [...document.querySelectorAll('h1')].find(vis); + if (h1 && navH && h1.getBoundingClientRect().top < navH - 1) out.push({ kind: 'UNDER-BAR', what: txt(h1), where: path(h1), detail: 'top ' + Math.round(h1.getBoundingClientRect().top) + 'px under a ' + Math.round(navH) + 'px bar' }); + const sp = parseFloat(getComputedStyle(document.documentElement).scrollPaddingTop) || 0; + for (const el of document.querySelectorAll('section[id],h2[id],h3[id],article[id],div[id].doc-section')) { const sm = parseFloat(getComputedStyle(el).scrollMarginTop) || 0; if (navH && Math.max(sp, sm) < navH) { out.push({ kind: 'UNDER-BAR', what: '#' + el.id, where: path(el), detail: 'scroll padding ' + Math.round(Math.max(sp, sm)) + 'px under a ' + Math.round(navH) + 'px bar' }); break; } } + return out; +})()`; + +async function serve(dir) { + const port = 4800 + Math.floor(Math.random() * 200); + const child = spawn(process.execPath, [join(repo, 'tools', 'site', 'serve.mjs'), String(port), dir, 'http://127.0.0.1:1'], { stdio: 'ignore' }); + await new Promise((res, rej) => { let n = 0; const t = setInterval(() => { http.get(`http://127.0.0.1:${port}/`, () => { clearInterval(t); res(); }).on('error', () => { if (++n > 80) { clearInterval(t); rej(new Error('serve.mjs did not answer')); } }); }, 100); }); + return { port, stop: () => child.kill() }; +} +async function sweep(dir, pages, browser) { + const { port, stop } = await serve(dir); + const findings = []; let renders = 0; + const jobs = []; for (const p of pages) for (const w of WIDTHS) for (const t of THEMES) jobs.push({ p, w, t }); + async function one({ p, w, t }) { + const ctx = await browser.newContext({ viewport: { width: w, height: w < 500 ? 844 : 900 }, deviceScaleFactor: 1, reducedMotion: 'reduce' }); + const page = await ctx.newPage(); + const route = p === 'index' ? '/' : '/' + p; + try { + await page.goto(`http://127.0.0.1:${port}${route}?theme=${t}&motion=off`, { waitUntil: 'load', timeout: 30000 }); + await page.waitForTimeout(250); + const found = await page.evaluate(INSPECT); + renders++; + for (const f of found) findings.push({ page: p, width: w, theme: t, ...f }); + } catch (e) { findings.push({ page: p, width: w, theme: t, kind: 'RENDER', what: e.message.split('\n')[0].slice(0, 120), where: route, detail: '' }); } + await ctx.close(); + } + let i = 0; await Promise.all(Array.from({ length: Math.max(1, JOBS) }, async () => { while (i < jobs.length) await one(jobs[i++]); })); + stop(); + return { renders, findings }; +} +const fmt = f => ` FAIL ${f.page} ${f.width}px ${f.theme}: ${f.kind} "${f.what}" in ${f.where}${f.container ? ' (container ' + f.container + ')' : ''}${f.detail ? ': ' + f.detail : ''}`; + +const browser = await pw.chromium.launch({ headless: true, args: ['--no-sandbox'] }); +try { + if (args.includes('--self-test')) { + // the fixture: the site's own stylesheet and bar, the exact /wallet band with its padding lost, a touching pair, an image over + // its frame, a heading under the bar; then the same page with each fixed + const site = join(repo, 'site'); + const fx = mkdtempSync(join(tmpdir(), 'padding-check-')); + const nav = readFileSync(join(site, 'partials', 'nav.html'), 'utf8'), head = readFileSync(join(site, 'partials', 'head.html'), 'utf8'); + const css = readFileSync(join(site, 'site.css'), 'utf8'); + writeFileSync(join(fx, 'site.css'), css); + const page = (broken) => `fixture${head.replace(/href="\/fonts\//g, 'href="/nofonts/').replace(/url\(\/fonts\//g, 'url(/nofonts/')} + +${nav} +

Fixture.

A page for the padding check.

+
+

The miner pays this wallet.

Install the miner, press Start, and the address it makes is the one this wallet imports with one click.

The miner
+`; + writeFileSync(join(fx, 'broken.html'), page(true)); writeFileSync(join(fx, 'clean.html'), page(false)); + writeFileSync(join(fx, '404.html'), '404'); writeFileSync(join(fx, 'icon-192.png'), readFileSync(join(site, 'icon-192.png'))); + const saveW = WIDTHS.splice(0, WIDTHS.length, 1440), saveT = THEMES.splice(0, THEMES.length, 'dark'); + const r = await sweep(fx, ['broken', 'clean'], browser); + rmSync(fx, { recursive: true, force: true }); + const broken = r.findings.filter(f => f.page === 'broken'), clean = r.findings.filter(f => f.page === 'clean'); + const kinds = new Set(broken.map(f => f.kind)); + const band = broken.find(f => f.kind === 'TIGHT' && /band/.test(f.container || '')); + let ok = true; + for (const k of ['TIGHT', 'TOUCH', 'OVERRUN', 'UNDER-BAR']) if (!kinds.has(k)) { console.error('self-test: the broken fixture did not raise ' + k); ok = false; } + if (!band) { console.error('self-test: the /wallet band with its padding lost was not flagged TIGHT'); ok = false; } + if (clean.length) { console.error('self-test: the clean fixture should pass\n' + clean.map(fmt).join('\n')); ok = false; } + if (!ok) process.exit(1); + console.log(`self-test passed: the band with no padding (${band.detail}), a touching pair, an image over its frame and a heading under the bar are caught; the clean fixture passes`); + WIDTHS.push(...saveW); THEMES.push(...saveT); + } + if (args.includes('--site')) { + const dir = opt('--site', '').startsWith('--') || !opt('--site', '') ? join(repo, 'site') : opt('--site'); + const pages = readdirSync(dir).filter(f => f.endsWith('.html')).map(f => f.replace(/\.html$/, '')).filter(p => !ONLY || p.includes(ONLY)); + const t0 = Date.now(); + const r = await sweep(dir, pages, browser); + if (JSON_OUT) writeFileSync(JSON_OUT, JSON.stringify(r.findings, null, 1)); + for (const f of r.findings) console.log(fmt(f)); + const byKind = {}; for (const f of r.findings) byKind[f.kind] = (byKind[f.kind] || 0) + 1; + console.log(`padding-check (site): ${r.renders} renders, ${r.findings.length} findings${r.findings.length ? ' (' + Object.entries(byKind).map(([k, n]) => k + ' ' + n).join(', ') + ')' : ''} in ${((Date.now() - t0) / 1000).toFixed(1)} s`); + if (r.findings.length) process.exitCode = 1; + } +} finally { await browser.close(); } diff --git a/tools/ci/pre-push.sh b/tools/ci/pre-push.sh index 5699d52cc..391b40955 100755 --- a/tools/ci/pre-push.sh +++ b/tools/ci/pre-push.sh @@ -79,6 +79,7 @@ tree_checks() { run "every served page carries the slim bar (mark, Mine, Network, Learn, Download) with every route in its panels and the sheet (self-test, then the tree)" bash -c 'node tools/ci/site-nav-check.mjs --self-test && node tools/ci/site-nav-check.mjs' run "vendor marks: site/lib/marks.mjs is brand/marks/vendor-marks.mjs byte for byte (the app and the site draw one set)" cmp brand/marks/vendor-marks.mjs site/lib/marks.mjs run "the phone menu opens and is seen at 390 px on every page (self-test first; needs the box or CI browser, says so without one)" node tools/site/sheet-test.mjs --self-test + run "padding and visuals: text 24 px from every band, card and section edge, section padding on the scale, no touching controls, media inside its frame, no heading under the bar, at 390 to 1600 px both themes (known-failed fixture first)" bash -c 'node tools/ci/padding-check.mjs --self-test && node tools/ci/padding-check.mjs --site "${SITE_TMP:-.}/site"' run "ledger sentences present verbatim on their public pages" node tools/ci/ledger-text-check.mjs never_push_checks run "shell inside .github/workflows parses (bash -n, the PowerShell 5.1 rule)" node tools/ci/check-workflow-shell.mjs