igneum/docs/plans/release-0.3.11.md
igneum-labs 87dcbd804a release-0.3.11 plan: the PC 2 job id, the rollout order as agreed
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 23:10:03 +00:00

22 KiB

Igneum Miner 0.3.11: program class v3 (Counter ASIC 2.0) and proving v1 on the devnet, 5 October 2026

Release engineer, from 22:39 UTC, on the coordinator's instruction under the project lead's delegation ("Counter ASIC 2.0 fully deployed", "deploy what is absolute best" for proving v1). Worktree /Users/joshm/Projects/igneum-wt-ship0311, branch release-0.3.11, assembled by the Counter ASIC coordinator from master b38f3de (the 0.3.10 merge) and taken over at its merge tip b968ee0 so there is one ship, not two. Fork worktree vendor/igneum-node-0311 UNDER the release tree (the node links ../../../../igneum-pow, the release tree's crate), branch release-0.3.11-node at 89dfcb95 (on 21d4c73c = 0.3.10's node, with proving-v1 ece42979 and the digest re-pin). The 0.3.10 recipe (release-0.3.10.md) throughout; every Mac build under the main checkout's lock; every PC job and publish from this worktree's tools (the signed envelope, the per-job zip names). Times are UTC.

1. What 0.3.11 carries

Change Where State
Program class v3 (Counter ASIC 2.0): the era draw, the cache growth rule, the mixer x8, behind program_class_v3_activation_daa (keys on the epoch: program_class_v3_first_epoch); the workers carry the class, era and attempt rules on the serve protocol and refuse a pack of the wrong class or era main ca2-v3 fa3c932 (code 49c7e78; igneum-pow, the workers, the fast-time scripts, the plans); fork ca2-v3-node 89dfcb95 merged (c9b0b2c)
Counter ASIC 2.0 docs, spec, site, evidence, the rollout plan and its gates (G1, G2, G3, G4, G4b, G6 green; G5 = the one-commit workers of this cut) main ca2-coord 076c0ab then 57844e9 (C34) merged (18605f4, 5cedcd4)
Proving v1 (spec 7.8): the aggregated segment record, the chain rule and the unproven rule behind proving_v1_activation_daa, with proving_v1_segment_blocks 8, proving_v1_unproven_daa 600, proving_v1_aggregator_share_bps 1000; the app's prover loop (the CPU path refused under 32 GB with the reason, the root-socket cleanup, the PermissionDenied line naming the cause); the resume fix (every stopped card re-armed, its pack re-exported, checked 90 s later); every worker gets --prepare-packs in the platform's path form (the Mac's Metal worker takes a class v3 day from the prepared pack) main proving-v1 22c2363 (its agent: the final code tip; c36dfea after it is docs only and waits); fork proving-v1 ece42979 inside 89dfcb95 merged (5cbb796)
CI: bash-body-check.sh (inline bash bodies in PowerShell job scripts parse), kit-path-check.sh (a run job tests its fetched kit before use, C32), prover-socket-check.sh (every root prover playbook unlinks the GPU server's socket) main bash-body-check e3bd761 merged (fe1ecdb; ci.yml keeps the signer-pipe step, both new steps and proving-v1's socket step)
The consequences ledger, the proving-methods analysis, the ASIC-resistance history consequences 99fd988, proving-methods e7e0db7, asic-history 9e4af7f merged (5dffb1b, 0f5bfc3, b968ee0)
The pinned proving guests unchanged (no prover drain)

Changelog line (the coordinator's words): "Igneum Miner 0.3.11: program class v3 (the era draw, the cache growth rule, the mixer x8) from epoch N4/3600 and proving v1 from DAA N5; the resume fix; the Metal worker takes v3 from a prepared pack".

2. The branch

Commit What
b968ee0 the Counter ASIC coordinator's merge tip (above), taken over at 22:40Z; its checks on the Mac: igneum-pow 53 + 4 + 19 + 7, the app 113 + 27 + 8, 0 failed
21173c4 Igneum Miner 0.3.11: the six version files (--check: 0.3.11 in all 6)
cc72f4a CI on the merged tree, three findings fixed: the identity check's hostname pattern MacBook matched prose in card-lifetime-2026-10-05.md and proving-methods.md (reworded "Apple laptop"); the kit-path check flagged tools/proving-v1/pc2-{memory-miner-on,memory-sweep,sp-curve}.ps1 for a bare jobs\ literal in WslPath (Join-Path ...) (now Test-Path on the kit root, then WslPath $kitFile); the socket check flagged tools/amd-prove/pc1-cpu-prove.ps1 and its -sp sibling, which the addendum said were allow-listed and were not (allowed, the CPU path starts no GPU server). The other agent's resolution had kept both ci.yml sides and bash-body-check's 24-line socket check; one slip of mine (a git show :3: redirect after that resolution had already committed) truncated that script to 0 lines in the working tree for a minute and was restored from HEAD
23bc2b2 packaging/mac/packaged-config.sh: the nine-field object (section 4) in the packaged line, --test passes (C34: a fresh install must start on the fleet's digest)

| a94416e | the plan draft committed to the tree before the push (the reviewer's C37) | | after a94416e | C38 (the reviewer through the Counter ASIC coordinator): the evidence rows, the litepaper's chip bullet, chip-model-v3.md and the rollout plan cite files on four Counter ASIC branches that never reached the tree. Taken as docs plus standalone sources under one gate: the diff against 23bc2b2 over every input a built artefact reads (igneum-pow/src, app/, proto-cuda/nvrtc/{packfile.h,worker.cpp,cuda_api.h,build-windows.sh}, proto-cuda/{host.cu,build.bat,windows-app}, proto-opencl/{host.c,cl_dynamic.h,build.*}, proto-metal, packaging, proving, vendor, .github) must stay empty apart from files no script compiles or copies. Merged: ca2-analysis ee42d7c (sram-mirror.md, int8-matrix-family.md, the dot4 probe sources: proto-metal/dot4-probe.swift is standalone, the DMG script compiles main.swift alone), ca2-epoch e95e8b5 (epoch-length.md), prover-floor cfe3d80 (prover-floor.md, tools/prover-floor/ scripts, a playbook, proving/prover-floor/sp1-gpu-6.8.1-floor.patch, which nothing reads: the next cut's packaging row); docs/bench-log.md conflicted each time (append-only: both sides kept). ca2-soundness a465881 conflicted in igneum-pow/tests/scratch.rs (add/add) and proto-metal/packbench.swift, code the mixer merge already carries, so its merge was aborted and docs/analysis/scratch-soundness.md taken alone. So G5 holds: the workers, the Metal worker and the DMG built at 23bc2b2 correspond to the tip's built inputs |

Every check at cc72f4a: identity 0 hits over 220 files, copied-sources, pinned-guests, signer-pipe, bash-body 15 bodies in 28 files, kit-path 14 of 14 kits checked, prover-socket, no-conflict-markers, workflow shell 0 findings over 35 .ps1, relay tests 17, UI tests 23.

3. Builds and tests (the 0.3.10 recipe)

What Command Result
The fork's Mac node, 89dfcb95 CARGO_TARGET_DIR=vendor/igneum-node/target-0311 cargo build --release -j 4 -p kaspad -p igneum-miner --features kaspad/igneum-pow from vendor/igneum-node-0311 (under the release tree), under the lock; the target dir cloned by APFS from target-0310 22:46:16 to 22:49:5xZ (3 min 19 s, incremental): igneumd bd7f043c453f4b3e9575e678912b71115227b09789d5ec0f367b8278f031d043 (41,386,016, 89dfcb95 in its strings); copied into the fork worktree's target-integration/release/
The seed's Linux node (glibc 2.36 target, zig) NODE_SRC=<abs fork> TARGET_DIR=<abs> OUT_DIR=<abs> infra/cross/build-linux.sh (the 0.3.10 fix: absolute paths; cargo clean -p kaspa-build-info first), under the lock 22:46:35 to 22:49:59Z (3 min 20 s): igneumd 63cf490d42483d3aa4e525eba9b4e4b68cae9090c32f409e745858defc381c52 (47,913,832, GLIBC_2.34 at most, 89dfcb95 in its strings), igneum-miner a136d622... (9,861,280)
The two Windows workers (G5: one commit) proto-cuda/nvrtc/build-windows.sh under the lock, tree 23bc2b2 22:46:43 to 22:46:50Z: igneum-worker-cuda.exe 2b3b8c92885442179f6bf2907c6f3eb453dc4a19908d90fd05981a09b7c2674c (1,536,512), igneum-worker-opencl.exe edc4a75da3b93d814caa69fd635010780d63d5b622ec24c3741d433c584f91e3 (478,208); both carry the resource block; both differ from 0.3.10's pair (85cc357b..., afa73a32...): the class, era and attempt rules are in them
The app cargo build --release in app/igneum-app (target cloned from the 0.3.10 worktree), then cargo test --release -p igneum-app, under the lock 22:47Z: igneum-app 0.3.11; tests ok 113 (lib) + 27 (ota-sign) + 8 (prove-verify), 0 failed
igneum-pow cargo test --release in igneum-pow, under the lock 22:47:33Z: ok 53 + 4 + 19 + 7, 0 failed (the class v3 vectors, the era draw, the mixer x8, the scratch soundness)
The prover host and export (the pin unchanged) cargo build --release -p igneum-prove-export -p igneum-prove-host in proving/igneum-prove (the worktree needed the vendor links: vendor/igneum-node-exec and 45 others symlinked to the main checkout's, beside the real igneum-node-0311 worktree) 22:48Z: --mode id shard 0x2b1a81cb..., aggregator 0x474678f3... (the 0.3.9 pin: no prover drain); the nine real fixtures --mode native all ok
PC 1 build job (the node and the app, Linux and Windows) IGNEUM_WIN_RELEASE=<fork>/target-integration/x86_64-pc-windows-gnu/release node tools/build-job.mjs run --node vendor/igneum-node-0311 --target ae432dc7 --targets linux,windows --no-tests from this worktree, its own zip build-inputs-20261005224625-29789.zip job build-20261005-224654, published 22:46:54Z (PC 1 given by the Counter ASIC coordinator at 22:4xZ: Ember's collect job closed, the AMD sweep off tonight). (pending)
PC 2 suites waits for the Counter ASIC coordinator's "PC 2 suites go" (agg-cost-pc2-3 on PC 2 until about 22:59Z) (pending)

3a. PC 1's app down, and the relay task that hit the wrong machine (22:31 to 23:05Z)

PC 1's installed 0.3.10 app quit at 22:31:06Z (its last upload 22:31:08Z, run win-ae432dc7-20261005-214041; Ember's tune job on it reported "aborted (the app is quitting)"; the quit's sender is C35 for the consequences reviewer) and did not come back, so PC 1 mined nothing, its build job build-20261005-224654 could not start and no update-now could reach it. Three relay tasks (#241 at 22:52:31Z, #243 at 22:55:10Z, #245 at 23:03:18Z) went to the relay machine named "PC1" to relaunch the app, the second ending an engine that answered nothing on /api/state and the third ending every igneum process before the launch, as the app's own updater does.

They hit the wrong machine. The relay's "PC1" is the 1ccfe586 box, the console's PC 2: both PCs carry the hostname DESKTOP-KMCV30N, the only relay agent runs on the 1ccfe586 box and was named PC1 when the clients were set up, and the relay's PC2 entry reads "never seen". The intake proves it: PC 2 got two new engine runs, win-1ccfe586-20261005-225528 and -230330, at the exact times of #243 and #245, while PC 1 has no run after 21:40:41Z; #243's "hung" engine, pid 26696 from 21:49:40Z, was PC 2's healthy 0.3.10 engine (my probe's "no answer" on /api/state was its own fault, no token), and the node, three miners and three workers it found were PC 2's own (a 5090 and the iGPU; PC 1 would have shown the 9070 XT too). So PC 2, the box the night's measurements run on, was force-restarted at 22:55:28Z and 23:03:30Z, which killed the aggregation-cost agent's job 3 (re-run owed, 20 min) and ended whatever followed; its app came back each time (after #245: pid 30484, responding, node, three miners and both workers up, the card climbing at 23:04Z). PC 1 is exactly as it was: engine down since 22:31:06Z, no relay agent on that box, unreachable tonight; it waits for the project lead in the morning and takes 0.3.11 through the manifest at its relaunch; the fleet runs short its 141 MH/s until then. Told the Counter ASIC coordinator at 23:05Z; it re-set PC 2's schedule (this cut's combined build and suite job first, then the prover-floor pair, the aggregation-cost re-run, "PC 2 clear", the M16 job) and ruled that no relay task goes to "PC1" from anyone without its word. Every relay "PC1" reading tonight was PC 2 (the AMD agent's "9070 XT absent" probes read a box that has no 9070 XT; the hardware events are being corrected). The relay machine should be renamed PC2 (node tools/relay.mjs name <hostname> <name>) and the PC 1 box get its own agent (section 11). The Mac cross-build fallback for the Windows exes was announced and not started: the combined PC 2 job replaced it within the minute.

| PC 2 combined job | IGNEUM_WIN_RELEASE=<fork>/target-integration/x86_64-pc-windows-gnu/release node tools/build-job.mjs run --node vendor/igneum-node-0311 --target 1ccfe586 --targets linux,windows --node-tests "kaspa-consensus kaspa-consensus-core igneum-exec kaspa-pow igneum-miner kaspa-p2p-flows" --app-tests igneum-app from this worktree (its own zip build-inputs-20261005230716-50058.zip); PC 1's job removed from the jobs file so nothing double-places the exes | job build-20261005-230745, published 23:07:45Z (PC 2 woken), the first job on PC 2's re-set schedule. (pending: the stages, the suites, the exes) | | PC 2 suites | waits for the Counter ASIC coordinator's "PC 2 suites go" (agg-cost-pc2-3 on PC 2 until about 22:59Z) | (pending) |

3a. PC 1's app down (22:31 to 22:5xZ)

PC 1's installed 0.3.10 app quit at 22:31:06Z (its last upload 22:31:08Z, run win-ae432dc7-20261005-214041; Ember's tune job on it reported "aborted (the app is quitting)"; the quit's sender is C35 for the consequences reviewer: the tray Quit, stdin EOF in wrapper mode, or POST /api/quit, which Ember's playbook sends when its budget is spent) and did not come back, so PC 1 mined nothing, the build job build-20261005-224654 could not start (no app to fetch it) and no update-now could reach it. The relay agent on PC 1 was alive (it runs as a logon scheduled task at highest privileges in the user's session), so the relaunch went through it at 22:52:31Z as relay item #241 (node tools/relay.mjs run PC1 ... relaunch-pc1.ps1): the per-user install's igneum-app.exe started through explorer.exe, which hands the app the user's own medium-integrity token as a double-click does (a plain Start-Process from the elevated agent would have made the app elevated, which its updater never does), with a one-shot scheduled task at limited run level as the fallback; the script prints the process, its session, app.url and /api/state. Its result (22:5xZ): igneum-app.exe was ALIVE, pid 26696 since 21:49:40Z in session 1 (app.url written 21:49:40Z), and answered nothing on /api/state in 60 s: the engine had logged its quit at 22:31:06Z, stopped the miners and the node, and then hung instead of exiting (the C35 fact: a quit that never ends; the sender is still the reviewer's question). The script launched nothing because a process existed. A second task (#243, 22:55:10Z) ends that engine by pid, as the app's own updater ends the old engine, and launches as above. Its result (#244, 22:57:18Z) changed the picture: the old engine was responding=True and had a node, two miners and three workers ALIVE under it, so PC 1 had been mining with an engine whose uploads and HTTP answers had stopped (my probe's "no answer" on /api/state may be its own fault: no token); the kill left those children running as orphans on their ports; the new engine (pid 30964, 22:55:28Z, session 1) wrote its app.url at once and then put nothing into the intake for minutes. The next step, if no run id appears by 23:01:30Z, is the updater's own order as one task: every igneum process ended (miners, workers, node, engine), then the launch.

The reading (Ember's agent through the Counter ASIC coordinator, 23:00Z): the alive children were Ember's SECOND engine's orphans (its tune job starts a second igneum-app with its own two miners on the 5090 and the 9070 XT), left mining when the job was aborted, holding both GPUs; the installed engine's quit at 22:31:06Z then stuck in the jobs runner's abort, waiting for EOF on the script's stdout pipe, whose write end the second engine and its miners had inherited (PowerShell's Process.Start inherits every inheritable handle), so EOF never came. The class rule, for every job script that starts a second engine (relay/playbooks/sweep-5090.ps1 has the same shape): no pipe into it, and its whole tree killed at the end. The installer-build fallback script of 0.3.10 starts no second engine. (pending: the reset's result, the new run id, the first STATUS line) | The DMG | NODE=<fork>/target-integration/release/igneumd MINER=... packaging/mac/build-dmg.sh under the lock, 22:50:0x to 22:50:51Z | Igneum-Miner-0.3.11.dmg b7e81d4f6f3af9f9179e29faa72c844b795df757dfb2e4cd1d56cd454e78e1e7 (41,592,041): engine 0.3.11, node 89dfcb95 Mac arm64, the 0.3.9 prover host and export, igneum-bench (the Metal worker) rebuilt from this tree (667,145 to 555,808 bytes, signed ad hoc), fingerprints 477bb0ef and ed9c4d2e; read back from the mounted image: Contents/Resources/igneum-app.json carries the nine-field node_override_params with N4 = N5 = 154,800 (C34) |

4. The override object, N4 and N5, the digests

The object every node runs after the publish (the four live fields plus the five new ones):

{"difficulty_v2_activation_daa":33000,"proving_v0_activation_daa":84100,"fees_v1_activation_daa":210000,"finality_v3_activation_daa":135200,"program_class_v3_activation_daa":154800,"proving_v1_activation_daa":154800,"proving_v1_segment_blocks":8,"proving_v1_unproven_daa":600,"proving_v1_aggregator_share_bps":1000}

N4 and N5 are fixed BEFORE the DMG and the installer are built, because the packaged line (C34) must equal the manifest's object: DAA 136,967 at 22:45Z (PC 1's card) at 0.965 blocks/s puts the publish (about 23:40Z) near 140,200; tip + 14,400 is near 154,600; the first multiple of 3,600 at or above it is 154,800 (N4's rule), which N5 takes too. At the publish the floor N - DAA >= 10,800 is checked; it holds until DAA 144,000 (about 00:45Z); past that the line is re-pinned and the DMG and installer rebuilt.

The two digest readings on the 0.3.11 Mac node (bd7f043c..., ports 60975/60976, 22 s each, under run):

Override file Lines Digest
none (the rolling-upgrade value: both new activations at never) igneumd/2.1.0-89dfcb95 c562d70e1428c9789823cc40067623b4767f7c555ce7ff4ea11c1498f013ef6c, EQUAL to the node agent's pinned test on 79bd8e10 (22:49:59Z)
the nine-field object above Program class v3 from the override file: active from epoch 43 (DAA score 154800 rounded up to the epoch boundary at 154800, epochs of 3600 DAA), Proving v1 from the override file: segment records paid from DAA score 154800, 8 blocks a segment, unproven after 600 DAA, aggregator share 1000 bps, Calibrated v1 fees ... 210000, Finality rule v3 ... 135200 0139ab9dc2992d449ec787d8f021974933631eb55740ab4b6ce9d5c226e72888 (22:50:23Z): the value every node must print after the publish; the sweep in section 9 reads it on every node

A node on the 0.3.10 override (1f4b4425...) and a node on this object never handshake, so the rollout moves every node in one sweep (the fee-switch and N3 shape): the manifest, update-now, the hand nodes, the seed.

10. The next cut

Branch What Why not 0.3.11
ember-tune b671c8b (and the tune behind it) the C35 fix: Cmd::Quit(&'static str) so every "quit:" line names its sender (the window host's stdin, the host gone, POST /api/quit, the sweep's end), elevation_allowed() = Power control alone (the unattended sweep on PC 1 raised one UAC prompt at 22:30Z under the old rule), no power cap at start under --sweep; the quit-source hunk is separable (main.rs 2 lines, server.rs 1 line, engine.rs the Quit arm, elevation_allowed and its test) arrived after the tree closed at 23bc2b2 (the app, the DMG and PC 1's job carry it); not among the branches named for this cut
fud-close (the ledger closer's main branch, a22ba27a60a6f1c64; its ready tip was due about 23:05Z) 45 public-text fixes on the site and litepaper, spec 8.3 and 8.8, two CI checks, relay fixes; touches packfile.h and host.c, so taking it means the two Windows workers, the Mac worker and the DMG rebuilt from the merged tip (G5) offered by the Counter ASIC coordinator at 22:5xZ after the tree closed; not among the branches named for this cut; the fork-side ledger-fixes is not in 0.3.11 either
explorer d7e797c (and 3e01212) /api/stats gains proving; tools/ci/public-api-check.mjs then FAILS when the live API lacks it, and ci.yml runs that check against the live site on every master push, which reads the OLD API until Vercel redeploys after the push (the reviewer's C36) not in 23bc2b2 (only on the explorer branch); its merge needs the check to retry for a few minutes or to require proving only when observer_updated_at is newer than the commit
proving-v1 c36dfea docs only, after the code tip 22c2363 its agent's choice: docs follow
the 0.3.10 list (release-0.3.10.md section 11): fork pack-loop 05ef0fa3, job-console, the rest of opencl-rdna4, opencl-rdna4-telemetry unchanged

5. The rollout order, as agreed with the Counter ASIC coordinator (PC 2's scheduler tonight)

The fee-switch and N3 shape (every node in one sweep, because the digest flips to 0139ab9d...), with PC 1 out of reach:

Step What Gate
the floor 154,800 minus the tip's DAA at least 10,800 at the publish (holds until DAA 144,000, about 00:45Z); past it the line is re-pinned and the DMG and installer rebuilt read on the observer before the manifest step
the manifest --public, --override '<the nine-field object>' --activation-height 154800 --deadline-note "program class v3 + proving v1", the changelog line of section 1 CI green on the release tip
update-now the Mac (attached to node 1) and the laptop (PC 37ba0461, if it is back) first; PC 2 only on the coordinator's "PC 2 clear" (after this cut's build job, the prover-floor pair and the aggregation-cost re-run); PC 1 is unreachable (section 3a) and takes 0.3.11 through the manifest at its morning relaunch
the watch every worker starts clean on the first try with the class-aware pair; the Mac's Metal worker takes the class v3 day from the prepared pack (--prepare-packs); the re-fetch rule C32: an update clears the jobs folder, so the agents whose kits sit on PC 2 republish their fetches after it
the hand nodes, the seed the two scripts with the same object (IGNEUMD the 0.3.11 Mac node, IGNEUMD_COMMIT=89dfcb95; IGNEUMD_LINUX the zig build 63cf490d... and its sha) after the app nodes
the sweep every restarted node prints 0139ab9dc2992d449ec787d8f021974933631eb55740ab4b6ce9d5c226e72888; PC 1 joins at its relaunch
the HiveOS package republished with the new override through the --public step
the plan, the master merge, the push the live observer must not read stale (public-api-check's other arm); the explorer branch's strict check is not in this tree