Compare commits
2 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7841ddfdc1 | ||
|
|
b1e45d9143 |
16 changed files with 82 additions and 186 deletions
|
|
@ -41,7 +41,7 @@ Versions in the table: `igneum-pow` is the Rust crate at `igneum-pow/Cargo.toml`
|
|||
| 14 | Ethereum bytecode runs unchanged, with the documented differences of spec 7.1 | Homepage Build card; litepaper Building | tested by the team | as row 13; fixes `F-exec-A`, `F-exec-B` (spec 7.5) | `tools/evm-smoke/smoke.mjs`: deploy via viem, `increment`, `hashLoop`, `eth_estimateGas`, `eth_getLogs`; `tools/exec-attacks` scenarios 1 and 3; bench-log "execution layer attack fixes" | Deployment, calls, reverts, logs and gas estimates behave as viem expects; chain id 4463; the prototype pgas table gives 0.0095 to 0.028 pgas per gas, below the design's band before calibration, 3 October 2026. 4 October 2026: a transaction that would cross the block's proving budget is refused by the mempool and, if forced in, aborted and charged with its nonce advanced (25 of 25 checks; 30 of 30 malformed cases). Apple M5 Max. The `Prover` precompile, proof records and the shard planner are not in the node | none yet |
|
||||
| 15 | Every block is proven, with the proof landing within about a minute at launch | Homepage stats ("~60 s to a proof"); litepaper Proving; roadmap phase 3 gate | implemented | repo `d7e1f89` (GPU proof), `e01a3cc`, `292e800`, `eedd136` (`proving/igneum-prove`: shard cutter, MPT witnesses, shard and aggregator guests); SP1 6.8.1; spec 7.2, 7.6 | `proving/windows-wsl2` (SETUP-PROVER, PROVE-BLOCK) on the RTX 5090; `igneum-prove-host --mode block` on `proving/fixtures/`; bench-log "proving v0 on the RTX 5090" and "proving: devnet v4 shards" | First GPU proof of an Igneum block, 4 October 2026, RTX 5090 (WSL2, SP1 cuda, mining paused): fixture `block-78-increment` (2 transactions), core proof 1.4 s (7.3 MB, verify 0.221 s), compressed proof 2.7 s (1.27 MB, verify 0.038 s), post-state and receipts roots identical to the node's; 15.7x and 20.6x faster than a loaded M5 Max CPU. The same day on that CPU (load 38 to 47): a three-shard block proved shard by shard and aggregated by recursion, 19 min (1,139 s) end to end, 245 to 337 s per compressed shard proof, every proof verified. What is not there: no proof is produced, carried or checked on the chain (the devnet prover is a stub that signs claims), the proving pool pays nobody (row 21), the block proven is far below one shard, and the 60-second figure remains a design target; the pass mark is the standard in `docs/benchmarks/proving-e2e.md`. Second RTX 5090 run, 4 October 2026 evening (job run-20261004-173115): a full shard at the provisional S_p (6.75 M pgas, 60.8 M cycles) executed in 1.63 s, core proof 8.3 s (18.1 MB), compressed proof 10.9 s (1.27 MB, verify 0.040 s); a two-shard block (13.5 M pgas) proved shard by shard (11.7 s and 10.0 s) and aggregated in 2.2 s, 24 s of GPU stages end to end, every proof verified, six tampered witnesses rejected. The two host defects (an abort after the upload, an idle wait that turned out to be an unbuffered 18 MB proof save through the WSL2 file bridge, 24 minutes) are fixed (ledger P20) 5 October 2026, live devnet with real transactions (bench-log "real transactions, the first non-empty shard proven and paid"): block 72704 shard 0, 29 transfers, 5,800 pgas, proven on PC 2 in 34 s, verified on the Mac in 0.297 s and paid 1.7623 IGN, 53 s after the chain block executed; of about 1,400 blocks in the 20-minute window 36 were proven (the one prover takes the newest shard assigned to it), so "every block" is not yet true; a second content shard (72803, all copies skipped) failed the native-execution veto on the exporter's block structure, fixed with fixtures the same day, the node side pending the 0.3.9 rollout 5 October 2026, evening (bench-log "proving v1"): the aggregated segment record, the chain rule and the unproven rule are implemented behind `proving_v1_activation_daa` (branch proving-v1, not on the devnet before 0.3.11); on the RTX 5090 a chain of 8 consecutive live blocks proved and aggregated by recursion in 135.6 s with the miner on the card (17 s a block, one proof of 1,272,909 bytes attesting all 8, verified in 0.04 s); the 3-node fast-time harness paid a segment record 1.0 s after submission and refused a late one after its deadline (21 checks); the devnet itself, with one prover, carried proofs for 2.4% of blocks over 30 minutes at a block-to-record latency p50 44 s, p99 52 s. The "within about a minute" holds per proven block; "every block" needs 18 mining 5090s or 6 proving-only cards at empty blocks on the measured rates, and the mandatory rule stays off until the share is one | none yet |
|
||||
| 16 | A 12 GB card proves one shard in about 20 s (WITHDRAWN 5 October 2026: a 24 GB card proves a full shard at the adopted size in 4.3 s; 32 GB mines and proves) | Litepaper Proving ("The proving budget"); roadmap gate 2 | designed | spec 5.1 (Target), 7.6 (`S_p` provisional, 7,500,000 pgas = `B_p` / 4) | `PROVE-SHARD.bat` on the RTX 5090 (pending); the end-to-end standard in `docs/benchmarks/proving-e2e.md`; bench-log "proving: devnet v4 shards" | Measured on a 32 GB card, not yet on a 12 GB card. A shard at the provisional `S_p` is 60.8 M SP1 cycles on the prototype pgas table (9 cycles per pgas, 44 per EVM gas; the modexp entry about 100x its SP1 cost); on an RTX 5090 (4 October 2026 evening, job run-20261004-173115) it executed in 1.63 s and its compressed proof took 10.9 s, verified in 0.040 s, so the 32 GB card is inside the 20 s target with margin. Whether a 12 GB card proves it at all, and in what time, is the next measurement (an RTX 3060 and an RTX 5060 Ti 16 GB are on order). A per-shard time can be met by shrinking the shard, so the project does not use it as a pass mark 5 October 2026, evening (bench-log "proving v1", the S_p curve): measured on the RTX 5090 with SP1 6.8.1's GPU prover, the card to itself, 1-s nvidia-smi samples: an empty shard 13,874 MiB and 2.2 s; a full shard at the ADOPTED v1 budget (30,000 pgas, 4.7 M cycles) 20,434 MiB and 4.3 s; the full prototype shard (6.75 M pgas, 60 M cycles) 28,307 MiB and 10.8 s; beside the miner 15,670 and 30,039 MiB. No environment knob of SP1 moves the 13.9 GB floor and the GPU server has no options of its own, so on this build a 12 GB card proves nothing, a 16 GB card only empty shards, a 24 GB card the adopted full shard alone and beside the miner (22,210 MiB and 13.2 s, measured on the 32 GB card: the 5090's allocation pattern, not yet a run on a 24 GB card) and a 32 GB card the prototype shard beside the miner with 2.5 GB spare. The litepaper line now says so; the 12 GB gate returns when a prover build with a smaller floor is measured on a 12 GB card | none yet |
|
||||
| 17 | The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (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/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.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 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026). | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
| 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 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 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/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026). | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
| 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 |
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ The chip model. We price the strongest chip we can design against an RTX 5090 an
|
|||
| The same chip at the ladder's second rung (about 200,000 ops per hash), reached by miner signal | about 2.8x | modelled, 7 October 2026 |
|
||||
| Any chip under class v5, where the dataset is the chain's own state | a 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 warp | designed, 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 percent | measured 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 day | at most 12 percent more hash rate on 12 days a century, nothing on the other days and nothing for any chip | measured census of 2^24 days, 7 October 2026; the rule in the next class |
|
||||
| A per-day FPGA that recomputes the dataset with cheap multipliers on a weak day | at most 12 percent more multiplier area on an FPGA's per-day build on 15 days a century, nothing on the other days and nothing for any chip | measured census of 2^24 days, 7 October 2026; the rule in the next class |
|
||||
| When a stored-dataset chip pays for itself | at about USD 100 M of market cap in the first two years, not before | modelled, 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 |
|
||||
|
||||
|
|
@ -30,4 +30,4 @@ Your card against the strongest chip we can price: an RTX 5090 at 136 MH/s on 35
|
|||
|
||||
| # | Claim | Where it is made | Status | Version or commit | Reproducible test | Result, date, machine | Independent verification |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 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/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.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 next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
| 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 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state) | the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line | tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 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/cryptanalysis/in-house-pass.md` (the internal adversarial pass) | the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses `tools/attack/f8-uniform` and the F4 census; the verifier by `igneum-pow bench` | 136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, PC 2's RTX 5090, PC 1's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 | none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word |
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -112,13 +112,3 @@ Three commits on 96161037: bd710a36 the sub-version 3 re-pin (byte 7, igneum-pow
|
|||
**The steward's two items before the public repository opens, both closed:** tools/exec-attacks/lib/common.mjs MINER_KEY is the public Anvil/Hardhat default account 1 key (five harnesses use it; balance 0 and nonce 0 on both chains at 20:55 and 20:59 BST; the fix is a chain-id guard in the five harnesses and a README line, a 0.3.24 steward row); app/igneum-wallet/src/hd.rs's KEY in one history commit is the public Hardhat default account 0 key in a removed test.
|
||||
|
||||
**Proven share, the second hour (20:59 BST):** cumulative 0.468 (1,848 of 3,952 shards since DAA 0); the hour's own segments 0.84 (1,094 of 1,304), the shortfall mostly the 34a2dbaa sweep's one-minute node restart per prover; eleven provers (five 3060s at about 85 s a segment, two 3090s, three 4090s, one A5000), a twelfth starting; the next hour's own segments should read one and the founder's 24 hours count from the first that does. **The pool hour** counts from 20:33:28 BST (dn3-pool-b's first OPEN SHARE on the 017e7037 daemons a357c581; WRONG HASH 0 since), the pool split's condition.
|
||||
|
||||
## 11. The 0.3.23 cut (21:1x to 21:3x BST): the fold, the version miss, the LG-4 shape
|
||||
|
||||
**release-0.3.23 = 05c2ddfe on the mirror:** 2f27ecb1 (the rights step 332b82eb with the deferred rule and the WebView2 right, the unattended driver install 50cdb8e4) + check-labels-23 e6f9ef0b + ota-token-23 757d7870 + the Windows pin to 2720d8d2 + dpi-23 ad407b13 (per-monitor DPI; BUILD-APP.bat, host.rc, host.manifest, host.cpp) + network-23 b18a5b0f (the first-run network step: the manifest's default_network, the testnet card present and refused until testnet_open, `--testnet --netsuffix=1` with the seeds as --addpeer; view.test.mjs resolved as the union of the check-labels and network tests) + install-close-23 5140e6fe (main's fold inside 15 minutes: the installer's stop step ends the window host first by path and waits up to 30 s for the unlock, CloseApplicationsFilter and SetupMutex in the .iss, install-running.flag holds every relaunch, the engine prints EXIT update and the host ends instead of restarting; tests known-failed first on tonight's PC 2 sequence) + the version bump 05c2ddfe. App gate GREEN on build-1 at every step (last 284 + 35 + 8), UI 86, pre-push 59. The version miss (rule 15): the branch carried 0.3.22 in every place until 21:26 BST, caught by the build-server lane before the host job; the exes and kit from 1c5323be are void. The Mac DMG re-cut under the lock on the 2720d8d2 Mac pair (igneumd efff01cd, igneum-miner 45c4c68f); the 0.3.23 host from the 05c2ddfe kit in the PC 1 slot after the hash lane's floor grid; the manifest carries default_network devnet-3 and keeps the floor file; the 0.3.23 Windows smoke is the first read of install-close-23 over a running app (the installer's own stop step, no pre-stop by the job) and of the OTA-return line through the app's own path.
|
||||
|
||||
**The 0.3.22 Windows smoke, take 1 FAIL (20:54 BST), the job shape:** the installer 5ac3dc62 built clean on PC 2 (every exe 0.3.22, the MSVC host 4bc25b7f through the host gate), but the job's silent install over the running 0.3.21 app sent api/quit, the engine stopped, the window host (the same pid since 19:14 BST) never stopped and its restart ladder relaunched the old engine 10 s later, Inno could not replace the locked host with its message box suppressed, every file stayed 0.3.21. Take 2 in the 0.3.10 smoke shape (the job stops the app by pid first, installs, asserts every file's version and sha, starts the host, reads the app alive at 60 s on 0.3.22 with stdin open). The defect is install-close-23 in 0.3.23. Devnet 3: the 34a2dbaa pass complete on every node by 21:17 BST (thirty-two read-backs incl. hub-1's and pool-1's second nodes); the 2720d8d2 pass started 21:17:23 BST with dn3-g1, the pair whole (igneumd df6476ed, miner dfdc6883, paired: program id 571131ccbd6e0de9 equal with c29f33bb at epoch 2).
|
||||
|
||||
**LG-4 (the founder: "use PC 1 or PC 2 or get another machine"; main's ruling):** on PC 2 tonight after both smokes, a fresh Windows user account created by job (no Igneum state, no card cache), the three timed steps (download and install, sync to the tip, dataset build to the first accepted share) as FIRST-SHARE lines, ten runs with the app uninstalled and the profile wiped between runs, no click anywhere, the rows on /evidence labelled "PC 2, fresh user account, not a fresh image, 7 October 2026", the 9-of-10 under-10-minutes bar read against them; macOS the same way as a fresh user account on the Mac tomorrow; a rented Windows VM only if the account shape fails the bar for a reason an image would change. PC 1 stays the founder's desk.
|
||||
|
||||
**0.3.22 Windows take 2 FAIL (21:13 BST) and the skip:** the job's detached helper was ended with the job's process tree before its first sleep ran out (Start-Process stays in the runner's tree; a survivor needs Win32_Process.Create or a scheduled task); nothing was installed, every file still 0.3.21, the payload untouched. Ruling: no take 3; the 0.3.22 Windows entry is skipped (the Mac and HiveOS entries stand); the first install over a running app is 0.3.23's installer with install-close-23 in the simplest job shape (Start-Process -Wait; the installer's own stop step and the install-running flag do the work), its smoke read the gate line for both; the Discord card publishes on the 0.3.23 Windows entry. **The version miss, second layer (21:30 BST):** the box cross of 0.3.23's exes failed in build.rs because igneum-app.rc still read 0.3.22 (Info.plist and the installer's AppVersion too); fixed at release-0.3.23 = 7c7489ac, the rule 15 check extended to six places and green on the tree; the 0.3.23 node pairs under /srv/artefacts/0323-2720d8d2/ (hands f2cf6a87/fb147dd1, seed 3edaf83d/be5ca735, win 8326d78a/38c74545) with the engine string.
|
||||
|
|
|
|||
|
|
@ -18,4 +18,3 @@ Every cut of the Igneum Miner app and its node runs under these. The dated plan
|
|||
11. **Kill by pid, never by name,** on the shared Mac; a merge worktree never checks out master.
|
||||
12. **The Discord card only when every platform is live.** Live manifest changes beyond the binaries (a moved consensus floor) go out only on the founder's explicit word, staged beside the release with their digest and a one-line diff.
|
||||
13. **Ship on green:** no calendar waits; when the gates are green, publish and state the clock time (UK). Checkpoints are for slips, not for waiting.
|
||||
15. **The version bump is the release branch's first commit (7 October 2026, after the 0.3.23 miss).** When a release-0.3.N branch opens, its first commit moves the six version places (app/igneum-app/Cargo.toml and Cargo.lock, app/windows/version.h, app/igneum-app/resources/igneum-app.rc's four fields, packaging/mac/app/Info.plist, the installer's AppVersion), never left to the cut: release-0.3.23 opened at 4cdcab31 and carried 0.3.22 in every place until 21:26 BST, so the app exes and the window host crossed from its first closed tip read 0.3.22 and were void. Gate check: on a push to release-0.3.N the pre-push gate (tools/ci/release-version-check.sh, self-test on tonight's shape first) reads all six places against the branch name and goes red on any mismatch; the .rc was the second layer of the same miss (the box cross failed in build.rs at 21:30 BST).
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ td.mono{font-family:var(--f-mono);font-size:12.5px;min-width:180px}td.iv{color:v
|
|||
<tr data-status="tested by the team"><td class="n">14</td><td class="claim">Ethereum bytecode runs unchanged, with the documented differences of spec 7.1<div class="where">Homepage Build card; litepaper Building</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">as row 13; fixes <code>F-exec-A</code>, <code>F-exec-B</code> (spec 7.5)</td><td><code>tools/evm-smoke/smoke.mjs</code>: deploy via viem, <code>increment</code>, <code>hashLoop</code>, <code>eth_estimateGas</code>, <code>eth_getLogs</code>; <code>tools/exec-attacks</code> scenarios 1 and 3; bench-log "execution layer attack fixes"</td><td>Deployment, calls, reverts, logs and gas estimates behave as viem expects; chain id 4463; the prototype pgas table gives 0.0095 to 0.028 pgas per gas, below the design's band before calibration, 3 October 2026. 4 October 2026: a transaction that would cross the block's proving budget is refused by the mempool and, if forced in, aborted and charged with its nonce advanced (25 of 25 checks; 30 of 30 malformed cases). Apple M5 Max. The <code>Prover</code> precompile, proof records and the shard planner are not in the node</td><td class="iv">none yet</td></tr>
|
||||
<tr data-status="implemented"><td class="n">15</td><td class="claim">Every block is proven, with the proof landing within about a minute at launch<div class="where">Homepage stats ("~60 s to a proof"); litepaper Proving; roadmap phase 3 gate</div></td><td><span class="st st-1">implemented</span></td><td class="mono">repo <code>d7e1f89</code> (GPU proof), <code>e01a3cc</code>, <code>292e800</code>, <code>eedd136</code> (<code>proving/igneum-prove</code>: shard cutter, MPT witnesses, shard and aggregator guests); SP1 6.8.1; spec 7.2, 7.6</td><td><code>proving/windows-wsl2</code> (SETUP-PROVER, PROVE-BLOCK) on the RTX 5090; <code>igneum-prove-host --mode block</code> on <code>proving/fixtures/</code>; bench-log "proving v0 on the RTX 5090" and "proving: devnet v4 shards"</td><td>First GPU proof of an Igneum block, 4 October 2026, RTX 5090 (WSL2, SP1 cuda, mining paused): fixture <code>block-78-increment</code> (2 transactions), core proof 1.4 s (7.3 MB, verify 0.221 s), compressed proof 2.7 s (1.27 MB, verify 0.038 s), post-state and receipts roots identical to the node's; 15.7x and 20.6x faster than a loaded M5 Max CPU. The same day on that CPU (load 38 to 47): a three-shard block proved shard by shard and aggregated by recursion, 19 min (1,139 s) end to end, 245 to 337 s per compressed shard proof, every proof verified. What is not there: no proof is produced, carried or checked on the chain (the devnet prover is a stub that signs claims), the proving pool pays nobody (row 21), the block proven is far below one shard, and the 60-second figure remains a design target; the pass mark is the standard in <code>docs/benchmarks/proving-e2e.md</code>. Second RTX 5090 run, 4 October 2026 evening (job run-20261004-173115): a full shard at the provisional S_p (6.75 M pgas, 60.8 M cycles) executed in 1.63 s, core proof 8.3 s (18.1 MB), compressed proof 10.9 s (1.27 MB, verify 0.040 s); a two-shard block (13.5 M pgas) proved shard by shard (11.7 s and 10.0 s) and aggregated in 2.2 s, 24 s of GPU stages end to end, every proof verified, six tampered witnesses rejected. The two host defects (an abort after the upload, an idle wait that turned out to be an unbuffered 18 MB proof save through the WSL2 file bridge, 24 minutes) are fixed (ledger P20) 5 October 2026, live devnet with real transactions (bench-log "real transactions, the first non-empty shard proven and paid"): block 72704 shard 0, 29 transfers, 5,800 pgas, proven on the RTX 5090 Windows rig in 34 s, verified on the Apple M5 Max in 0.297 s and paid 1.7623 IGN, 53 s after the chain block executed; of about 1,400 blocks in the 20-minute window 36 were proven (the one prover takes the newest shard assigned to it), so "every block" is not yet true; a second content shard (72803, all copies skipped) failed the native-execution veto on the exporter's block structure, fixed with fixtures the same day, the node side pending the 0.3.9 rollout 5 October 2026, evening (bench-log "proving v1"): the aggregated segment record, the chain rule and the unproven rule are implemented behind <code>proving_v1_activation_daa</code> (branch proving-v1, not on the devnet before 0.3.11); on the RTX 5090 a chain of 8 consecutive live blocks proved and aggregated by recursion in 135.6 s with the miner on the card (17 s a block, one proof of 1,272,909 bytes attesting all 8, verified in 0.04 s); the 3-node fast-time harness paid a segment record 1.0 s after submission and refused a late one after its deadline (21 checks); the devnet itself, with one prover, carried proofs for 2.4% of blocks over 30 minutes at a block-to-record latency p50 44 s, p99 52 s. The "within about a minute" holds per proven block; "every block" needs 18 mining 5090s or 6 proving-only cards at empty blocks on the measured rates, and the mandatory rule stays off until the share is one</td><td class="iv">none yet</td></tr>
|
||||
<tr data-status="designed"><td class="n">16</td><td class="claim">A 12 GB card proves one shard in about 20 s (WITHDRAWN 5 October 2026: a 24 GB card proves a full shard at the adopted size in 4.3 s; 32 GB mines and proves)<div class="where">Litepaper Proving ("The proving budget"); roadmap gate 2</div></td><td><span class="st st-0">designed</span></td><td class="mono">spec 5.1 (Target), 7.6 (<code>S_p</code> provisional, 7,500,000 pgas = <code>B_p</code> / 4)</td><td><code>PROVE-SHARD.bat</code> on the RTX 5090 (pending); the end-to-end standard in <code>docs/benchmarks/proving-e2e.md</code>; bench-log "proving: devnet v4 shards"</td><td>Measured on a 32 GB card, not yet on a 12 GB card. A shard at the provisional <code>S_p</code> is 60.8 M SP1 cycles on the prototype pgas table (9 cycles per pgas, 44 per EVM gas; the modexp entry about 100x its SP1 cost); on an RTX 5090 (4 October 2026 evening, job run-20261004-173115) it executed in 1.63 s and its compressed proof took 10.9 s, verified in 0.040 s, so the 32 GB card is inside the 20 s target with margin. Whether a 12 GB card proves it at all, and in what time, is the next measurement (an RTX 3060 and an RTX 5060 Ti 16 GB are on order). A per-shard time can be met by shrinking the shard, so the project does not use it as a pass mark 5 October 2026, evening (bench-log "proving v1", the S_p curve): measured on the RTX 5090 with SP1 6.8.1's GPU prover, the card to itself, 1-s nvidia-smi samples: an empty shard 13,874 MiB and 2.2 s; a full shard at the ADOPTED v1 budget (30,000 pgas, 4.7 M cycles) 20,434 MiB and 4.3 s; the full prototype shard (6.75 M pgas, 60 M cycles) 28,307 MiB and 10.8 s; beside the miner 15,670 and 30,039 MiB. No environment knob of SP1 moves the 13.9 GB floor and the GPU server has no options of its own, so on this build a 12 GB card proves nothing, a 16 GB card only empty shards, a 24 GB card the adopted full shard alone and beside the miner (22,210 MiB and 13.2 s, measured on the 32 GB card: the 5090's allocation pattern, not yet a run on a 24 GB card) and a 32 GB card the prototype shard beside the miner with 2.5 GB spare. The litepaper line now says so; the 12 GB gate returns when a prover build with a smaller floor is measured on a 12 GB card</td><td class="iv">none yet</td></tr>
|
||||
<tr data-status="designed"><td class="n">17</td><td class="claim">The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (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)<div class="where">the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line</div></td><td><span class="st st-0">tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured</span></td><td class="mono"><code>docs/analysis/chip-model-v3.md</code> 5 and 6; <code>docs/analysis/latency-shadow-2026-10-06.md</code>; <code>docs/plans/counter-asic-3-status.md</code>; <code>docs/analysis/attack-pass/f8-uniform.md</code>, <code>f4-weakday.md</code>, <code>docs/analysis/ca3-v4-uniform.md</code>; <code>docs/design/class-v5-stored-state.md</code>; the H100 and market-cap rows of 7 October; <code>docs/plans/cryptanalysis/in-house-pass.md</code> (the internal adversarial pass)</td><td>the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses <code>tools/attack/f8-uniform</code> and the F4 census; the verifier by <code>igneum-pow bench</code></td><td>136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.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-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026).</td><td class="iv">none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word</td></tr>
|
||||
<tr data-status="designed"><td class="n">17</td><td class="claim">The chip resistance claim: at launch the strongest chip in the public model reaches 2.1x (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 15 days a century, both routed to the next class; datacentre silicon does not change the question; a stored-dataset chip pays for itself only at about USD 100 M of market cap in two years; without class v4 the same chip would reach 5x to 9x (the class v3 baseline, the devnet's starting state, never the launch state)<div class="where">the home page's chip line, the litepaper's chip section (/litepaper#chip-model), the miner page's line</div></td><td><span class="st st-0">tested by the team (every card, the verifier, the two attack-pass bounds, the H100), the chip itself modelled, class v5 and the ladder designed, the X9 core claimed and never measured</span></td><td class="mono"><code>docs/analysis/chip-model-v3.md</code> 5 and 6; <code>docs/analysis/latency-shadow-2026-10-06.md</code>; <code>docs/plans/counter-asic-3-status.md</code>; <code>docs/analysis/attack-pass/f8-uniform.md</code>, <code>f4-weakday.md</code>, <code>docs/analysis/ca3-v4-uniform.md</code>; <code>docs/design/class-v5-stored-state.md</code>; the H100 and market-cap rows of 7 October; <code>docs/plans/cryptanalysis/in-house-pass.md</code> (the internal adversarial pass)</td><td>the chip model's arithmetic in its file; the card rows by the benchmark package; the attack-pass harnesses <code>tools/attack/f8-uniform</code> and the F4 census; the verifier by <code>igneum-pow bench</code></td><td>136 MH/s at 350 W (5090, bench) and 290 W (app); 27 MH/s at 21 W (M5 Max); 249 MH/s (H100 SXM) at 98 percent of its read ceiling, 1.78x hash, 1.15x MH/W, a third per rented dollar; 2.33 ms per warp; 2.1x, 3.9x, 2.8x at launch; 1.067x at the ceiling; 12 percent on 15 days a century; 10.85 ms at rung 3; USD 100 M; 5.1x to 9.2x the class v3 baseline; 6 and 7 October 2026, the M5 Max, the RTX 5090 Windows rig's RTX 5090, the three-card Windows rig's RX 9070 XT and RTX 4070, a rented H100 SXM, igneum-build-1 The k about 0.33 bound is the implied core of Bitmain's Antminer X9 (RandomX; 1,000 KH/s, 2,472 W, 2.47 J per KH, USD 5,600; pre-orders 26 December 2025), withdrawn in mid-May 2026 with buyers refunded before any unit shipped, no independent benchmark, commodity Sophgo SG2044 server SoCs with an AES accelerator, no tapeout: a claimed, unmeasured figure carried as the pessimistic bound, not a calibration point (attack pass AP-F5-1, 7 October 2026).</td><td class="iv">none yet; the next test is the internal adversarial pass (three lanes new to the hash code, outsider inputs only, reports published whole), and the one outside check is staged and waits on its escrow and the publish word</td></tr>
|
||||
<tr data-status="tested by the team"><td class="n">18</td><td class="claim">The chip resistance measurements: the program is latency-bound (random reads), not bandwidth-bound, on every card we own, and sits beyond a card's on-chip cache<div class="where">Litepaper Mining ("waits on memory latency, not on maths or bandwidth"), vs RandomX; the numbers page</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">readwidth e752fc7 (<code>docs/plans/read-width.md</code>), ca2-era 78c0ee4, ca2-cache 2de19e5 (<code>docs/plans/hot-table.md</code>)</td><td>The dependent-read probes at 32 to 1,024 MiB and the hash rate per class on the three cards; the latency-bound share = rate over the probe ceiling per load</td><td>Latency-bound share at the 1 GiB dataset: RTX 5090 0.96 (v2) and 1.01 (v3), RX 9070 XT 0.87 and 0.95, M5 Max 1.01 and 1.06; wider reads do not close the AMD gap (the 9070 XT does 2.4 G dependent reads per second at every width; the 5090 goes bandwidth-bound at 64 B, share 0.58); a 32 to 96 MiB hot table is not kept resident by any card while the dataset streams (g 0.80 to 0.87 in the added form). 5 October 2026</td><td class="iv">none yet</td></tr>
|
||||
<tr data-status="tested by the team"><td class="n">19</td><td class="claim">The lottery hash is sound as a hash: uniform output, deterministic, no out-of-bounds read, fuzzed; class v3 bit-exact on the three vendors<div class="where">Litepaper vs RandomX ("Every number above is measured and logged"), the numbers page</div></td><td><span class="st st-2">tested by the team</span></td><td class="mono">ca2-mixer 1ab8b21 (<code>tests/mixer.rs</code>, <code>tests/scratch.rs</code>), ca2-era 78c0ee4, ca2-soundness a465881 (<code>docs/analysis/scratch-soundness.md</code>), <code>igneum-pow/tests/packs.rs</code></td><td>The crate suite (53 + 4 + 19 + 7), the Metal fuzz, edge, stats and determinism runs on the v3 construction, the pack vectors and 2^24 fingerprints on Metal, Apple OpenCL, the RTX 5090 and the RX 9070 XT, the 1,024-hash CPU re-check per card</td><td>Class v3 (mixer x8 + era): 200-program fuzz 200 of 200 on Metal, every tenth on Apple OpenCL; the pinned v3 packs 3/3 + 3/3 and 96 of 96 lanes on Metal and Apple OpenCL; the six era packs' fingerprints equal on the three vendors (the three-card Windows rig (RTX 5090, RTX 4070, RX 9070 XT) job run-ca2-era-pc1-20261005, 5 October 2026); the v2 exports byte-identical on the v3 crate; the final-class PC rows and the G2 re-check: job run-ca2-era-pc1b-20261005 (pending at the time of writing)</td><td class="iv">none yet</td></tr>
|
||||
<tr data-status="implemented"><td class="n">20</td><td class="claim">No premine, no pre-sale, no allocation: every coin is minted by the schedule and every coin goes to the block producer (80%) and the proving pool (20%)<div class="where">Homepage stats and Economics tiles; litepaper Supply, Economics</div></td><td><span class="st st-1">implemented</span></td><td class="mono">repo <code>6ac80a3</code>; fork "igneum-node devnet v0"; <code>consensus/core/src/igneum.rs</code>, <code>coinbase.rs</code></td><td><code>cargo test -p kaspa-consensus-core igneum</code> (8 pass: subsidy table, ramp, split, cap) and <code>cargo test -p kaspa-consensus coinbase</code> (8 pass); <code>igneum-miner inspect 40</code>; bench-log "igneum-node devnet v0"</td><td>Coinbases on the devnet: 80/20 exact on 39 of 39 single-payee blocks, the 20% to the <code>igneum-proving-pool-v0</code> output; the per-second schedule sums to under the 4,000,000,000 cap by less than 100 coins; 3,168,808,781 units per DAA second in years 0 to 2, halving at 63,115,200 DAA s. 3 October 2026, Apple M5 Max. The devnet genesis carries no allocation; the mainnet genesis does not exist yet, so the claim is about the code and the stated rule, not a launch that has happened</td><td class="iv">none yet</td></tr>
|
||||
|
|
|
|||
|
|
@ -13,9 +13,16 @@ intake[_-]?key
|
|||
Tailscale
|
||||
tailscale
|
||||
ts\.net
|
||||
# the founder's name, logins and the earlier businesses are NOT in this file in any encoding (a base64 line is a disclosure to any reader, found
|
||||
# 7 October 2026, 21:3x UK, on the public host): they live in the private list ~/.config/igneum/founder-strings, read by site/scrub.mjs,
|
||||
# tools/ci/launch-gates-check.mjs and tools/ci/founder-strings-check.sh where it exists; the Mac's pre-push hook is the guard on every push.
|
||||
# the founder's name, logins and the earlier businesses, base64-encoded so the list is not itself a hit (a `b64:` line is decoded
|
||||
# and compiled case-insensitive by site/scrub.mjs and tools/ci/launch-gates-check.mjs; the same patterns live in tools/ci/founder-strings.b64)
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
b64:[encoded-pattern-removed]
|
||||
Hetzner
|
||||
igneum-seed
|
||||
/root/
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ body.all .pager{display:none}
|
|||
<tr><td>The same chip at the ladder’s second rung (about 200,000 ops per hash), reached by miner signal</td><td>about 2.8x</td><td>modelled, 7 October 2026</td></tr>
|
||||
<tr><td>Any chip under class v5, where the dataset is the chain’s own state</td><td>a 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 warp</td><td>designed, 7 October 2026</td></tr>
|
||||
<tr><td>A chip caching the hottest 0.1 percent of items (about 1 MB of SRAM)</td><td>bounded at 1.067x at the ceiling, 1.005x on about half the hours and 1.048x on 5 percent</td><td>measured census of 1,024 programs, 7 October 2026; the source rule in the next class</td></tr>
|
||||
<tr><td>A per-day FPGA that recomputes the dataset with cheap multipliers on a weak day</td><td>at most 12 percent more hash rate on 12 days a century, nothing on the other days and nothing for any chip</td><td>measured census of 2^24 days, 7 October 2026; the rule in the next class</td></tr>
|
||||
<tr><td>A per-day FPGA that recomputes the dataset with cheap multipliers on a weak day</td><td>at most 12 percent more multiplier area on an FPGA’s per-day build on 15 days a century, nothing on the other days and nothing for any chip</td><td>measured census of 2^24 days, 7 October 2026; the rule in the next class</td></tr>
|
||||
<tr><td>When a stored-dataset chip pays for itself</td><td>at about USD 100 M of market cap in the first two years, not before</td><td>modelled, 7 October 2026</td></tr>
|
||||
<tr><td>The baseline the work started from: the same chip under class v3, without the shadow (the Ethash class)</td><td>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)</td><td>modelled, 6 October 2026; the precedent measured by others, 2020 to 2022; never the launch state</td></tr>
|
||||
</tbody></table></div>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// so the build runs the same on this Mac, on Vercel and on the CI runner. The build fails if any pattern in
|
||||
// site/forbidden-strings.txt survives, so a private name, host or address can never reach the page.
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { homedir } from 'node:os';
|
||||
import { join, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
|
|
@ -60,21 +59,13 @@ const RULES = [
|
|||
[/\(local time, UTC\+1\)/g, '(UTC)'],
|
||||
[/\bB[S]T\b/g, 'UTC'],
|
||||
];
|
||||
// the private founder list (~/.config/igneum/founder-strings or $IGNEUM_FOUNDER_STRINGS; perl regex, a tab, a sample per row; # comments);
|
||||
// absent here: no founder patterns from this reader (the Mac's pre-push hook carries the file and is the guard)
|
||||
function founderPatternsFromFile() {
|
||||
try {
|
||||
const f = process.env.IGNEUM_FOUNDER_STRINGS || join(homedir(), '.config', 'igneum', 'founder-strings');
|
||||
return readFileSync(f, 'utf8').split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#')).map((l) => new RegExp(l.split('\t')[0], 'i'));
|
||||
} catch { return []; }
|
||||
}
|
||||
export function scrubBench(text) {
|
||||
let out = text;
|
||||
for (const [re, rep] of RULES) out = out.replace(re, rep);
|
||||
const pats = readFileSync(join(here, 'forbidden-strings.txt'), 'utf8').split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#'))
|
||||
.map(l => new RegExp(l)).concat(founderPatternsFromFile()); // plus the private founder list where it exists
|
||||
.map(l => (l.startsWith('b64:') ? new RegExp(Buffer.from(l.slice(4), 'base64').toString('utf8'), 'i') : new RegExp(l))); // a b64: line is an encoded, case-insensitive pattern
|
||||
const hits = [];
|
||||
out.split('\n').forEach((line, i) => { for (const p of pats) if (p.test(line)) { hits.push(`${i + 1}: ${p.flags.includes('i') ? '(a founder pattern from the private list)' : p.source}`); break; } });
|
||||
out.split('\n').forEach((line, i) => { for (const p of pats) if (p.test(line)) { hits.push(`${i + 1}: ${p.source.startsWith('(?<!') || p.flags.includes('i') ? '(an encoded founder pattern)' : p.source}`); break; } });
|
||||
if (hits.length) throw new Error(`scrub: forbidden strings remain on the bench page:\n${hits.slice(0, 20).join('\n')}`);
|
||||
return out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +1,37 @@
|
|||
#!/usr/bin/env bash
|
||||
# No founder name, personal login, earlier business or personal address in any tracked text file, in plain text OR in an encoding
|
||||
# (the pre-public scrub, 7 October 2026; a never-push class since 20:5x UK: every push, every branch). The identity check
|
||||
# (tools/ci/identity-check.sh) reads the public EXPORT list; this one reads EVERY tracked file, because the repository itself
|
||||
# is public (git.igneum.network).
|
||||
# No founder name, personal login, earlier business or personal address in any tracked text file (the pre-public scrub,
|
||||
# 7 October 2026, main's item (4): forbidden strings over tracked files on every merge, known-failed first). The identity
|
||||
# check (tools/ci/identity-check.sh) reads the public EXPORT list; this one reads EVERY tracked file, because the repository
|
||||
# itself goes public at the testnet (docs/fud-fixes.md section 5).
|
||||
#
|
||||
# The patterns are NOT in the repository in any form. They live in a private file, ~/.config/igneum/founder-strings
|
||||
# ($IGNEUM_FOUNDER_STRINGS overrides; one row per pattern: perl regex, a tab, a sample the self-test plants; # comments), on the
|
||||
# Mac that pushes. A base64 copy in the tree (tools/ci/founder-strings.b64, 19:5x to 21:3x UK) was a disclosure to any reader of
|
||||
# the public host and is gone from every commit. Where the file is absent (a hosted CI runner, a box) the check prints a skip
|
||||
# line and passes; the Mac's pre-push hook, which has the file, is the guard.
|
||||
# The patterns are not written in this tree in plain text: a plaintext list would be the hit it looks for. They live
|
||||
# base64-encoded in tools/ci/founder-strings.b64 (one decoded line per pattern: perl regex, a tab, a sample the self-test plants;
|
||||
# case-insensitive; # comments ignored)
|
||||
# and are decoded into a private temporary file at run time. The login's pre-rename spelling is in the list too (main's ruling,
|
||||
# 7 October 2026: the public tree names igneum-labs only); the fresh-repository step rewrites it in the history (tools/repo/fresh-repo.sh).
|
||||
#
|
||||
# Two passes over every tracked text file: the plain text, then every encoded blob decoded and scanned (base64 literals of 24
|
||||
# characters or more, every *.b64 file whole, hex literals of 24 characters or more), so an encoding never hides a term again.
|
||||
#
|
||||
# tools/ci/founder-strings-check.sh # exit 1 with file:line for every hit (decoded hits say so); exit 0 with a skip line without the list
|
||||
# tools/ci/founder-strings-check.sh --self-test # with a FIXTURE list of made-up names (never the real file): a clean tree passes; each
|
||||
# # sample planted in plain text, in a .b64 file, as a base64 literal and as a hex literal is
|
||||
# # caught and names its file; a tree without the list skips with the line
|
||||
# tools/ci/founder-strings-check.sh # exit 1 with file:line for every hit over the tracked text files
|
||||
# tools/ci/founder-strings-check.sh --self-test # a fixture tree with one hit per pattern class fails and names the file; a clean
|
||||
# # fixture passes; the encoded list decodes to at least five patterns
|
||||
set -euo pipefail
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
LIST="${IGNEUM_FOUNDER_STRINGS:-$HOME/.config/igneum/founder-strings}"
|
||||
LIST="$HERE/founder-strings.b64"
|
||||
REPO="${FOUNDER_CHECK_REPO:-$(cd "$HERE/../.." && pwd)}"
|
||||
|
||||
rows() { grep -vE '^\s*(#|$)' "$LIST"; } # the live rows
|
||||
scan() { # <repo> <list>: plain pass, then the decoded pass; prints "file:line:text" or "file:line:(decoded <kind>) text"; exit 1 on any hit
|
||||
local repo="$1" list="$2" pats hits
|
||||
pats="$(mktemp)"; chmod 600 "$pats"; grep -vE '^\s*(#|$)' "$list" | cut -f1 > "$pats"
|
||||
hits="$(cd "$repo" && git ls-files -z -- . ':!*.png' ':!*.jpg' ':!*.jpeg' ':!*.gif' ':!*.ico' ':!*.woff' ':!*.woff2' ':!*.ttf' ':!*.pdf' ':!*.zip' ':!*.bin' \
|
||||
decode() { # [samples]: the regexes (or, with "samples", the sample per regex), one per line, into a 0600 file whose name is printed
|
||||
local f col=1; [ "${1:-}" = samples ] && col=2
|
||||
f="$(mktemp)"; chmod 600 "$f"
|
||||
base64 -d < "$LIST" | grep -vE '^\s*(#|$)' | cut -f"$col" > "$f"
|
||||
echo "$f"
|
||||
}
|
||||
scan() { # <repo>: every tracked text file against the decoded list; prints file:line:text, exit 1 on any hit (perl: the Mac's grep has no -P)
|
||||
local repo="$1" pats hits
|
||||
pats="$(decode)"
|
||||
hits="$(cd "$repo" && git ls-files -z -- . ':!*.png' ':!*.jpg' ':!*.jpeg' ':!*.gif' ':!*.ico' ':!*.woff' ':!*.woff2' ':!*.ttf' ':!*.pdf' ':!*.zip' ':!*.bin' ':!*.b64' \
|
||||
| xargs -0 perl -e '
|
||||
use MIME::Base64 qw(decode_base64);
|
||||
my $pf = shift @ARGV; open(my $ph, "<", $pf) or die; my @pats = map { chomp; qr/$_/i } grep { /\S/ } <$ph>; close $ph;
|
||||
sub hit { my ($t) = @_; for my $p (@pats) { return 1 if $t =~ $p } 0 }
|
||||
for my $f (@ARGV) {
|
||||
next unless -f $f && -T $f; open(my $h, "<", $f) or next; my $n = 0; my $whole = "";
|
||||
while (my $l = <$h>) {
|
||||
$n++; $whole .= $l;
|
||||
if (hit($l)) { chomp $l; print "$f:$n:" . substr($l, 0, 160) . "\n"; next }
|
||||
# the encoded pass on this line: base64 literals and hex literals of 24 characters or more
|
||||
while ($l =~ /([A-Za-z0-9+\/]{24,}={0,2})/g) { my $d = decode_base64($1); next unless length $d; if (hit($d)) { print "$f:$n:(decoded base64) " . substr($d =~ s/[^\x20-\x7e]/./gr, 0, 120) . "\n"; last } }
|
||||
while ($l =~ /\b([0-9a-fA-F]{24,})\b/g) { my $x = $1; next if length($x) % 2; my $d = pack("H*", $x); if (hit($d)) { print "$f:$n:(decoded hex) " . substr($d =~ s/[^\x20-\x7e]/./gr, 0, 120) . "\n"; last } }
|
||||
}
|
||||
close $h;
|
||||
# a .b64 file as one blob
|
||||
if ($f =~ /\.b64$/) { (my $b = $whole) =~ s/\s+//g; my $d = decode_base64($b); if (length $d && hit($d)) { print "$f:1:(decoded .b64 file) " . substr($d =~ s/[^\x20-\x7e]/./gr, 0, 120) . "\n" } }
|
||||
}
|
||||
for my $f (@ARGV) { next unless -f $f && -T $f; open(my $h, "<", $f) or next; my $n = 0;
|
||||
while (my $l = <$h>) { $n++; for my $p (@pats) { if ($l =~ $p) { chomp $l; print "$f:$n:" . substr($l, 0, 160) . "\n"; last } } } close $h; }
|
||||
' "$pats" 2>/dev/null || true)"
|
||||
rm -f "$pats"
|
||||
if [ -n "$hits" ]; then printf '%s\n' "$hits" | sed 's/^/founder-strings: /' >&2; return 1; fi
|
||||
|
|
@ -51,34 +39,28 @@ scan() { # <repo> <list>: plain pass, then the decoded pass; prints "file:line
|
|||
}
|
||||
|
||||
if [ "${1:-}" = "--self-test" ]; then
|
||||
top="$(mktemp -d)"; trap 'rm -rf "$top"' EXIT; fx="$top/repo"; mkdir -p "$fx"
|
||||
fixture="$top/list"; printf '# fixture\n\\bfoundername\\b\tfoundername\n\\bsurnamex\\b\tSurnamex\n\\bbiznamez\\b\tbiznamez\n' > "$fixture"
|
||||
( cd "$fx" && git init -q -b master . ); mkdir -p "$fx/docs" "$fx/tools/ci" "$fx/site"
|
||||
n="$(base64 -d < "$LIST" | grep -vcE '^\s*(#|$)')"
|
||||
[ "$n" -ge 5 ] || { echo "self-test failed: the encoded list decodes to $n pattern(s), expected at least 5"; exit 1; }
|
||||
fx="$(mktemp -d)"; trap 'rm -rf "$fx"' EXIT
|
||||
( cd "$fx" && git init -q -b master . )
|
||||
mkdir -p "$fx/docs"
|
||||
# a clean tree: the standing login, the project, a neutral owner word
|
||||
printf 'Commit as igneum-labs. The founder decided on 5 October 2026. Igneum Labs LTD, DIFC.\n' > "$fx/docs/clean.md"
|
||||
printf 'aGVsbG8gd29ybGQsIG5vdGhpbmcgaGVyZQ==\n' > "$fx/tools/ci/clean.b64" # "hello world, nothing here"
|
||||
( cd "$fx" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m c )
|
||||
fails=0
|
||||
scan "$fx" "$fixture" >/dev/null 2>&1 || { echo "self-test failed: a clean tree (with a harmless .b64) was reported"; fails=1; }
|
||||
i=0
|
||||
while IFS=$'\t' read -r re sample; do
|
||||
i=$((i + 1)); [ -n "$sample" ] || continue
|
||||
for kind in plain b64file base64 hex; do
|
||||
case "$kind" in
|
||||
plain) f="docs/hit-$i.md"; printf 'a line that names %s in passing\n' "$sample" > "$fx/$f" ;;
|
||||
b64file) f="tools/ci/hit-$i.b64"; printf 'a line that names %s in passing\n' "$sample" | base64 > "$fx/$f" ;;
|
||||
base64) f="site/hit-$i.mjs"; printf 'const X = "%s";\n' "$(printf 'a line that names %s in passing' "$sample" | base64 | tr -d '\n')" > "$fx/$f" ;;
|
||||
hex) f="site/hit-$i-hex.mjs"; printf 'const H = "%s";\n' "$(printf 'a line that names %s in passing' "$sample" | xxd -p | tr -d '\n')" > "$fx/$f" ;;
|
||||
esac
|
||||
( cd "$fx" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m "h" )
|
||||
if out="$(scan "$fx" "$fixture" 2>&1)"; then echo "self-test failed: pattern $i was not caught as $kind"; fails=1
|
||||
else case "$out" in *"$f"*) ;; *) echo "self-test failed: the $kind hit for pattern $i did not name $f: $out"; fails=1 ;; esac; fi
|
||||
rm -f "$fx/$f"; ( cd "$fx" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m "r" )
|
||||
done
|
||||
done < <(grep -vE '^\s*(#|$)' "$fixture")
|
||||
# without a list: the skip line, exit 0
|
||||
out="$(IGNEUM_FOUNDER_STRINGS="$fx/no-such-list" FOUNDER_CHECK_REPO="$fx" bash "$0" 2>&1)" && case "$out" in *"skipped, no private list"*) ;; *) echo "self-test failed: no skip line without the list: $out"; fails=1 ;; esac || { echo "self-test failed: a tree without the list did not pass with a skip line"; fails=1; }
|
||||
[ "$fails" = 0 ] && echo "self-test passed: a clean tree passes; every fixture pattern is caught in plain text, in a .b64 file, as a base64 literal and as a hex literal, each naming its file; without the private list the check skips with its line"
|
||||
FOUNDER_CHECK_REPO="$fx" bash "$0" >/dev/null 2>&1 || { echo "self-test failed: a clean tree was reported"; exit 1; }
|
||||
# one hit per pattern class, each from the encoded list's own sample column, so this script never spells them; every hit
|
||||
# must name its file
|
||||
samples="$(decode samples)"; i=0; fails=0
|
||||
while IFS= read -r word; do
|
||||
i=$((i + 1)); [ -n "$word" ] || continue
|
||||
printf 'a line that names %s in passing\n' "$word" > "$fx/docs/hit-$i.md"
|
||||
( cd "$fx" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m "h$i" )
|
||||
if out="$(FOUNDER_CHECK_REPO="$fx" bash "$0" 2>&1)"; then echo "self-test failed: pattern $i was not caught"; fails=1
|
||||
else case "$out" in *"docs/hit-$i.md"*) ;; *) echo "self-test failed: the hit for pattern $i did not name its file: $out"; fails=1 ;; esac; fi
|
||||
rm -f "$fx/docs/hit-$i.md"; ( cd "$fx" && git add -A && git -c user.name=t -c user.email=t@t commit -q -m "r$i" )
|
||||
done < "$samples"; rm -f "$samples"
|
||||
# a binary file carrying a pattern is not read (images are not text)
|
||||
[ "$fails" = 0 ] && echo "self-test passed: a clean tree passes; every pattern class in the encoded list is caught in a fixture file and named; the list decodes to $n patterns"
|
||||
exit $fails
|
||||
fi
|
||||
if [ ! -s "$LIST" ]; then echo "founder-strings: skipped, no private list at $LIST (the Mac's pre-push hook carries the list and is the guard; a runner or box has none)"; exit 0; fi
|
||||
scan "$REPO" "$LIST" && echo "founder-strings: no founder name, personal login, earlier business or personal address in any tracked text file, plain or encoded ($(rows | wc -l | tr -d ' ') patterns from the private list)"
|
||||
scan "$REPO" && echo "founder-strings: no founder name, personal login, earlier business or personal address in any tracked text file"
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
// node tools/ci/launch-gates-check.mjs --self-test # a gate row without a check fails; a handoff with the founder's name fails
|
||||
import { existsSync, readFileSync, mkdtempSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import path, { join } from 'node:path';
|
||||
import { homedir } from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
|
@ -22,18 +21,11 @@ const GO = 'docs/plans/testnet-go.md';
|
|||
const PACK = 'docs/plans/launch-pack.md';
|
||||
const INCOME = 'docs/analysis/income-tiers.md';
|
||||
|
||||
// the private founder list (~/.config/igneum/founder-strings or $IGNEUM_FOUNDER_STRINGS; perl regex, a tab, a sample per row; # comments);
|
||||
// absent here: no founder patterns from this reader (the Mac's pre-push hook carries the file and is the guard)
|
||||
function founderPatternsFromFile() {
|
||||
try {
|
||||
const f = process.env.IGNEUM_FOUNDER_STRINGS || join(homedir(), '.config', 'igneum', 'founder-strings');
|
||||
return readFileSync(f, 'utf8').split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#')).map((l) => new RegExp(l.split('\t')[0], 'i'));
|
||||
} catch { return []; }
|
||||
}
|
||||
function patterns(root) {
|
||||
const read = f => { try { return readFileSync(path.join(root, f), 'utf8'); } catch { return ''; } };
|
||||
const lines = [...read('site/forbidden-strings.txt').split('\n'), ...read('tools/ci/forbidden-strings.txt').split('\n')];
|
||||
return lines.map(l => l.trim()).filter(l => l && !l.startsWith('#')).map(l => new RegExp(l)).concat(root === process.cwd() || root === ROOT ? founderPatternsFromFile() : []); // plus the private founder list for the real tree
|
||||
return lines.map(l => l.trim()).filter(l => l && !l.startsWith('#'))
|
||||
.map(l => (l.startsWith('b64:') ? new RegExp(Buffer.from(l.slice(4), 'base64').toString('utf8'), 'i') : new RegExp(l))); // b64: = an encoded founder pattern
|
||||
}
|
||||
|
||||
export function gateRows(text) {
|
||||
|
|
@ -108,7 +100,7 @@ function selfTest() {
|
|||
const fx = mkdtempSync(path.join(tmpdir(), 'launch-gates-'));
|
||||
try {
|
||||
for (const d of ['docs/plans', 'docs/analysis', 'site', 'tools/ci', 'tools/launch']) mkdirSync(path.join(fx, d), { recursive: true });
|
||||
writeFileSync(path.join(fx, 'site/forbidden-strings.txt'), '(?i)\\bfoundername\\b\n'.replace('(?i)', '')); // a made-up name as a plain pattern (the private list is not read for a fixture root)
|
||||
writeFileSync(path.join(fx, 'site/forbidden-strings.txt'), 'b64:XGJmb3VuZGVybmFtZVxi\n'); // an encoded, case-insensitive pattern for a made-up name
|
||||
writeFileSync(path.join(fx, 'tools/ci/forbidden-strings.txt'), '/Users/\n');
|
||||
writeFileSync(path.join(fx, 'tools/launch/x.mjs'), '');
|
||||
const sentences = Array.from({ length: 8 }, (_, i) => `${i + 1}. sentence (8.3 sentence ${i + 1})`).join('\n');
|
||||
|
|
@ -125,8 +117,8 @@ function selfTest() {
|
|||
r = run(fx); if (!r.problems.some(p => /does not exist/.test(p))) throw new Error('self-test: a check naming a missing script passed');
|
||||
writeFileSync(path.join(fx, GO), good);
|
||||
// the founder's name in the handoff, an em dash, a missing sentence
|
||||
writeFileSync(path.join(fx, PACK), goodPack.replace('1. sentence', '1. foundername says'));
|
||||
r = run(fx); if (!r.problems.some(p => /forbidden pattern .*foundername/i.test(p))) throw new Error('self-test: the founder\'s name in the handoff passed');
|
||||
writeFileSync(path.join(fx, PACK), goodPack.replace('1. sentence', '1. Foundername says'));
|
||||
r = run(fx); if (!r.problems.some(p => /forbidden pattern .*foundername/i.test(p))) throw new Error('self-test: the founder\'s name in the handoff passed (the encoded pattern did not match case-insensitively)');
|
||||
writeFileSync(path.join(fx, PACK), goodPack.replace('2. sentence', '2. a \u2014 dash'));
|
||||
r = run(fx); if (!r.problems.some(p => /em dash/.test(p))) throw new Error('self-test: an em dash in the handoff passed');
|
||||
writeFileSync(path.join(fx, PACK), goodPack.replace('(8.3 sentence 5)', ''));
|
||||
|
|
|
|||
|
|
@ -83,8 +83,6 @@ never_push_checks() {
|
|||
# the third never-push class (7 October 2026, 20:5x UK): a founder name on ANY branch, because every branch went to the public host's
|
||||
# mirror and a branch green-stamped before the check existed carried one onto master through the deferred merge
|
||||
run "no founder name, personal login, earlier business or personal address in any tracked text file (the pre-public scrub; self-test first, encoded list)" bash -c 'bash tools/ci/founder-strings-check.sh --self-test && bash tools/ci/founder-strings-check.sh'
|
||||
# rule 15 (7 October 2026): a release branch reads its own version in Cargo.toml, Cargo.lock and version.h from its first commit
|
||||
run "release-version: a release-0.3.N branch reads 0.3.N in Cargo.toml, Cargo.lock and version.h (self-test first)" bash -c 'bash tools/ci/release-version-check.sh --self-test && bash tools/ci/release-version-check.sh'
|
||||
}
|
||||
|
||||
tree_checks() {
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# Rule 15 (7 October 2026, after the 0.3.23 miss): the version bump is a release branch's first commit. release-0.3.23 opened
|
||||
# at 4cdcab31 and carried 0.3.22 in Cargo.toml, Cargo.lock and app/windows/version.h until 21:26 BST, so the app exes and the
|
||||
# window host crossed from its first closed tip read 0.3.22 and were void. On a push to release-0.3.N this check reads the
|
||||
# six version places (Cargo.toml, Cargo.lock, version.h, igneum-app.rc's four fields, Info.plist, the installer's AppVersion) against the branch name and goes red on a mismatch; a branch that is not release-* passes.
|
||||
#
|
||||
# tools/ci/release-version-check.sh [<branch>] # the current branch when omitted; exit 1 with the mismatch named
|
||||
# tools/ci/release-version-check.sh --self-test # a release-0.3.23 tree reading 0.3.22 fails on every place; a matching tree passes; a feature branch passes
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/../.."
|
||||
check() { # <branch> <cargo toml> <cargo lock> <version.h> [<igneum-app.rc> <Info.plist> <Igneum-Miner.iss>] -> prints each mismatch, exit 1 if any
|
||||
local branch="$1" toml="$2" lock="$3" vh="$4" rc="${5:-}" plist="${6:-}" iss="${7:-}" want bad=0
|
||||
case "$branch" in release-*) want="${branch#release-}" ;; *) echo "release-version: $branch is not a release branch; nothing to check"; return 0 ;; esac
|
||||
case "$want" in *.*.*) ;; *) echo "release-version: $branch is not a three-part version (rule 1)"; return 1 ;; esac
|
||||
local got_toml got_lock got_h got_rc
|
||||
got_toml=$(awk -F'"' '/^version = "/{print $2; exit}' "$toml")
|
||||
got_lock=$(awk '/^name = "igneum-app"$/{f=1;next} f&&/^version = /{gsub(/"/,"",$3); print $3; exit}' "$lock")
|
||||
got_h=$(awk -F'"' '/IGNEUM_HOST_VERSION_STR/{print $2; exit}' "$vh")
|
||||
got_rc=$(awk '/IGNEUM_HOST_VERSION_RC/{print $3; exit}' "$vh" | tr -d ' ')
|
||||
[ "$got_toml" = "$want" ] || { echo "release-version: $toml reads $got_toml, the branch is $branch"; bad=1; }
|
||||
[ "$got_lock" = "$want" ] || { echo "release-version: $lock reads $got_lock for igneum-app, the branch is $branch"; bad=1; }
|
||||
[ "$got_h" = "$want" ] || { echo "release-version: $vh IGNEUM_HOST_VERSION_STR reads $got_h, the branch is $branch"; bad=1; }
|
||||
[ "$got_rc" = "$(echo "$want" | tr . ,),0" ] || { echo "release-version: $vh IGNEUM_HOST_VERSION_RC reads $got_rc, want $(echo "$want" | tr . ,),0"; bad=1; }
|
||||
if [ -n "$rc" ]; then
|
||||
local n; n=$(grep -cE "^(FILEVERSION|PRODUCTVERSION) +$(echo "$want" | tr . ,),0\$|VALUE \"(FileVersion|ProductVersion)\", +\"$want\"" "$rc" || true)
|
||||
[ "$n" = 4 ] || { echo "release-version: $rc carries $n of 4 version fields at $want (build.rs refuses the cross otherwise)"; bad=1; }
|
||||
grep -qF "<string>$want</string>" "$plist" || { echo "release-version: $plist does not read $want"; bad=1; }
|
||||
grep -qF "#define AppVersion \"$want\"" "$iss" || { echo "release-version: $iss AppVersion does not read $want"; bad=1; }
|
||||
fi
|
||||
[ $bad = 0 ] && echo "release-version: $branch reads $want in Cargo.toml, Cargo.lock, version.h${rc:+, igneum-app.rc, Info.plist and the installer}"
|
||||
return $bad
|
||||
}
|
||||
if [ "${1:-}" = "--self-test" ]; then
|
||||
T=$(mktemp -d); trap 'rm -rf "$T"' EXIT
|
||||
printf '[package]\nname = "igneum-app"\nversion = "0.3.22"\n' > "$T/Cargo.toml"
|
||||
printf '[[package]]\nname = "igneum-app"\nversion = "0.3.22"\n' > "$T/Cargo.lock"
|
||||
printf '#define IGNEUM_HOST_VERSION_STR "0.3.22"\n#define IGNEUM_HOST_VERSION_RC 0,3,22,0\n' > "$T/version.h"
|
||||
out=$(check release-0.3.23 "$T/Cargo.toml" "$T/Cargo.lock" "$T/version.h" 2>&1 || true)
|
||||
[ "$(printf '%s\n' "$out" | grep -cF ' reads 0.3.22')" = 3 ] && printf '%s\n' "$out" | grep -q 'VERSION_RC reads 0,3,22,0' || { echo "self-test: the 0.3.23 miss was not caught on every place"; printf '%s\n' "$out"; exit 1; }
|
||||
sed -i.bak 's/0\.3\.22/0.3.23/g; s/0,3,22,0/0,3,23,0/' "$T/Cargo.toml" "$T/Cargo.lock" "$T/version.h"
|
||||
check release-0.3.23 "$T/Cargo.toml" "$T/Cargo.lock" "$T/version.h" >/dev/null || { echo "self-test: a matching tree failed"; exit 1; }
|
||||
check driver-check "$T/Cargo.toml" "$T/Cargo.lock" "$T/version.h" >/dev/null || { echo "self-test: a feature branch failed"; exit 1; }
|
||||
echo "self-test passed: the 0.3.23 shape fails on every place, a matching release tree passes, a feature branch passes"; exit 0
|
||||
fi
|
||||
BRANCH="${1:-$(git rev-parse --abbrev-ref HEAD)}"
|
||||
check "$BRANCH" app/igneum-app/Cargo.toml app/igneum-app/Cargo.lock app/windows/version.h app/igneum-app/resources/igneum-app.rc packaging/mac/app/Info.plist packaging/windows/Igneum-Miner.iss
|
||||
|
|
@ -49,18 +49,12 @@ const STATE_FILE_LIVE = process.env.IGNEUM_DISCORD_STATE || path.join(os.homedir
|
|||
// ---------- guards ----------
|
||||
// Forbidden in any post: the founder's name and logins, rented-box and build hosts, machine ids, internal paths, IP addresses,
|
||||
// a standalone 32-hex token (a sha256 is 64 hex and passes), any dl.igneum.network path outside /public/, any mention.
|
||||
// The founder's name, logins and the earlier businesses come from the PRIVATE list (never a tracked file in any encoding: a base64
|
||||
// copy in the tree was a disclosure on the public host, 7 October 2026, 21:3x UK): $IGNEUM_FOUNDER_STRINGS, else
|
||||
// ~/.config/igneum/founder-strings (the Mac), else /srv/discord-hooks/founder-strings (build-1, beside the webhook env). One row per
|
||||
// pattern: perl regex, a tab, a sample. Absent everywhere: no founder rows (the host that posts carries the file).
|
||||
export function founderListPath(env = process.env) {
|
||||
for (const f of [env.IGNEUM_FOUNDER_STRINGS, path.join(os.homedir(), '.config', 'igneum', 'founder-strings'), '/srv/discord-hooks/founder-strings']) if (f && fs.existsSync(f)) return f;
|
||||
return '';
|
||||
}
|
||||
export function founderPatterns(file = founderListPath()) {
|
||||
if (!file) return [];
|
||||
const rows = fs.readFileSync(file, 'utf8').split('\n').filter((l) => l.trim() && !l.startsWith('#')).map((l) => l.split('\t'));
|
||||
return rows.map(([re, sample], i) => ({ re: new RegExp(re, 'i'), sample, why: i < 3 ? "the founder's name or login" : i < 8 ? 'an earlier business' : i === 8 ? "the founder's address" : 'the login before its rename' }));
|
||||
// The founder's name, logins and the earlier businesses come from tools/ci/founder-strings.b64 (base64, so no tracked file
|
||||
// spells them; the first three decoded patterns are the founder, the rest the earlier businesses). fs is read once at load.
|
||||
const FOUNDER_LIST = path.join(HERE, '..', 'ci', 'founder-strings.b64');
|
||||
export function founderPatterns(file = FOUNDER_LIST) {
|
||||
const rows = Buffer.from(fs.readFileSync(file, 'utf8'), 'base64').toString('utf8').split('\n').filter((l) => l.trim() && !l.startsWith('#')).map((l) => l.split('\t'));
|
||||
return rows.map(([re, sample], i) => ({ re: new RegExp(re, 'i'), sample, why: i < 3 ? "the founder's name or login" : i < 8 ? 'an earlier business' : "the founder's address" }));
|
||||
}
|
||||
export const FORBIDDEN = [
|
||||
...founderPatterns().map(({ re, why }) => ({ re, why })),
|
||||
|
|
|
|||
|
|
@ -7,14 +7,11 @@ import fs from 'node:fs';
|
|||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
// the founder guard reads a private list; the test writes a FIXTURE list of made-up names and points the module at it before loading
|
||||
import { mkdtempSync as _mkd, writeFileSync as _wf } from 'node:fs'; import { tmpdir as _tmp } from 'node:os'; import { join as _join } from 'node:path';
|
||||
{ const d = _mkd(_join(_tmp(), 'founder-fixture-')); _wf(_join(d, 'list'), '\\bfoundername\\b\tFoundername\n\\bsurnamex\\b\tSurnamex\n\\bloginx\\b\tloginx\n\\bbiz1\\b\tbiz1\n\\bbiz2\\b\tbiz2\n\\bbiz3\\b\tbiz3\n\\bbiz4\\b\tbiz4\n\\bbiz5\\b\tbiz5\n\\bmail@x\\.y\\b\tmail@x.y\n\\boldlogin\\b\toldlogin\n'); process.env.IGNEUM_FOUNDER_STRINGS = _join(d, 'list'); }
|
||||
const {
|
||||
import {
|
||||
shapePulse, shapeDigest, shapeWeekly, shapeRelease, shapeIncidentOpen, shapeIncidentResolve, changedLinesFromPlan, plainLine,
|
||||
guardText, guardPayload, embed, embedLength, LIMITS, snapshot, devnet2Line, versionShare, watchPass, WATCH, WATCH_CONDITIONS,
|
||||
Poster, postWebhook, dueNow, ukStamp, londonParts, fmtHash, fmtDur, fmtDelta, fmtChangePct, renderPreview, ICON, EMBER,
|
||||
shapeFeed, feedMilestones, shapeMilestone, hashOriginLine, runFeed, FEED_MILESTONES, founderPatterns } = await import('./discord-hooks.mjs');
|
||||
shapeFeed, feedMilestones, shapeMilestone, hashOriginLine, runFeed, FEED_MILESTONES, founderPatterns } from './discord-hooks.mjs';
|
||||
|
||||
const HERE = path.dirname(fileURLToPath(import.meta.url));
|
||||
const fx = name => JSON.parse(fs.readFileSync(path.join(HERE, 'fixtures', 'discord', `${name}.json`), 'utf8'));
|
||||
|
|
|
|||
|
|
@ -27,9 +27,7 @@ set -euo pipefail
|
|||
export TZ=UTC
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
ROOT="$(cd "$HERE/../.." && pwd)"
|
||||
FOUNDER_LIST="${IGNEUM_FOUNDER_STRINGS:-$HOME/.config/igneum/founder-strings}" # the PRIVATE list (perl regex, tab, sample per row); never a tracked file in any encoding
|
||||
[ -s "$FOUNDER_LIST" ] || { echo "fresh-repo: no private founder list at $FOUNDER_LIST (the Mac holds it; the rewrite needs its rows)" >&2; exit 1; }
|
||||
STANDING_LOGIN="${IGNEUM_STANDING_LOGIN:-$(grep -vE '^#' "$FOUNDER_LIST" | sed -n '10p' | cut -f2)}" # row 10: the login's pre-rename spelling
|
||||
STANDING_LOGIN="${IGNEUM_STANDING_LOGIN:-$(base64 -d < "$(cd "$(dirname "$0")/../.." && pwd)/tools/ci/founder-strings.b64" | grep -vE '^#' | sed -n '10p' | cut -f2)}" # the login's pre-rename spelling, from the encoded list (no tracked file spells it)
|
||||
ORG="igneum-network"
|
||||
SOURCE="" WORK="" NEW_REPO="$ORG/igneum-core" NEW_LOGIN="" PUBLIC_CLAUDE="" CLEAN=0
|
||||
while [ $# -gt 0 ]; do
|
||||
|
|
@ -92,14 +90,14 @@ PERSONAL_EMAILS="$(printf '%s\n' "$PERSONAL_PAIRS" | awk -F'|' 'NF==2{print $2}'
|
|||
PERSONAL_NAMES="$(printf '%s\n' "$PERSONAL_PAIRS" | awk -F'|' 'NF==2 && $1 ~ / /{print $1}' | grep -v -E "^($STANDING_LOGIN|$TARGET_LOGIN)$" | sort -u || true)" # a name has a space; a login is not a name
|
||||
# the founder's first name, surname and second login from the encoded list (rows 1 to 3, sample column), so the rules never depend on
|
||||
# which commits a given mirror carries (7 Oct 2026: build-1's mirror holds none of the 40 personal-identity commits)
|
||||
LIST_ROWS="$(grep -vE '^#' "$FOUNDER_LIST")"
|
||||
LIST_ROWS="$(base64 -d < "$ROOT/tools/ci/founder-strings.b64" | grep -vE '^#')"
|
||||
LIST_FIRST="$(printf '%s\n' "$LIST_ROWS" | sed -n '1p' | cut -f2 | awk '{print $1}')"; LIST_LAST="$(printf '%s\n' "$LIST_ROWS" | sed -n '2p' | cut -f2)"; LIST_SECOND="$(printf '%s\n' "$LIST_ROWS" | sed -n '3p' | cut -f2)"
|
||||
FIRST_NAMES="$( { printf '%s\n' "$PERSONAL_NAMES" | awk 'NF>=2{print $1}'; printf '%s\n' "$LIST_FIRST"; } | grep . | sort -u)"
|
||||
LAST_NAMES="$( { printf '%s\n' "$PERSONAL_NAMES" | awk 'NF>=2{print $NF}'; printf '%s\n' "$LIST_LAST"; } | grep . | sort -u)"
|
||||
SECOND_LOGINS="$( { printf '%s\n' "$PERSONAL_EMAILS" | sed -nE 's/^[0-9]+\+([A-Za-z0-9-]+)@users\.noreply\.github\.com$/\1/p'; printf '%s\n' "$LIST_SECOND"; } | grep . | grep -v -E "^($STANDING_LOGIN|$TARGET_LOGIN)$" | sort -u || true)"
|
||||
# the other businesses named in the plan (brand names, not people), from the encoded list tools/ci/founder-strings.b64 (rows 4 to 8;
|
||||
# no tracked file spells them: the founder-strings check reads every tracked file)
|
||||
OTHER_BUSINESSES="$(grep -vE '^#' "$FOUNDER_LIST" | sed -n '4,8p' | cut -f1 | sed -E 's/\\b//g' | paste -sd'|' -)"
|
||||
OTHER_BUSINESSES="$(base64 -d < "$ROOT/tools/ci/founder-strings.b64" | grep -vE '^#' | sed -n '4,8p' | cut -f1 | sed -E 's/\\b//g' | paste -sd'|' -)"
|
||||
[ -n "$OTHER_BUSINESSES" ] || { echo "fresh-repo: the encoded founder list decoded to no business names" >&2; exit 1; }
|
||||
# the secrets: whichever of the four files exist, plus every dated copy the rotation left behind
|
||||
# (log-intake-key.old-<date>, dl-token.old-<date>: rotation phase 2 section 5 step 2 renames the .next files to the
|
||||
|
|
@ -159,12 +157,6 @@ while IFS= read -r login; do
|
|||
printf '\\b%s\\b\n' "$login" >> "$IDENT"
|
||||
done <<< "$SECOND_LOGINS"
|
||||
printf 'regex:(?i)\\b(%s)\\b==>[other-business]\n' "$OTHER_BUSINESSES" >> "$REPLACE"
|
||||
# the encoded forms: the base64 of every list regex (site/forbidden-strings.txt carried them as b64: lines until 21:3x UK on 7 October 2026)
|
||||
while IFS= read -r re; do
|
||||
[ -n "$re" ] || continue; b="$(printf '%s' "$re" | base64 | tr -d '\n')"
|
||||
printf 'literal:%s==>[encoded-pattern-removed]\n' "$b" >> "$REPLACE"
|
||||
printf '%s\n' "$b" | sed 's/[][\\.*^$?+(){}|/]/\\&/g' >> "$IDENT"
|
||||
done < <(printf '%s\n' "$LIST_ROWS" | cut -f1)
|
||||
printf '\\b(%s)\\b\n' "$OTHER_BUSINESSES" >> "$IDENT"
|
||||
say "rules: $(grep -c . "$REPLACE") replace lines, $(grep -c . "$MAILMAP") mailmap lines, $(grep -c . "$IDENT") identity patterns, $(grep -c . "$SECRETS") secret patterns (files under $RULES, removed at exit)"
|
||||
|
||||
|
|
@ -177,7 +169,7 @@ scan_blobs() {
|
|||
| perl -ne 'BEGIN { open(P, "<", shift) or die; @p = map { chomp; qr/$_/i } grep { /\S/ } <P>; $n = 0 } for my $p (@p) { if ($_ =~ $p) { $n++; last } } END { print "$n\n" }' "$1"
|
||||
}
|
||||
scan_meta() { git log --all --format='%an%n%ae%n%cn%n%ce%n%s%n%b' | perl -ne 'BEGIN { open(P, "<", shift) or die; @p = map { chomp; qr/$_/i } grep { /\S/ } <P>; $n = 0 } for my $p (@p) { if ($_ =~ $p) { $n++; last } } END { print "$n\n" }' "$1"; }
|
||||
DROPPED=(docs/review tools/ci/founder-strings.b64) # the encoded founder list (19:5x to 21:3x UK, 7 October 2026) leaves every commit # the ledger, its fixes file and the ledger page are published with the repository (decision of 5 October 2026, docs/fud-fixes.md section 5); the review folder stays internal
|
||||
DROPPED=(docs/review) # the ledger, its fixes file and the ledger page are published with the repository (decision of 5 October 2026, docs/fud-fixes.md section 5); the review folder stays internal
|
||||
counts() { # <label>
|
||||
local label="$1"
|
||||
say ""
|
||||
|
|
|
|||
Loading…
Reference in a new issue