igneum/docs/plans/cutover-2026-10-04.md
igneum-labs 7eed16a29a Pre-public scrub, the text pass (7 October 2026, 19:5x UK): no founder name, personal login, earlier business or personal address in any tracked text file, and a gate check that keeps it so
The sweep (main's item 1): 199 tracked text files, 783 lines. The founder's full name, first name and possessive become "the founder" (sentence starts capitalised); the lowercase operating-system user name in WSL paths and commands becomes <user>; the second owner login becomes "the second owner login"; the three earlier businesses and the two other brands become "the other business", "the earlier entity", "the earlier business" and "another brand"; the Chrome profile rule names the igneum.network profile, not the profile's label. The standing commit login igneum-labs is not a founder term here: the fresh-repository step renames it in the history (docs/plans/history-rewrite.md, tools/repo/fresh-repo.sh).

The patterns never appear in plain text in the tree (a plaintext list would be the hit): tools/ci/founder-strings.b64 (perl regex, tab, a sample per row) is read by tools/ci/founder-strings-check.sh (every tracked text file, perl, known-failed first: the self-test plants each row's sample in a fixture and the hit must name the file), by tools/community/discord-hooks.mjs (the guard's founder and business rows; the test takes its fixtures from the samples) and by tools/repo/fresh-repo.sh (the business names of the rewrite rules). site/forbidden-strings.txt carries the same patterns as b64: lines, decoded case-insensitive by site/scrub.mjs and tools/ci/launch-gates-check.mjs (whose fixture now plants an encoded made-up name). The check runs in the gate's tree checks on every merge.

Not in this commit, by main's word: the 105 commit messages and 40 personal-identity commits that need the history rewrite (listed, not run), and the secrets found by gitleaks over the history (reported with owners).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 18:39:50 +00:00

15 KiB

Devnet v4 cut-over: runbook for the morning of 4 October 2026

Staged overnight by the release engineer (packages built, seed build installed, nothing switched). The cut-over is a ten-minute operation in this order. Background: docs/fork-divergence.md, section "Integration 4 Oct 2026" (what v4 is, why it is a new chain, the test-network numbers). All Mac commands run from /Users/joshm/Projects/igneum unless a cd says otherwise. Times are BST.

What is staged

Item Where What it carries
Windows combined package 0.2.0 ~/Desktop/igneum-windows-v4.zip (26,238,253 bytes, rebuilt 08:56 BST) v4 igneumd.exe and igneum-miner.exe (cross-build of 6457ca95: generator v2 and the 2/3 floor), the three mingw DLLs, the launchers: peers = seed 188.245.5.161:26611 then Mac 192.168.68.64:26611, appdir %LOCALAPPDATA%\igneum\devnet-v4, MINERS=8 as --identities 8 on ONE worker per card, --evm-address (PAYOUT_EVM, else derived from the PC name per vendor), voting on, --prepare-packs for the hot swap, --exit-on-seed-change kept as the fallback, PLAIN=1 kept, version in the dashboard header
Windows node-only package /tmp/igneum-integration/igneum-node-windows-v4.zip and ~/Desktop/igneum-node-windows-v4.zip (32,973,919 bytes, rebuilt 08:57 BST from 6457ca95) same exes, src.zip, START-NODE.bat with appdir devnet-v4 and EXTRA_ARGS=--addpeer=188.245.5.161:26611 --yes
Mac app 0.2.0 packaging/mac/dist/Igneum-Miner-0.2.0.dmg (19,924,804 bytes, rebuilt 08:56 BST from 6457ca95; the Metal worker carries the generator v2 port) v4 igneumd and igneum-miner from target-integration/release, the Metal worker rebuilt from the hot-swap source with -target arm64-apple-macos11 (prepare 1), SEED_PEERS = seed then Mac, data ~/Library/Application Support/Igneum/devnet-v4, --evm-address and --identities
Seed node v4 igneum-seed-1 (188.245.5.161): /opt/igneum/v4/bin/{igneumd,igneum-miner,run-seed-v4.sh}, /var/lib/igneum-v4 (empty), /etc/igneum/seed-v4.env, unit igneumd-v4 installed and DISABLED first staged from dc749905 overnight; RE-STAGED from 6457ca95 (generator v2, 2/3 floor) starting 08:55 BST on 4 October (stage-v4.sh igneum-seed-1 start, log infra/seed-nodes/build/stage-v4-gen2-run.out); originally built from plus the working-tree igneum-pow (infra/seed-nodes/stage-v4.sh; log infra/seed-nodes/build/stage-v4-igneum-seed-1.log). The v3 unit igneumd keeps running on /var/lib/igneum until step (c)
Mac binaries vendor/igneum-node/target-integration/release/igneumd (40,463,680 bytes), igneum-miner (7,916,096) built from dc749905

Not staged, by design: the live devnet (node 1 on 26610/26611, the observer peer on 26640/26641/28640, observer.mjs, the Mac seed relay on 26680/26681) and the seed's v3 unit all still run the v3 chain.

The order

(a) the founder stops the PC

In both windows on the PC: Ctrl+C (the mining window first, then the node window; or one window if START-IGNEUM.bat was running: it stops the miners first, then the node). Wait for "Igneum has stopped" / "The node has stopped". Expected: the PC's node leaves the Mac's peer list within a few seconds (step (e) checks peers). The old folder C:\igneum (or wherever v3 was extracted) and %LOCALAPPDATA%\igneum\devnet are left as they are.

(b) Main session cuts the Mac over

# 1. stop node 1 (caffeinate exits with it) and move the v3 database aside
kill -INT 72039; while kill -0 72039 2>/dev/null; do sleep 1; done
mv /tmp/igneum-devnet/node1 /tmp/igneum-devnet/node1-v3-2026-10-04

# 2. start igneumd v4: same appdir path, rpclisten and listen, plus the two peers (seed, PC)
cd /Users/joshm/Projects/igneum/vendor/igneum-node
nohup caffeinate -dims target-integration/release/igneumd --devnet --nodnsseed --disable-upnp --enable-unsynced-mining \
  --appdir=/tmp/igneum-devnet/node1 --rpclisten=0.0.0.0:26610 --listen=0.0.0.0:26611 \
  --addpeer=188.245.5.161:26611 --addpeer=192.168.68.67:26611 --nologfiles --yes > /tmp/igneum-devnet/node1-v4.out 2>&1 &
# the execution layer starts with it (eth_ JSON-RPC on 127.0.0.1:26790); expected in node1-v4.out within 5 s:
#   "GRPC Server starting on: 0.0.0.0:26610", "P2P Server starting on: 0.0.0.0:26611", the genesis as the sink, 0 blocks

# 3. restart the observer peer from the same binary (fresh appdir) and observer.mjs
kill -INT 73692; kill -INT 74029
nohup target-integration/release/igneumd --devnet --nodnsseed --disable-upnp --appdir=/tmp/igneum-devnet/observer-v4 \
  --rpclisten=127.0.0.1:26640 --rpclisten-json=127.0.0.1:28640 --listen=127.0.0.1:26641 --connect=127.0.0.1:26611 \
  --nologfiles --yes > /tmp/igneum-devnet/observer-v4.out 2>&1 &
cd /Users/joshm/Projects/igneum && IGNEUM_RPC=ws://127.0.0.1:28640 nohup node tools/observer/observer.mjs > /tmp/igneum-devnet/observer-mjs-v4.out 2>&1 &
# block numbers restart at 0 on the new chain; LIVE_TABLE_PREFIX=v4_ keeps the v3 rows apart if wanted

# 4. the Mac seed relay (pid 72139, v3 binary): stop it; node 1 now dials the seed itself (--addpeer above), so the
#    relay is not needed. If the seed should also be reached through a second path, start it again from v4:
kill -INT 72139
#    RELAY_BIN=vendor/igneum-node/target-integration/release/igneumd infra/seed-nodes/addpeer-from-mac.sh relay start   (optional; it needs
#    its own fresh appdir: rm -rf /tmp/igneum-seed-relay first, or the v3 database refuses to open)

Where the Mac miner runs (the Metal worker, /tmp/igneum-devnet/metal-worker.log): restart it from target-integration/release/igneum-miner with --evm-address 0x... (any address the founder holds) once node 1 is up; an old miner's blocks are rejected from the first epoch boundary (DAA 3,600).

Expected after (b): igneum-miner watch 1 grpc://127.0.0.1:26610 prints blocks=1 headers=1 ... peers=0 synced=true (the genesis only, --enable-unsynced-mining reports synced); the live page shows the new chain from block 0.

(c) Seed: switch to v4

cd /Users/joshm/Projects/igneum/infra/seed-nodes
./stage-v4.sh igneum-seed-1 status      # expect: build=done | ... | v4: installed igneumd 2.1.0, unit igneumd-v4 disabled/inactive | v3: unit igneumd enabled/active
./switch-v4.sh igneum-seed-1            # stop+disable igneumd, enable+start igneumd-v4, then one sync line every 10 s

Expected output of the switch: igneumd: disabled/inactive igneumd-v4: enabled/active, six journal lines ending in P2P Server starting on: 0.0.0.0:26611 and WRPC Server starting on: 127.0.0.1:28610, then lines like synced=False version=2.1.0 blocks=1 headers=1 daa=0 sink=... peers=0 active turning into synced=True ... peers=1 within a minute once node 1 (which dials the seed) has connected and the few v4 blocks have crossed. ./health.sh then prints unit=active-v4. The seed never mines; it relays. Rollback of this step alone: ./switch-v4.sh igneum-seed-1 --back.

(d) the founder starts the PC on v4

  1. Extract igneum-windows-v4.zip to a FRESH folder, for example C:\igneum-v4 (not over the old one: the old package's built workers and packs must not be mixed in).
  2. Double-click START-IGNEUM.bat. Settings at the top are already right (peers, devnet-v4, MINERS=8). If the founder wants a specific payout address, set PAYOUT_EVM=0x... first; otherwise the launcher derives one per card and prints it.
  3. Firewall prompt for the new igneumd.exe path: tick Private networks, Allow access (new exe path = new prompt).

Expected on the dashboard (header "Igneum: node and miners devnet v4, package 0.2.0"): NODE card "starting", then "syncing" with blocks climbing (the v4 chain is minutes old, so sync is seconds), "peer joined (1 peers)" then "(2 peers)" in the events, "synced in N s", then "exporting the program pack", "building the RTX 5090 worker (about 30 s for CUDA)", "started 8 RTX 5090 identities (1 miner)", "RTX 5090 worker ready, hot swap at the hour boundary" and the first "RTX 5090 found a block" within a minute. The launcher log (igneum-<stamp>.log next to the bat) carries the EVM address line and the full miner command line.

If the worker's ready event says "no hot swap (nvcc missing)", nvcc is not on the PATH of the launcher: the old exit-42 path rebuilds the worker at the boundary (about 30 s of no mining per hour), nothing else changes.

(e) Checks

Check Command (Mac) Expected
node 1 peers vendor/igneum-node/target-integration/release/igneum-miner watch 1 grpc://127.0.0.1:26610 peers=2 (seed and PC), synced=true, blocks climbing about 1 per second once the PC mines
PC synced, blocks flowing the PC dashboard NODE card: synced, blocks equal to the Mac's within a few blocks; chain N blocks/s near 1.00 the Mac's watch line shows the same sink as the PC's launcher log status block
seed synced infra/seed-nodes/health.sh OK ... unit=active-v4 rpc=yes synced=True blocks=<same as node 1> peers=1..2
live page https://igneum.network/live LIVE dot, the strip (blocks, miners, difficulty, peers) counting from the new genesis, the finality lock markers appear only after the first lock (next row)
first checkpoint lock IGNEUM_RPC=ws://127.0.0.1:28640 python3 infra/cloud-devnet/node/wrpc.py call getFinalityCheckpoints "window filling, N of 7,200" until the sink's DAA score reaches 7,200: the devnet weight window and min_daa are 7,200 DAA seconds, which is TWO HOURS of chain time after the v4 genesis (finality.rs DEVNET). The first lock lands at the first checkpoint whose DAA score is at least 7,200: expect it about 2 h after the chain starts, and observer.mjs then emits "checkpoint N locked (xx% of weight)" and the live page draws the lock marker. Locks every 30 s after that
hourly program swap the PC events at the first boundary (DAA 3,600, about one hour after the v4 genesis; the pack for the next program is written 600 DAA s, 10 minutes, before it) "the next hourly program is compiled and resident (hot swap ready)" about 10 minutes before the boundary, no miner restart at the boundary, hash rate unbroken. On the Mac miner's log: prepared ... then jobs on the new seed. Test-network numbers: first block of the new epoch accepted 0.5 to 2.2 s after the last of the old (fork-divergence)
EVM smoke cd tools/evm-smoke && IGNEUM_RPCS=http://127.0.0.1:26790 IGNEUM_MINER_KEY=<the private key of an --evm-address that has mined> node smoke.mjs SMOKE SUMMARY: 84 checks passed, 1 failed is the known result (the one failure wants duplicate sends in parallel blocks and a PoW network with one tip rarely offers any); fewer passes means the execution layer is not running. The quick check without a key: curl -s -X POST http://127.0.0.1:26790 -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' returns "0x116f" (4463) and eth_blockNumber climbs

Shorter finality window for the first day (optional). The two-hour wait is the window filling; to see locks sooner, every node on the network must carry the same override file (it is a consensus parameter, so node 1, the observer peer, the seed and the PC all need it, and a node without it rejects nothing but certifies on a different schedule, which the lock rule treats as disagreement). The override file, with every finality field present (the parser takes the whole object):

{ "finality": { "checkpoint_interval": 30, "checkpoint_depth": 20, "weight_window": 1800, "dust": 5,
                "presence_window": 20, "aggregators": 8, "equivocation_ban": 1800, "min_daa": 1800, "aggregator_fallback": 15 } }

Flag on every node: --override-params-file=/path/override.json (Mac: in the two nohup lines above; PC: EXTRA_ARGS at the top of START-IGNEUM.bat, for example --override-params-file=C:\igneum-v4\override.json; seed: EXTRA_ARGS= in /etc/igneum/seed-v4.env, then systemctl restart igneumd-v4). 1,800 DAA s = 30 minutes to the first lock. The recommendation is to leave the default (7,200) and let the first lock arrive two hours in: that is the rule the network will run and the window is the test. The 300-DAA window of the integration test was the same mechanism.

(f) Rollback to v3 (two commands per machine)

Mac (node 1; the observer peer and observer.mjs the same way with their v3 commands from docs/fork-divergence.md):

pkill -INT -f 'target-integration/release/igneumd --devnet --nodnsseed --disable-upnp --enable-unsynced-mining --appdir=/tmp/igneum-devnet/node1'; sleep 3; mv /tmp/igneum-devnet/node1 /tmp/igneum-devnet/node1-v4-abandoned && mv /tmp/igneum-devnet/node1-v3-2026-10-04 /tmp/igneum-devnet/node1
cd vendor/igneum-node && nohup caffeinate -dims ./target/release/kaspad --devnet --nodnsseed --disable-upnp --enable-unsynced-mining --appdir=/tmp/igneum-devnet/node1 --rpclisten=0.0.0.0:26610 --listen=0.0.0.0:26611 --addpeer=192.168.68.67:26611 --nologfiles > /tmp/igneum-devnet/node1-v3-again.out 2>&1 &

(pkill -f with the full v4 command line only, never a bare name: the observer peer and the relay must not match.)

Seed: infra/seed-nodes/switch-v4.sh igneum-seed-1 --back (stops igneumd-v4, starts igneumd on the untouched /var/lib/igneum).

PC: Ctrl+C in the v4 window, then START-IGNEUM.bat in the OLD folder (its igneumd.exe, igneum-miner.exe and %LOCALAPPDATA%\igneum\devnet are untouched).

Mac app users: the 0.1.0 app and its devnet data folder are untouched by 0.2.0.

What the old chain's data means

Nothing is lost. The v3 chain (3 October, 12,000+ blocks, the finality v2 locks, the hash-rate measurements) stays in /tmp/igneum-devnet/node1-v3-2026-10-04 on the Mac, /var/lib/igneum on the seed, %LOCALAPPDATA%\igneum\devnet on the PC and ~/Library/Application Support/Igneum/devnet on any Mac that ran 0.1.0. The v3 binaries (target/release/kaspad, target-finality/release/igneumd, the old zips and Igneum-Miner-0.1.0.dmg) can read it. The live page's v3 rows stay in the live_* tables unless LIVE_TABLE_PREFIX=v4_ is set (then both chains keep their rows apart). The v3 chain is kept aside for reference and rollback; it is not deleted by any step above. The v4 chain starts again from the same genesis with block numbers from 0, so comparisons across the cut (block counts, DAA scores, difficulty) restart as well.

Untested before the morning

Item Why
Windows package on the PC no Windows machine on the Mac side; the PowerShell edits are checked by hand and by a bracket and quote balance pass (no pwsh on this Mac: the Homebrew cask is unavailable), not parsed by PowerShell. The CUDA worker's hot swap (host.cu with prepare, uncommitted working tree) has not run on the PC either; the exit-42 rebuild path stays underneath it
Mac app sync and mining tested on this Mac with MINERS=0 on ports 28900/28901 against a dead peer (launch, version line, EVM address line, node up, Terminal title escape, --stop in 4 s, ports free, live devnet untouched); no v4 node was running, so sync and the Metal miner were not exercised by the 0.2.0 bundle (the same binaries mined on the integration test network)
Seed v4 unit built and installed, never started; switch-v4.sh is new code, its rollback too
First lock and the hourly swap on the real devnet values 7,200 and 3,600 DAA; only the 300/60 test values ran