9 fee blocks in the 785 blocks of the two fee-paying miners (1.15%, expected 1 in 100 templates), the miners' fee
counters equal the chain's count on both nodes, the control miner at --dev-fee 0 paid nothing.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
rollout-v2.sh stages the Linux igneumd (gateways from the Mac, private nodes from their gateway), rolls one node at a time with
difficulty_v2_activation_daa in every override file, checks the common chain and watches the height; results/2026-10-04/
rollout-v2*.log and v2/ (the hash-rate step under v2 and the v1 comparison). docs/plans/difficulty-v2-rollout-devnet.md: the
binaries and their sha256, the activation rule (N = DAA at publish + 10,800; baked at the cut as DAA + 14,400), the exact
restart lines for the observer node, the seed and Mac node 1, the OTA path for the two PCs through NODE_OVERRIDE_PARAMS in
packaged-config.sh (the engine side landed in 0dd587d), the rehearsal record. Bench-log entry.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
partition.sh adapted to private-network mode: the cut sits on the region's gateway (INPUT, OUTPUT and FORWARD
against the far gateways' public IPs over 26611 and the DNAT ports 27001:27099), since a per-node port-26611 rule
leaves the DNAT links up. It now records the locks per side at cut, during, at heal and after convergence, the
first lock after the heal from the journals, and the heal time as each minority node's first chain removal of 5+
blocks (the sink-count criterion is tip churn on a healthy network). hop.sh and partition.sh hold the Mac awake
with caffeinate; analyze.py gains a 10-s hop series (difficulty, block count, 1- and 2-min rates, threads) and an
overshoot table; collect.sh writes hop-series.tsv and hop.md and gzips the journals.
Results 2026-10-04: partition 1 (window still filling) reorg 431/496 on the minority, 2 on the majority, healed in
10 and 14 s; partition 2 (locks active): minority locked nothing during the cut, majority locked every interval at
66.8% to 84.5% of total, 0 conflicting locks over 107 indices, healed in 11 and 15 s, first lock after heal 13 s.
Hash-rate steps x1.42, x0.70, x0.75, x1.32: difficulty overshoots x1.67, x0.66, x0.53, x1.60, settle 751 s,
never in 900 s, 241 s, 646 s. Failures stated in summary.md: the Mac hibernated during the hop (phase 2 ran 94
min), the first partition could not see locks, the script's heal and first-lock figures were artefacts (fixed),
and another agent's v2 rollout restarted every node during the second heal.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Root cause from the uploads (bench-log entry): the app exported the pack while its node was in IBD inside the previous
epoch, the OpenCL worker started after the boundary with no next epoch within lead, so no prepare was ever sent and
every job was a seed mismatch; the CUDA worker on the same PC had swapped correctly. Both workers now print
need <epoch> <day> before the error; the devnet-v4 miner (3bfe346f) prepares the current pair on a need line or three
mismatches, exits 42 for a worker without prepare support, and restarts a ready worker that completes no job for
60 s with jobs queued. Package rebuilt with the guarded miner (ship build on dc749905), payload inputs published.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Live devnet v4: a second RTX 5090 joining 7 minutes into an epoch left the whole-epoch reference lane polluted for the hour; the short lane read 11 to 25% above it and the 25% trigger flipped between the two for 40 minutes (102M to 164M, 54 to 81 blocks a minute). Record and hash-rate truth under sim/difficulty/records/. sim.py gains a DAG model (miners on nodes with igneum-miner's template staleness, GHOSTDAG, the rule as the node runs it) and --live replay: std of log difficulty 0.115 against the record's 0.134, 4.3 peaks of 1.31x against 4 of 1.37x. The brief's candidates (short lane 240/360, ease clamp 3%, clamp once per DAA second, hysteresis, median of three) leave 0.09 to 0.13; capping the reference lane at the newest 600 blocks of the epoch gives 0.026 with no flips. Rule v2 = that cap, epoch lane only, behind difficulty_v2_activation_daa (devnet-v4 fork). Attack suite and synthetic set before and after, 3-node test network of the switch (testnet_v2.py), analysis document, spec 2.3, bench-log entry, ledger M24, fast-time file carries the new field.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
infra/fast-time/override-60x.json is the devnet with every clock-like consensus parameter divided by 60 and every
block count unchanged (finality window, ban and min_daa 120 DAA; merge depth 60; Kaspa finality depth 720; pruning
depth at the anticone bound 13,838; coinbase maturity 2; the hourly program epoch 60 blocks with a 10-block lead;
the dataset day 24 minutes). The epoch length, lead and day are consensus parameters of the node since devnet-v4
a5ef8b07, carried by the override file. README lists each field, why it scales or not, the flags and the numbers.
Measured (simnet.mjs, three devnet-v4 nodes, three vmine voters at 1 block/s, one real-hash CPU miner): next
epoch seed in the template at 56.1 s, program swap at 65.1 s wall (DAA 60), first finality lock at 185.5 s wall
(checkpoint 5, DAA 149). Both harnesses take --fast-time: finality-attacks s3 PASS in 113 s wall with 16 locks
per node (the devnet rule needs 20 min of warm-up at 6 blocks/s before any lock); harness s3 partition and heal
43 s wall for three cuts against 983 s for four on the devnet profile with the same binary. Bench-log entry.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
igneum-common.ps1 uses igneum-worker-cuda.exe (with nvrtc64_*_0.dll next to it) and igneum-worker-opencl.exe when they
are in the folder, passes the exported pack with --pack, and only surveys the toolchain (Find-Toolchain) when a worker
is missing or FORCE_BUILD=1; the dashboard and the status block name the path per card; a prebuilt worker that is not
ready after 150 s falls back to the build path once when a toolchain exists; 90 s of seed mismatch errors re-export
the pack and restart the vendor; WORKER_ARCH overrides the NVRTC target. make-package.sh ships the two exes, the two
NVRTC DLLs, the licence texts, THIRD-PARTY.md and TEST.md (what the first RTX 5090 run should print and what to send
back). README.txt, the bats, proto-cuda/README.md (nvrtc/ section), WINDOWS-MINER.md and the bench log updated with
what the Mac measured.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A lock needs two thirds of all 30-day weight signing; finality pauses
whenever less than two thirds is connected and signing, the chain runs
on proof of work meanwhile and the node reports it. Spec 3.3, 3.3.1,
3.7, 3.9, 3.10 Q3 row, 3.11 rewritten with the new arithmetic (safety
one third in every view, liveness two thirds connected, the per-view
window bound stated as 3.7 item 9); O-3.15 decided, O-3.16 closed,
O-3.18 and O-3.19 narrowed. Simulator: --floor, the +local partition
mode, scenario L; A to L re-run at the 2/3 floor over five seeds with
the 0.85 deltas in results_v2.md. Litepaper finality sentences and the
'does not claim' item. Ledger F2, F9, F16, F18 restated, F21 added
(the window bound and the post-heal finality fork from the devnet).
Bench-log: node build and tests, simulator deltas, three-node six-voter
runs of 6A, 6B and 6A with a long heal on ports 29200 and up.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
igneum-pow 0.2.0: generator v2 draws exactly 16 load slots from instructions 1..63, a
load's source from the registers written earlier and not read by a load since, the other
48 ops from the ten non-load weights; accept.rs is spec 01 section 1.4.6 (static: no
stale load source, every register injected; dynamic: 64 units on the seed-keyed
closed-form dataset, no constant bit, no lane-constant site, under 164 saturated, bias
within 136 of 1024, distinct addresses above 245,760); a rejected candidate is replaced
by the next attempt of the seed (seed || k_le32), 32 a consensus fault. Packs carry the
generator version, attempt and program id. Version 1 kept as generate_v1 for the census.
Packs: igneum-genesis, igneum-hourly, igneum-genesis-mh regenerated by igneum-pow export;
new igneum-devnet-v4-epoch0 (devnet genesis hash, day bytes 20730). Checks: Rust 39 of
39 tests; Metal natively via the Swift port (export cross-check 3 of 3 warps, identical
programs and vectors on five seeds incl. three with attempt 1, fuzz 2,000 of 2,000);
CUDA emu 4 of 4 packs; OpenCL emu 2 packs x 2 configurations; Apple OpenCL 4 of 4 packs
at 27.9 Mhash/s. Census 20,000: 5.225 percent rejected, accepted distinct mean 127.887.
Spec 01 0.2 (1.4.2, 1.4.3, 1.4.6, 1.11, 1.15, 1.16, 1.17), igneum-pow README, the CUDA,
OpenCL and Metal test notes, bench-log entry, ledger M5 and M6 Fixed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Spec 2.3: rule 1 measures every chain step on a sanitised clock stored per header
(c(b) = max(c(p) + clamp(t(b) - c(p), -20 T, +20 T), t(b) - 60 T), step min(c(b) - c(p),
20 T)); rule 4 bounds the output to [2^128, MAX_DIFFICULTY_TARGET]; the timestamp rules
are Igneum's own, 10 s ahead of the clock and 10 s behind the selected parent beside the
unchanged past-median rule; new parameter rows, the bounds paragraph rewritten (the old
"next honest block cancels it" was the attack), the attack and test-network results added.
sim/difficulty/sim.py: class Igneum carries the same clock, lag bound and floor, so the
rule as simulated is the rule as coded (attacks.py's igneum-san is now identical to it).
docs/analysis/difficulty-2026-10-03.md section 11: the attack, the three parts, before and
after tables (simulator seeds 7 to 9, base-profile regression within 10% on the 3-seed
means, pool hopping unchanged, the two 15-minute 3-node forger runs), unit tests, limits.
docs/bench-log.md: the 4 October entry. docs/fud-ledger.md: M23, status Fixed.
Node side: vendor/igneum-node branch difficulty, commit 52eacad9.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- spec 3.10: C5/3.8 (min_daa = weight window, window-filling report), Q4 (drawn aggregator at
once, fallback for anyone), S1 (draw by weight), 3.9 (finality_reason) rows for fin-fixes da1eb889
- fork-divergence: four rows for the fin-fixes files and the merge note against the difficulty
branch (hot swap is already in master)
- bench-log: unit tests and the scenario 2 and 5 re-runs before (master) and after (fin-fixes)
- fud-ledger: F17 and F1 status lines
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simulator harness over sim/difficulty/sim.py with multi-miner attribution and in-rule timestamp forging, a 3-node CPU test network (ports 27700+), results and bench-log entry. Timestamp stretching inside Kaspa's rules drops the Igneum block rate 34 to 88% (the per-step clamp cancels forged and honest pairs to zero time); proposed 10 s timestamp bounds plus a sanitised running clock in the chain steps (+0.7% to +1.1% drift at 50% in the simulator). Block flood underflows the 192-bit work after 4,142 blocks; a 2^128 target floor proposed. Rule not changed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/finality-attacks: run.mjs drives a private igneum-devnet-800 network (ports 27800+,
/tmp/igneum-fin-attacks, skip_proof_of_work) with the test-only hostile flags of igneum-miner
(vmine, --equivocate, --sybil, --drop-votes, --pulse, fin-rpc-attack; worktree fin-attacks on
master c6d47547..2a00ff55). Seven scenarios in priority order 3,2,1,6,4,8,5 with a spec 03
criterion and a measured result each; README carries the catalogue, what needs a finality-aware
p2p probe, and a proposed diff for every FAIL.
Results (six voters): S3 dishonest aggregators PASS (35/35/35 locks, 0 conflicts, 1,018 ms);
S2 Sybil dust: weights PASS, aggregator sortition FAIL (per key, ledger F17); S1 equivocation
PASS (2/2/2 stripped, 0 conflicts); S6A 3/3 partition FAIL (floor is time-bounded, one side
crossed 56.7% at 84 s of a 90 s split, T* = 2F/13R, 9.2 days for a 50/50 split at mainnet
scale); S6B 4/2 PASS; S4 vote-dropping producer PASS (0 ms added); S8 malformed votes over
RPC PASS (9 cases, no crash); S5 pulse: no retarget amplification (ratio 0.999) PASS,
lock-alone FAIL (a 20 s burst locked checkpoints 1 to 10 alone on a young window, ledger F1,
spec 3.8 not implemented). S7 eclipse not run.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
No per-job growth in any worker or in the miner's memory. The STATUS rates are cumulative averages
(a fast first interval decays by construction), and the miner's Seeder walks the selected chain from
the sink to the epoch start on every memo miss (one getBlock per block, up to 3,600), a gap between
jobs that grew 0.10 s to 0.33 s across epoch 2 on the PC and reset at the epoch boundary while the
difficulty held. Reproduced on the Metal worker (churn on, off, on). One versus eight workers at two
fixed difficulties: 4% and 1% constant cost, no decay. Fix as a unified diff, not applied.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
sim/economy/sim.py: 1,000 operators choosing MINE, PROVE, HYBRID or OFF per card class with their own clients; sortition by weight with the 10-s window then open claiming, external jobs with the 90/10 split, backlog rule, difficulty clamps, GBM price. Scenarios a to f, 5 seeds: no backlog, no window miss, hash floor 0.74 of pre-event. Traffic sensitivity finds the shortage oscillation only above the proving fleet's capacity (100 to 300 shards per block); at 100 the sortition window (10 s to 20 s) is the lever that removes it. docs/analysis/economy-2026-10-04.md holds the model, assumptions, results, worst case and the proposal (window = p90 shard time plus a swap, 25 s at today's targets; B_p tied to the live fleet), not applied.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adversarial robustness and conformance tests of the execution layer against a
throwaway 3-node simnet on ports 27600+. Six scenarios, each a runnable command
with a design-derived pass criterion and a measured result: malformed/boundary
txs, nonce games across parallel blocks, RPC fuzz, pgas exhaustion, reorgs under
execution, and developer-registry abuse. 98 checks, 0 failures, 0 node panics.
Two findings filed in the bench-log entry: the mempool admits txs with gas_limit
above B_e (low), and an over-pgas-budget tx is executed natively in full before
being skipped for no fee (medium, griefing).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/harness runs the standard consensus-attack catalogue against a private
test network of our own igneumd nodes (127.0.0.1 ports 27200+, /tmp/igneum-harness,
never the live devnet or the PC node), with a pass criterion per scenario from the
spec and a measured result each. Built on the node fork's own crates
(igneum-harness-sim on kaspa_utils::sim as simpa does; igneum-p2p-probe for the
wire). Scenarios: 1 withholding, 2 timestamp edges and drift, 3 partition and heal,
4 eclipse, 5 malformed and boundary inputs on every p2p and RPC surface, 6 resource
exhaustion, 7 fast-miner flood. Finality and difficulty-controller scenarios are
stubs with their criteria written.
bench-log: one dated entry, a row per scenario (criterion, measured, pass or fail).
First run: 19 of 20 measured rows pass. Findings recorded in the entry: scenario 5
reproduces ledger M15 on HEAD (bogus past-day or DAA headers build a 256 MiB cache
before rejection; the r3-fixes branch removes it); scenario 1 at 45% hash with
burst withholding shows a selfish-mining blue-share gain (50.7% of blues), the one
failing row.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs/design/execution-layer.md section 10: what the execution-layer branch implements
(D1 to D10, RPC, differential), the devnet rules fixed there, what is missing, the merge
plan with the finality branch. docs/bench-log.md: the 3-node simnet run with numbers.
tools/evm-smoke: viem 2.57 smoke test (fund, 50 transfers, duplicates in parallel blocks,
contract deploy and call, state roots across nodes, export for igneum-exec-diff) and the
solc build of DeveloperRegistry and the Counter test contract.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- docs/fork-divergence.md: "Finality v2" table (every file, risk, merge note), decisions
- docs/spec/03-finality.md: section 3.10 implementation notes, clause by clause
- docs/bench-log.md: test-network results (72 of 72 steady locks, median 0.80 s; equivocation
strip; partition: 0 locks at 39.6% of total with the floor binding, heal in 30 s), follower
- tools/observer: live_checkpoints table, FinalityLock subscription, "checkpoint N locked" events
- site: /api/live adds checkpoints and locked/final flags; /live draws the lock ring and final line
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
fork-divergence.md: a section for branch r3-fixes (the PoW-before-validation
reorder, the cache-build cap and the per-peer guard), the merge-overlap note for
the finality branch, and the updated "PoW before or after GHOSTDAG" and "Day
seed" open decisions. bench-log.md: the before-and-after attack numbers (50
bogus headers build 50 caches in 10.6 s before, 0 and all rejected in 14 ms
after), one cache builds in about 0.2 s, and the M16 Mac inline-dataset note.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
proto-cuda/windows-node/: START-NODE.bat and start-node.ps1 (igneumd
--devnet with --addpeer to the Mac, status line every 30 s through
igneum-miner watch, keep-awake, random-delay restart, Ctrl+C),
BUILD-NODE.bat and build-node.ps1 (builds on the PC from the src.zip
snapshot; winget for Rustup, LLVM and protoc; MSVC default toolset),
ALLOW-FIREWALL.bat and allow-firewall.ps1, README.txt, cross-build.sh
(the mingw-w64 recipe that built igneumd.exe in 8 min 25 s; the exe
ships with the three mingw runtime DLLs) and make-package.sh.
WINDOWS-MINER.md gains "Run your own node"; bench-log records the
cross-compile and the two-peer sync test on the Mac (ports 27000 and
27010, live node untouched). The mining launcher's NODE_HOST=auto
edit stays uncommitted for the agent that owns start-mining.ps1.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
proto-metal --serve compiles igneum_hash_bound at runtime and mines jobs from stdin (init words in buffer 3, program
and dataset cached per seed); proto-cuda and proto-opencl host serve modes from the pack's kernel_bound.cu / .cl with a
seed guard; --vendor device filter for OpenCL. windows-miner/: START-MINING.bat + start-mining.ps1 (GPU and tool
detection, pack export, cached builds, MINERS identities per vendor, status every 30 s, uploads every 60 s, rebuild on
seed change, Ctrl+C summary), README.txt, make-package.sh (igneum-mine-test.zip with a cross-compiled miner).
docs: fork-divergence devnet v1, bench-log entry with the CPU, Metal and overnight numbers.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs/fork-divergence.md: every rusty-kaspa file the fork changed (file, what,
why, risk, upstream-merge note), the decisions left open (8 vs 18 decimals,
temporary epoch seed, day seed, lane-to-target mapping, pool payee, depth
bounds, PoW after GHOSTDAG) and the per-second subsidy table.
docs/bench-log.md: 3 October 2026 entry for the 3-node igneum-devnet run at
0.84 blocks/s with the 80/20 coinbase and vote_key_hash verified on all nodes.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Exporter writes kernel.cl next to kernel.cu (same instruction list; memory-hard core emitted in a third, OpenCL C
dialect with the same literals as memhard.h). Pack headers are now C99-safe so a plain C host can include them.
proto-opencl/host.c: C99 + OpenCL 1.2 API, device list, runtime build, cache fill and FNV check, dataset build and
self-test, 3 vector warps standalone and in batch, bench and sweep as host.cu, whole-batch fingerprint. The 32-lane
exchange is sub_group_shuffle_xor only when the queried sub-group size for a 32-item work-group is exactly 32;
otherwise a local-memory exchange with one barrier per exchange, so wave64 hardware cannot change the hash
(WAVEFRONT.md). build.sh (macOS, Linux), build.bat (MSVC), README with the exact AMD-rig commands.
Proven without AMD silicon: Apple OpenCL 1.2 on the M5 Max 96/96 on all three packs (45.0 Mhash/s at 1 GiB, Apple
number, not AMD); pocl 7.2 CPU device 96/96 on both exchange paths including the real sub_group_shuffle_xor text;
CPU emulator 7 configurations incl. 64-wide sub-groups, identical fingerprint f99fb375b3abeaf5 everywhere.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Class group (1024-bit prime discriminant from the checkpoint hash, chiavdf
construction, NUDUPL/NUCOMP/Lehmer xgcd ported from vendor/chiavdf) and an
RSA-2048 trusted-setup stand-in for timing. eval, block prover, verify,
epoch_seed/verify_epoch_seed, grinding model, README with measurements and
the parameter recommendation, bench-log entry.
M5 Max: class 163k sq/s (T 98 M for 10 min, 588 M for 1 h), verify 4.5 ms,
proof 516 bytes; full 10-min runs for both groups; grinding gain for a 30%
miner +3.62 blocks/epoch with no delay, 0 with it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
proto-metal: default dataset is now the memory-hard construction (MEMHARD.md), --closed-form keeps the original.
Cache fill 2 ms GPU / 185 ms one CPU core; dataset build 20.6 ms; GPU cache == CPU cache on all 2^26 words.
Shortcut ratio: inline kernel 111x faster than honest (closed form) to 4.8x slower (memory-hard), 1 GiB.
CPU verify 0.63 to 0.80 ms per warp at 104 loads, 1.21 ms at 144 loads (4,608 items): 10 ms gate met.
Levers --load-weight and --wide-frac implemented and measured, both off; default generator unchanged.
Fuzz 200/200, edge, determinism, memcheck, stats re-run on the new dataset, all PASS.
proto-cuda: host.cu handles both dataset modes; new pack igneum-genesis-mh with memhard.h; clang emulation PASS
including the three-way cache check. Old packs unchanged; closed-form export is byte-identical to them.
docs/bench-log.md: dated summary.
Note: a concurrent session running git commit -a swept earlier states of these files into its site commits
(7b28d5e through d6539fa); this commit carries the remainder.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>