igneum/docs/plans/release-0.3.10.md
2026-10-05 18:38:10 +00:00

32 KiB

Igneum Miner 0.3.10: the certificate-driven reorg, transaction gossip and the PC-built Windows node, 5 October 2026

Release engineer, from 16:39 UTC. Worktree /Users/joshm/Projects/igneum-wt-ship0310, branch release-0.3.10 from master after the 0.3.9 merge. Fork worktree vendor/igneum-node-0310, branch release-0.3.10 from a24ab01a (the 0.3.9 fork tip). Every Mac build through /Users/joshm/Projects/igneum/tools/lock/with-lock.sh build at nice -n 19 with -j 4; every PC job through the main checkout's tools/build-job.mjs and packaging/ota/publish-jobs.sh (the signed envelope). Times are UTC. release-0.3.9.md and release-0.3.8.md are the template; release-0.3.6.md section 10 for the Windows acceptance. The rollout waited for 0.3.9's (shipped about 17:00Z, fee switch published about 17:50Z): nothing of 0.3.10 moved on the network before every node's digest was ab8847da...

1. What 0.3.10 carries

Change Where Fork commit
A. The windows-gnu node links the C++ runtime statically (database/build.rs, rocks-probe), so the PC-built Windows node runs (release-0.3.6 plan section 10) fork housekeeping 4fb32865 merged 2f88a82f
B. TestConsensus sets the unbounded PoW cache build queue, so the five node suites pass in parallel on PC 2 fork housekeeping 7003055b merged 2f88a82f
C. The certificate-driven reorg (ledger C4, measured in FUD round 6, 75c6658: a certificate over an off-chain block stayed pending and the heavier side locked alone): a verified certificate over a block off the node's selected chain now locks it there and moves the virtual to the heaviest tip through it (spec 3.5 F1 and F2); the block relay takes a lighter block a pending certificate names. A consensus-behaviour change with NO digest change: it converges when every node is new (the c4 agent's rollout note, section 10) fork c4-fix e18f1e0e (its message records PC 2 job build-20261005-180827: kaspa-consensus 97 passed, kaspa-consensus-core 101 passed, three new tests), main c4-fix 68f14b9 (spec 3.5, 3.2, 3.10, 3.11.7, ledger, bench-log, c4.mjs v2 mode; the signer-pipe-check CI script and per-job build-inputs zip names) fork: merged 21d4c73c; main: 0cbaf3a and the tip merge

Changelog line for C (the coordinator's words): "A node that comes back from a partition now follows the certified checkpoints, even when its own chain is heavier." | D. EVM transaction relay between nodes: three p2p messages after Kaspa's transaction inv/request/answer, PROTOCOL_VERSION 13 to 14 (13 peers still connect: a v14 node never sends the new messages to an older peer), the mempool caps and faults, the block-added hold instead of the 4-s hand-out cooldown; the digest is unchanged, so no activation height and no fresh chain | fork tx-gossip e242acd0 (its message records PC 2: igneum-exec 15 of 15, kaspa-p2p-flows 33 of 33), main tx-gossip 0166e94 (the relay-net harness tools/txgen/relay-net.mjs, the design note); acceptance here: node tools/txgen/relay-net.mjs --rate 2 --duration 120 --wallets 16 --fund 2 on the 0.3.10 Mac node, expected 240 of 240 included | fork: merged 21babaa7; main: (pending the worktree) |

Changelog line for D (the coordinator's words): "Transactions now travel between nodes; a miner on an older node still carries only what was sent to it directly." | E. GPU hot-plug (coordinator, 17:5xZ): cards re-enumerated every 60 s and on WM_DEVICECHANGE, new cards mine by default, Code 43 cards marked unusable, vanished cards dropped without shifting slots, the Ryzen gfx1036 iGPU classified integrated and off by default, a cards: line the relay parses (machines API gpus/hotplug). 14 files: app/igneum-app/src/{detect,engine,hotplug,main,state}.rs, ui/{app.css,app.js,notices.test.mjs}, app/windows/host.cpp, relay/{api/console.mjs,lib/parse.mjs,test/parse.test.mjs,ui.html}, tools/console.mjs; no proving, packaging or workflow file. Its Windows-only paths (detect::adapters, host.cpp WM_DEVICECHANGE) were never compiled on the Mac: PC 1's Windows app build and the GitHub runner's host build are their first compile and are read for errors | main gpu-hotplug 4517004 (igneum-wt-hotplug, on master 22ffc02); its tests on the branch: igneum-app 91 pass, notices, update-card and parse node tests pass | merged after C and D | | F. Elevated jobs that never started (coordinator, 18:0xZ): an elevated job whose UAC prompt is refused, cancelled or times out fails with exit 251 and the summary "did not start: the administrator prompt was refused, cancelled or timed out"; before, Start-Process threw, $p stayed null and exit $p.ExitCode exited 0, so the PC 1 driver job at 17:58Z read as done. One file, app/igneum-app/src/jobrun.rs, plus its unit test | main elevated-exit 9816d58 (igneum-wt-elevated) | merged after E | | The app engine otherwise | unchanged except the version (0.3.10 in the six files); the signed jobs envelope client is master's (housekeeping C, 318a2de) | |

Changelog line for F (the coordinator's words): "A remote job that needs administrator rights now reports when the prompt was not accepted instead of claiming success."

Changelog line for E (the coordinator's words): "New cards are picked up while the miner runs; a card that goes away is released; integrated GPUs stay off unless you switch them on. | The pinned guest | UNCHANGED unless C or D touches proving/igneum-prove/core or elf/ (checked at the merge: section 2) | |

2. The branch

Commit What
9268b64 origin/master at the worktree's creation (18:00Z: the 0.3.9 merge, fast-forwarded)
2e943a8 Merge tx-gossip (0166e94): the relay design note, rows 463 and 9, the 3-node relay harness and its evidence; no conflict
824059b Igneum Miner 0.3.10: the six version files (node tools/ship-app.mjs --check: 0.3.10 in all 6)
9997ef1 packaging/mac/packaged-config.sh: the four-field override object in the packaged line, the self-test fix (section 3)
0cbaf3a Merge c4-fix (3072919, 18:20Z). One conflict, docs/bench-log.md: both entries kept (the fee-table entry, then the C4 entry). Brings tools/ci/signer-pipe-check.sh (igneum-ota-sign ... | head -1 under pipefail panicked the signer with SIGPIPE on a loaded Mac and killed a publish; now sed -n 1p in publish-jobs.sh, publish-manifest.sh, push-inputs.sh) and one build-inputs-<time>-<pid>.zip per build job (build-job.mjs, push-build-inputs.sh --name: with the shared name a job pinned another agent's sources three times tonight). From here every PC job and publish runs from THIS worktree's tools: they carry master's signed envelope (housekeeping C) and these two fixes, which the main checkout lacks until this branch merges
4d10c20 Merge gpu-hotplug at its tip at merge time, 4d122e1 (the agent's second commit: one row per physical GPU across OpenCL platforms, Windows names on the rows, index-free card keys, the OpenCL worker's --list prints the PCI address in proto-opencl/host.c); no conflict, 15 files
5520fb1 Merge elevated-exit (9816d58); no conflict
5520fb1 the fast checks again: identity 0 hits over 212 files, copied-sources, pinned-guests, signer-pipe-check ok, no-conflict-markers ok, workflow shell 0 findings, --check 0.3.10 in all 6, relay tests 16 pass (hotplug's parse test added), UI tests 12 pass; 18:21Z

A vendor symlink to the main checkout's vendor/ (untracked) makes the relative node paths resolve, as in the earlier cuts. The app and prover target dirs were cloned by APFS from the 0.3.9 worktree (18:01Z).

The fork branch release-0.3.10 in vendor/igneum-node-0310, from a24ab01a: 2f88a82f (housekeeping 4fb32865), 21babaa7 (tx-gossip e242acd0), 21d4c73c (c4-fix e18f1e0e: finality.rs, blockrelay/flow.rs and five small files, 601 insertions), all three without conflict. Neither c4-fix nor tx-gossip touches a params file, proving/igneum-prove/core or elf/: the pinned guest and the prover rollout are untouched by 0.3.10.

3. Tests and checks, with the command

Tip Command Result
fork 2f88a82f (a24ab01a + housekeeping) PC 2 job build-20261005-164604 (node tools/build-job.mjs run --node vendor/igneum-node-0310 --target 1ccfe586 --targets linux --node-tests "kaspa-consensus kaspa-consensus-core igneum-exec kaspa-pow igneum-miner" --no-app) started 16:46Z, done 16:48:43Z (129 s): Linux node built, RESULT test node [the five packages] exit 0 39 s: the parallel five-package run is green on the housekeeping tree (housekeeping B); the short report carries the per-package exit, not the per-test names
fork 2f88a82f PC 1 job build-20261005-164512 (--targets linux,windows --no-tests --no-app --no-place) started 16:45Z, done 16:50:26Z (292 s), every stage ok, 7 files, all sha256 and PE checks ok: igneumd.exe 37d0b1045043bc86... (50,889,728), igneum-miner.exe bc8cb3a12111e7bb... (10,725,888), Linux igneumd d0331c109babe77e... (48,733,736, glibc 2.39: HiveOS, not the seed). strings igneumd.exe: msvcrt.dll is the only C runtime named; no libstdc++-6, libgcc_s_seh-1 or libwinpthread-1 (housekeeping A)
fork 2f88a82f, PC 1 exe run job run-0310-accept-hk (the housekeeping agent's acceptance script: rocks-probe, igneumd 60 s on a scratch appdir with no mingw DLL beside it, igneum-miner.exe key-hash probe, Application event 1000 check), published 16:51:01Z (the apps woken) ran 16:57:15 to 16:58:21Z (66 s), exit 0: rocks-probe exit 0 (21 files in its db), RESULT run node60: still running after 60 s (alive for the whole wait); killing it with 14 files written under the scratch appdir, igneum-miner.exe key-hash probe exit 0, RESULT event 1000: none; the exe's imports on the PC (objdump): KERNEL32, advapi32, bcrypt, iphlpapi, msvcrt, ntdll, ole32, ws2_32 and the api-ms-win-core set, no mingw DLL. The one warning, cannot bind the eth_ JSON-RPC server on 127.0.0.1:26790, is PC 1's live node holding the port, as in the housekeeping run. So the PC-built Windows node is the 0.3.10 Windows node (no Mac cross-build needed)
fork 2f88a82f, Mac arm64 CARGO_TARGET_DIR=vendor/igneum-node/target-0310 cargo build --release -j 4 -p kaspad -p igneum-miner --features kaspad/igneum-pow from vendor/igneum-node-0310 under the lock (target dir cloned by APFS from target-036; a new worktree path rebuilds every crate) 16:44:52 to 16:57:28Z (12 min 36 s): igneumd 2a7df6245ffe047a... (40,968,368, 2f88a82f in its strings), igneum-miner 322472ae95a316d1... (8,514,928)
fork 2f88a82f, Mac arm64 the digest check: that igneumd on a scratch node (ports 60975/60976, 22 s, 16:57:58Z) with {"difficulty_v2_activation_daa":33000,"proving_v0_activation_daa":84100,"fees_v1_activation_daa":210000} Calibrated v1 fees from the override file: ... from DAA score 210000, digest ab8847da538dead1dc10e046dfaadab3c1c35928e3748810c4e050d4a886087a, igneumd/2.1.0-2f88a82f: housekeeping moves no parameter

| fork 2f88a82f, Linux x86-64 for the seed | NODE_SRC=vendor/igneum-node-0310 TARGET_DIR=vendor/igneum-node/target-0310-linux infra/cross/build-linux.sh (zig, glibc 2.36 target) under the lock | queued 16:57Z behind two other agents' builds, built 17:23 to 17:35:49Z (754 s, 564 crates), and its output was WRONG: igneumd 7e26e374... BYTE-IDENTICAL to the 0.3.9 build of a24ab01a, embedding a24ab01a. Cause (found at the second run, 18:25Z): build-linux.sh does cd "$NODE_SRC" and runs cargo with CARGO_TARGET_DIR="$TARGET_DIR", so a RELATIVE target dir resolved inside the node worktree (vendor/igneum-node-0310/vendor/igneum-node/target-0310-linux, the untracked vendor/ that appeared there), while the copy step read the repository-relative clone that still held the a24ab01a binary. Every crate had compiled, into the wrong place. Fixed on this branch (e0a5fd1: the three paths made absolute before the cd) and the build rerun with an absolute target (section 5). My first reading of it, a stale kaspa-build-info output in the cloned target, was wrong and is withdrawn | | fork 21babaa7 (2f88a82f + tx-gossip e242acd0), Mac arm64 | the same cargo build, incremental on target-0310 | 17:49:52 to 17:52:00Z (2 min 08 s): igneumd 5d7f1b576029b462... (41,118,944, 21babaa7 in its strings) | | fork 21babaa7, Mac arm64 | the digest check as above (ports 60975/60976, 22 s, 17:52:01Z) | Calibrated v1 fees ... from DAA score 210000, digest ab8847da538dead1dc10e046dfaadab3c1c35928e3748810c4e050d4a886087a, igneumd/2.1.0-21babaa7: tx-gossip moves no parameter (its commit message says the protocol version is not in the digest; measured here) | | fork 21babaa7 | PC 2 job build-20261005-175022 (--node-tests "kaspa-consensus kaspa-consensus-core igneum-exec kaspa-pow igneum-miner kaspa-p2p-flows" --no-app) | started 17:50Z, done 17:53:10Z (145 s): RESULT test node [the six packages] exit 0 53 s (kaspa-p2p-flows added: tx-gossip's relay tests live there and in igneum-exec) | | 2e943a8 + bump | tools/ci/identity-check.sh (0 hits over 212 files), copied-sources-check.sh, pinned-guests-check.sh (elf/ matches its manifest), node tools/ci/check-workflow-shell.mjs (12 run blocks, 25 .ps1, 0 findings), the relay tests (15 pass), the UI tests (10 pass) | all green, 18:00Z | | fork 21babaa7, Mac arm64 | the digest check with the FOUR-field object {"difficulty_v2_activation_daa":33000,"proving_v0_activation_daa":84100,"fees_v1_activation_daa":210000,"finality_v3_activation_daa":135200} (N3 = 135,200 from the live 0.3.9 manifest republished 17:59:14Z, deadline note "finality v3"; the project lead: "deploy N3 now", the 0.3.9 agent publishing it) | 18:01:59Z, 22 s: Finality rule v3 from the override file: active from checkpoint DAA score 135200, Calibrated v1 fees ... 210000, digest 1f4b44255fcd2ea8f75664ed47200f409186ddd2292960c9e2cf95bbbdc11505, igneumd/2.1.0-21babaa7. Equal to the live hand nodes' lines at 18:02Z (observer-v4.out, node1.out: digest 1f4b4425..., igneumd/2.1.0-a24ab01a, the four-field /tmp/igneum-devnet/override-v3.json): the 0.3.9 agent's N3 rollout had reached them. This is the digest every node must show; the final 0.3.10 node is read again against it | | 9997ef1 | packaging/mac/packaged-config.sh: NODE_OVERRIDE_PARAMS = that four-field object (it was empty on master; the manifest's consensus.override is what the apps write, the packaged line covers a first start before any manifest). Its self-test's "json has no override line" check read the file's shipped default and failed on a non-empty line (master's empty line passed it), so that check now passes NODE_OVERRIDE_PARAMS='' itself, as the "override params land" check already passes its own value; bash packaging/mac/packaged-config.sh --test: all checks passed | | fork 21d4c73c (+ c4-fix), app 5520fb1 | PC 2 job build-20261005-182244 (--node-tests "kaspa-consensus kaspa-consensus-core igneum-exec kaspa-pow igneum-miner kaspa-p2p-flows" --app-tests igneum-app) | 18:23:15 to 18:25:41Z: the node stage FAILED, exit 101 after 44 s: kaspa-consensus 96 passed, 1 failed, 3 ignored: processes::finality::tests::ban_is_decided_by_the_carrying_block_so_nodes_agree_on_every_voter_list panicked at finality.rs:1883:82 (the mine_on_all helper's validate_and_insert_block(...).unwrap()) with UnexpectedDifficulty(<bits>, 487112096, 487129281): a block built on one TestConsensus was refused by another for a difficulty a few hundred bits off. cargo stopped at the first failing package, so the other five were not run in this job. The app tests passed: igneum-app exit 0 in 6 s (hotplug's and elevated-exit's tests included; 96 + the signer and wrapper suites) | | fork 21d4c73c | PC 2 job build-20261005-182804 (--node-tests kaspa-consensus, the suite ALONE) | 18:28:3x to 18:30:15Z: kaspa-consensus 97 passed, 0 failed, 3 ignored in 1.99 s, ban_is_decided_by_the_carrying_block_so_nodes_agree_on_every_voter_list ... ok. So the test passes alone (as in the c4 agent's own run, build-20261005-180827, 97 passed) and failed once under the six-package parallel run: the 0.3.6 isolation class (release-0.3.6 plan 8f), now with a difficulty expectation that depends on wall-clock timing rather than the PoW cache queue. Not a consensus regression by the same reasoning as then; recorded in section 11 for the c4 agent (the test or the helper should pin its clock) | | fork 21d4c73c | PC 2 job build-20261005-183131 (--node-tests "kaspa-consensus-core igneum-exec kaspa-pow igneum-miner kaspa-p2p-flows") | 18:31:31 to 18:33:59Z: exit 0 in 37 s: kaspa-consensus-core 101 passed (2 ignored), igneum-exec 15 passed, igneum-miner 15 passed, kaspa-p2p-flows 33 passed (the target compiles and passes on the merged tree: the nine epoch_seed_headers errors of release-0.3.6 are gone with tx-gossip's ibd/proof.rs update, as the c4 agent said), kaspa-pow 13 passed (both queue tests of housekeeping B). With build-20261005-182804 (consensus alone, 97 passed) every package of the six is green on 21d4c73c; the app suite passed in build-20261005-182244 |

4. The state of the network before the cut

Both of the 0.3.9 agent's rollouts finished before anything of 0.3.10 moved: the fee switch (H = 210,000, every node on ab8847da..., release-0.3.9.md 10e, 17:55Z) and then N3 (the project lead: "deploy N3 now"; finality_v3_activation_daa 135,200, manifest republished 17:59:14Z, docs/plans/finality-v3-devnet-publish.md): the sweep there lists every live node on 1f4b44255fcd2ea8f75664ed47200f409186ddd2292960c9e2cf95bbbdc11505 (the observer 17:58:13Z, node 1 17:58:25Z, the seed 17:58:43Z, PC 2's app node 18:04:57Z, PC 1's app node 18:06:28Z). The override object every node runs, and the one the 0.3.10 manifest and packaged line carry:

{"difficulty_v2_activation_daa":33000,"proving_v0_activation_daa":84100,"fees_v1_activation_daa":210000,"finality_v3_activation_daa":135200}
Node Binary at 18:03Z Override Digest
Mac d937c69d app 0.3.9; its engine has run NO node of its own since its hourly restart at 17:45:16Z: it found node 1 answering on 127.0.0.1:26610 and uses it (the N3 record, "the Mac app's external-node finding"), so the Mac card's node line is node 1's node 1's node 1's
PC 1 ae432dc7, PC 2 1ccfe586 app 0.3.9, node a24ab01a (the Mac cross-build) the four-field object 1f4b4425...
Sam's Mac 3a9bf309 app 0.3.9, node a24ab01a, 0.0 MH/s at 18:03Z (its app writes the manifest's object) not read
The observer, node 1 (hand nodes, this Mac) vendor/igneum-node-036/target-integration/release/igneumd a24ab01a /tmp/igneum-devnet/override-v3.json, the four-field object 1f4b4425... (read 18:02Z)
The seed 188.245.5.161 /opt/igneum/v4/bin/igneumd 7e26e374... (the a24ab01a zig cross-build, glibc 2.34) /etc/igneum/override-v3.json, the same 1f4b4425...
PC 37ba0461 silent (0.3.7 at the 0.3.8 cut)

Master moved under the branch while it was cut (fef98a2/a850aef CLAUDE.md, 900bba7 the site's 0.3.9 download cards, 46a6a4e and bf8d1ba the N3 record, a93199a); merged as d1f4923 (docs and site only, 5 files, no conflict).

5. The node binaries and the DMG (fork 21d4c73c, app 5520fb1 and later)

Platform Build sha256 Size Notes
Mac arm64 igneumd CARGO_TARGET_DIR=vendor/igneum-node/target-0310 cargo build --release -j 4 -p kaspad -p igneum-miner --features kaspad/igneum-pow from vendor/igneum-node-0310, under the lock, 18:21:54 to 18:24:2xZ (incremental) 4bb356f492a52154c932ee6f802cd59dc5c917840ad46ba2133905f52b838b3c 41,152,144 21d4c73c in its strings; copied into vendor/igneum-node-0310/target-integration/release/
Mac arm64 igneum-miner same 322472ae95a316d12281fed99b2112cdb5f7b6caf9f25ea24019219b7e907948 8,514,928 byte-identical to the 2f88a82f build: the miner is untouched by gossip and c4
The digest check that igneumd on a scratch node, ports 60975/60976, 22 s, 18:24:23Z, the four-field object Finality rule v3 ... 135200, Calibrated v1 fees ... 210000, digest 1f4b44255fcd2ea8f75664ed47200f409186ddd2292960c9e2cf95bbbdc11505, igneumd/2.1.0-21d4c73c equal to every live node's (section 4): the three fork branches move no parameter; the chain script stops on any other value
Linux x86-64 igneumd (the seed, glibc 2.36) NODE_SRC=<abs> TARGET_DIR=<abs> OUT_DIR=<abs> infra/cross/build-linux.sh (zig), under the lock, 18:25:43 to 18:27:29Z (105 s incremental) 40be0e142e30f6de89ccb61f6dc13e8748ed2a41988753604dbdbb9da1466b4b 47,638,184 GLIBC_2.34 at most, 21d4c73c in its strings; version.txt from 21d4c73c (release-0.3.10). Kept in the scratchpad r0310/cross-final2/ and copied to infra/cross/out-0310/ of the main checkout for restart-seed.sh
Linux x86-64 igneum-miner same 6ec3536717536fd505b63eef5d01ec9fa19d1fe608ba86398135c5776222ec73 9,631,280
Windows x86-64 igneumd.exe PC 1 job build-20261005-182405 (IGNEUM_WIN_RELEASE=<fork>/target-integration/x86_64-pc-windows-gnu/release node tools/build-job.mjs run --node vendor/igneum-node-0310 --target ae432dc7 --targets linux,windows --no-tests from this worktree: its own build-inputs-20261005182334-74461.zip, the per-job name of 68f14b9), published 18:24:05Z, started 18:26:1xZ after another agent's job on PC 1, every stage ok 18:31:43Z (linux 136 s, windows 162 s, pack 3 s; 9 files, 45 MB, all sha256 and PE checks ok, placed) 3adb01a712fba678706ed5eeb1fa9788895735e4fab5e81dbefe03bd675a5e04 50,978,816 the PC build (housekeeping A); no commit string inside (section 11); acceptance: section 5b
Windows x86-64 igneum-miner.exe same 1105151c91738a4e177b8f327625c6e22a90423fe66a71a5d045130618281052 10,725,888
Windows x86-64 igneum-app.exe (the PC's build; the installer's engine is the GitHub runner's) same 4ead820eb4c502de18f8c122d319543452615ba96b8471a501eb2237e76835b7 2,925,056 hotplug's first Windows compile (detect::adapters, the WM_DEVICECHANGE path is host.cpp, built by the runner): warnings only; among them hotplug's own function adapter_for is never used (for its agent), the rest pre-existing (94 trailing semicolon in macro, p2p-flows 21, dead keep/wsl_path)
Linux x86-64 igneumd (HiveOS, glibc 2.39, not the seed) same, infra/cross/out/ of this worktree 38e69412b66a9ee183f3a28f25198f31ce29f83554f7a7f7dce9bdc4f61970be 48,915,112
Linux x86-64 igneum-miner, igneum-app same 39efcb1773dc215d..., cd8680e5b8c07795... 9,607,448; 2,370,544

5b. The acceptance of the PC-built Windows node (housekeeping A)

Run job run-0310-accept-final (the housekeeping agent's run-accept-pc1.ps1 unchanged: copies the three exes from PC 1's /root/igneum-build/target/x86_64-pc-windows-gnu/release into a scratch folder with NO mingw DLL, runs rocks-probe, then igneumd.exe --devnet --nodnsseed --disable-upnp --rpclisten=127.0.0.1:26710 --listen=127.0.0.1:26711 --nologfiles --yes on a scratch appdir for 60 s, then igneum-miner.exe key-hash probe, then reads Application event 1000), published 18:32:37Z from this worktree: ran 18:33:08 to 18:34:15Z (67 s), exit 0: rocks-probe exit 0, RESULT run node60: still running after 60 s (alive for the whole wait); killing it, igneum-miner.exe key-hash probe exit 0, RESULT event 1000: none since 18:32:11Z. The same verdict as the housekeeping run (run-hk-accept-1) and my warm-up run on 2f88a82f (run-0310-accept-hk, 16:57Z, the exe 37d0b104...). So the PC-built Windows node ships; no Mac cross-build was needed. The payload inputs: section 5c.

5a. The DMG

The chain under the lock (the 0.3.9 script's shape): the app (cargo build --release in app/igneum-app, 18:24:47Z, target cloned from the 0.3.9 worktree), the prover host and export (18:24:54Z, no Succinct toolchain: the host embeds elf/), igneum-prove-host --mode id on this tree: shard program id 0x2b1a81cb413236cf063077b46ed3111628f6c41036bcf6e23ee4cbbf5679ef7a (2,832,504 bytes, sha256 0x150f4c05a2951fc5), aggregator 0x474678f35f7545db28055d5e5bbc308231d84a5a072202087a2a8d5b09123896: the 0.3.9 pin, unchanged (no prover rollout). The nine real fixtures ran --mode native with the new host (338, 341, 344, 56 x2, 58927, 72803, 72854, 78: all ok); the first chain stopped on block-72803-skipped-copies.json.node-plan.json, which is a node-plan SIDECAR of the 72803 fixture (txgen 49796b0), not a fixture, so the glob now excludes node-plan sidecars. Then NODE=<fork>/target-integration/release/igneumd MINER=... packaging/mac/build-dmg.sh (18:26:04 to 18:26:34Z): prover: ... from <worktree>/proving/igneum-prove/target/release, the same --mode id line, fingerprints 477bb0ef (intake key) and ed9c4d2e (folder).

Artefact sha256 Size
packaging/mac/dist/Igneum-Miner-0.3.10.dmg (engine 0.3.10, node 21d4c73c Mac arm64, the 0.3.9 prover host and export rebuilt from this tree) e8f1f9f620cb598fd21ff2b6f6a2dea3d9e58efc0550c6454dc65f0a3d791b97 41,377,608

Read back from the DMG (mounted read-only, 18:28Z): Contents/Resources/igneum-app.json carries node_override_params = {"difficulty_v2_activation_daa": 33000, "fees_v1_activation_daa": 210000, "finality_v3_activation_daa": 135200, "proving_v0_activation_daa": 84100} (the packaged line of 9997ef1) beside update_manifest, log_intake_url, log_intake_key, live_page, download_page; bin/ holds igneumd, igneum-miner, igneum-bench, igneum-prove-host, igneum-prove-export.

A note on my own logs: the chained scripts print <time> ... exit $? lines where the time is a command substitution evaluated first, so those lines always say 0. Every outcome in this plan is read from a content line (Finished, a sha256, a RESULT, a final:), never from them; tools/lock/with-lock.sh itself propagates the exit code (checked: run bash -c 'exit 3' returns 3).

6. The harness runs (C and D)

Run Node Command Result
D, early (before c4) fork 21babaa7 Mac arm64 (target-0310) IGNEUMD=... IGNEUM_MINER=... IGNEUM_HARNESS_BASE_PORT=29750 IGNEUM_HARNESS_TMP=/tmp/igneum-txrelay-0310 tools/lock/with-lock.sh run node tools/txgen/relay-net.mjs --rate 2 --duration 120 --wallets 16 --fund 2 from the tx-gossip worktree (the harness was not yet on this branch) 17:54:26 to 18:01:01Z: final: sent 240, included 240, pending 0, failures 0, 1.951/s, latency p50 2,017 ms, p90 3,561 ms, max 6,560 ms: the coordinator's expected 240 of 240
D, final fork 21d4c73c Mac arm64 (igneumd 4bb356f4...) the same command from the tx-gossip worktree (this worktree has no node_modules: the harness imports viem, the first attempt from here died at import; tools/txgen/ needs an install note), ports 29750+, data /tmp/igneum-txrelay-0310b 18:26 to 18:31:05Z: final: sent 240, included 240, pending 0, failures 0, 1.975/s, latency p50 1,537 ms, p90 3,027 ms, max 5,025 ms; report in the scratchpad r0310/relay-final2/ (by miner: B and C only, A none, as the harness requires)
C the 0.3.10 node node tools/finality-attacks/c4.mjs on (pending)

5c. The Windows payload inputs (18:35:33 to 18:36Z)

IGNEUM_WIN_RELEASE=<fork>/target-integration/x86_64-pc-windows-gnu/release IGNEUM_NODE_SRC=<fork> packaging/windows/push-inputs.sh from this worktree (the sed -n 1p signer read of 68f14b9): igneumd.exe 3adb01a7... (50,978,816) and igneum-miner.exe 1105151c... (10,725,888), the PC 1 build of 21d4c73c, with the PC's three mingw DLLs (libstdc++-6 26,347,027, libgcc_s_seh-1 774,200, libwinpthread-1 324,451; the exes import none of them since housekeeping A, the DLL gate and the copy stay for an older fork). Signed inputs: zip c175446e33ccb020e2f5fdaf99100d5bd46138c7693b3e16948a82f7c252eaa4 (33,996,479 bytes, 5 files), node_source_commit 21d4c73c6ce32fcbd68391968e85827339a511c0 (release-0.3.10), repo_commit 9a51e32, built 18:35:37Z, deployed, payload-inputs.json HTTP 200; node-source.pin = 21d4c73c, committed as 065c67c.

7. The ship

git push -u origin release-0.3.10 at b958493 (18:36:44Z, the credential helper; gh auth switch --user igneum-labs before every gh call, the login renamed igneum-labs at 18:00Z, the token still under that name), gh workflow run windows.yml --ref release-0.3.10 -> run 37357266092 (queued 18:36:49Z on b958493).

The pre-push hook (fb076de: no conflict markers, cd site && node build.mjs) left site/index.html and site/journey.json modified after the push: the hook builds from site/, I had built from the root (node site/build.mjs), and the two runs label one bench entry differently ("RTX 5090 first run" from site/, "RTX 5090, memory-hard dataset" from the root; master carries the hook's form). A cwd-dependent site build, recorded in section 11; the hook's output is committed (the next push reproduces it and leaves the tree clean). Those commits touch no app or packaging file, so the installer built at b958493 is the release; the ship state file (~/.cache/igneum/ship/0.3.10.json) got sha = b958493 and runId = 37357266092, what the tool's own steps would have recorded, and the run resumes with --from ci.

(pending: the ship command and its steps)

8. The machines after the publish

(pending)

9. The hand nodes and the seed

(pending)

10. The mixed fleet during the window

(pending)

11. Open after the cut

Item State
infra/cross/build-linux.sh resolved a relative TARGET_DIR inside the node source after its cd, so the copy step shipped the previous build's bytes (twice tonight, caught by the commit string in strings). Fixed here (e0a5fd1). The class: any script that takes a directory argument and changes directory before using it; proto-cuda/windows-node/cross-build.sh takes the node worktree as $1 and CARGO_TARGET_DIR from the environment (the 0.3.9 cut passed a relative one and it worked only because that script does not cd); a CI check for the shape is owed fixed on the branch; the check owed
hotplug's proto-opencl/host.c change (the worker's --list prints the PCI address, the key to one row per physical card): no prebuilt OpenCL worker is in the payload inputs (the live zip holds igneumd.exe, igneum-miner.exe and three DLLs), the payload carries host.c and build.bat and the app builds the worker on the PC from them (engine.rs build_worker_from_source), so the change ships inside the 0.3.10 installer; whether an app that already has a worker exe rebuilds it from the newer source was not read here. Check on the console after the update: the PCs' card rows carry the PCI address (and one row per AMD card) only if the worker was rebuilt; else a rebuild is the hotplug agent's follow-up open: told the hotplug agent
kaspa-consensus test ban_is_decided_by_the_carrying_block_so_nodes_agree_on_every_voter_list (c4-fix) failed once under the six-package parallel run on PC 2 with UnexpectedDifficulty(487112096 vs 487129281) in mine_on_all (section 3) and passes alone, twice. The helper builds a block on one TestConsensus and inserts it into others; the expected difficulty of the receiving node differs when the run is slow, which points at a wall-clock dependence (difficulty v2's sanitised clock per header). For the c4 agent: pin the clock or the timestamps in that helper, as the finality tests do for the cache queue. Until then a parallel six-package run can fail this test under load; the suites are run as consensus alone plus the other five open
site/build.mjs labels one bench entry differently when run from the root and from site/ (the pre-push hook's cwd): "RTX 5090 first run" against "RTX 5090, memory-hard dataset" for the same tree (section 7). Something in the build reads relative to the cwd or orders by it; master carries the hook's form open: find the read, make the build cwd-independent, and have the hook refuse a push whose build output differs from the committed site
The PC-built node binaries embed no commit (the build inputs zip has no git dir, build-info falls back to the bare version): the console shows PC 1 and PC 2 as node 2.1.0 with no commit after 0.3.10, as the 0.3.6 PC build did. The build inputs manifest records the fork commit (2f88a82f and later) open: a commit stamp through the build job (jobbuild.rs) is an app change, not tonight