igneum/docs/plans/testnet-go.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

137 lines
21 KiB
Markdown

# Igneum public testnet: the go checklist
Prepared 5 October 2026 by the infrastructure and consensus engineer for the 19:00 BST (18:00 UTC) opening. State of
every line as of 16:05 UTC. Nothing mines until the owner says go; the seeds hold the chain at height 0.
## What runs now
| Piece | Where | State at 16:05 UTC |
|---|---|---|
| `igneum-testnet-1` seed 1 | `seed1.testnet.igneum.network` = 195.201.35.33, Hetzner cx23, Nuremberg (nbg1), Debian 13 | up, unit `igneumd` active, p2p 26811 open, 2 peers, height 0, sink = genesis |
| seed 2 | `seed2.testnet.igneum.network` = 5.161.232.205, Hetzner cpx21, Ashburn (ash), Debian 13 | up, 2 peers, height 0 |
| seed 3 | `seed3.testnet.igneum.network` = 5.223.52.210, Hetzner cpx22, Singapore (sin), Debian 13 | up, 2 peers, height 0 |
| Public JSON-RPC | `https://rpc.testnet.igneum.network` (seed 1: nginx, Let's Encrypt, 20 req/s per address with a burst of 40, 20 connections per address, bodies to 256 KiB, then `rpc-filter.py` on 127.0.0.1:8545, then the node's EVM RPC on 127.0.0.1:26890) | live: `eth_chainId` = 0x116e (4462), `eth_blockNumber` = 0x0, `net_version` = 4462; `admin_peers` and `igneum_submitProofRecord` refused with -32601 |
| DNS | deSEC (`ns1.desec.io`, `ns2.desec.org`), A records for the three seeds and `rpc.testnet`, TTL 3600 | all four resolve from the authoritative servers |
| Firewalls | `igneum-testnet-seed` (22, 26811, icmp) on all three; `igneum-testnet-rpc` (80, 443) on seed 1 only | applied |
| The node binary | `igneumd 1c19441d` (fork branch `testnet-infra`), built on PC 1 by build job `build-20261005-154330` (WSL2 Ubuntu 24.04, glibc 2.39), sha256 `a9ea25f8ada29e3ee1dfc2ccced4e088a56237511be75d5d80f7bb7a72414b10` | on every seed as `/opt/igneum/bin/igneumd` |
| Mining | none | nothing mines; no `--enable-unsynced-mining`, no miner process anywhere on the testnet |
Each seed's start-up log, identical on the three:
```
Fees on igneum-testnet-1: pgas table v1, B_p 120000 pgas, S_p 30000 pgas, floors 100000000000 wei per gas and 10000000000000 wei per pgas; calibrated v1 from DAA score 0
Consensus params digest: b7d8c915f20f5af261e69e7f4aa9c3d03a9c4a462174776502b63fa1e9ec8447 (exchanged in the p2p handshake; a peer with another digest is refused)
igneumd/2.1.0
[igneum-exec] genesis 87617621714af1bf33bd17f291f90a7e0bff760a669bba53083ea8c0f7cbd840 executed: chain id 4462, registry at 0x0000000000000000000000000000000000000210
```
`health.sh` shows `synced=False` on all three: that is the no-blocks state (a node is synced once it has blocks past
genesis), not a fault. The check: `cd infra/seed-nodes && NET=testnet ./health.sh`.
## The genesis, final
| Field | Value |
|---|---|
| Network | `igneum-testnet-1`, chain id 4462, address prefix `igneumtest`, ports 26810 (gRPC), 26811 (p2p), 28810 (wRPC JSON), 26890 (EVM JSON-RPC) |
| Coinbase message | `igneum-testnet-1 \| 2026-10-05 \| coins here have no value \| resets are announced` ("proposed, not final" dropped before the first public node) |
| Timestamp | 1,791,158,400,000 ms = 2026-10-05T00:00:00Z |
| Bits | `0x1d100000` |
| Hash | `87617621714af1bf33bd17f291f90a7e0bff760a669bba53083ea8c0f7cbd840` |
| Merkle root | `44acfc40b1c6647011510f3c39ddb7606f979df92ad26a2914de56e44610efad` |
| Consensus digest | `b7d8c915f20f5af261e69e7f4aa9c3d03a9c4a462174776502b63fa1e9ec8447` |
| Fees | `CALIBRATED_V1` from DAA 0 |
| DNS seeders in `TESTNET_PARAMS` | `seed1.testnet.igneum.network`, `seed2.testnet.igneum.network`, `seed3.testnet.igneum.network` |
| `--netsuffix` | defaults to 1 under `--testnet` |
The proposal's hash `52a3e6a9...` is void: it hashed the old message. Any node built from a fork commit before 1c19441d
has the old genesis and never completes a handshake with the seeds (different genesis, different digest).
## Branches and commits (nothing pushed, nothing merged)
| Repository | Branch | Head | What |
|---|---|---|---|
| node fork (`vendor/igneum-node-testnet-infra`, from `release-0.3.6` 2b6d23ef) | `testnet-infra` | 1c19441d | final genesis message, hash and merkle root; `--netsuffix` default 1; the three DNS seeders; `igneum_testnet_identity` and `test_genesis_hashes` updated |
| app repository (`igneum-wt-testnet-infra`, from master 23d11d5) | `testnet-infra` | 358e565 | `infra/seed-nodes`: `NET=testnet` profile, `seeds-testnet.tsv`, `dns.sh`, `rpc/` (filter, unit, nginx site), `node/install-rpc.sh`, `install-rpc-from-mac.sh`, ports from `seed.env`, glibc check, debian-13 images, quoted env values; `tools/build-job.mjs` forwards `--node-tests`/`--app-tests` and its watcher reads the SUMMARY wherever it sits; `docs/testnet/README.md` final genesis; this file |
| app repository (`igneum-wt-testnet-app`, from `testnet-infra` 9fa2bb3) | `testnet-app` | c00df85 | the app's network setting: `Packaged.network/peers/public_rpc`, `Network` enum with the testnet's ports, seeds and node directory, `Runtime::from_env_and_packaged`, the dashboard's chain label `testnet-1` with the public RPC on its tooltip, the testnet node keeps its DNS seeders; `packaged-config.sh` `IGNEUM_PACKAGE_NETWORK` (default testnet; the fleet's devnet builds pass `devnet`) |
| app repository (`igneum-wt-testnet-wallet`, from `wallet-v1` a238781) | `testnet-wallet` | fe6e5e8 | `igneum-common`: `Packaged.network`, `TESTNET_PUBLIC_RPC`, `chain_id`, `effective_public_rpc`; the wallet engine reads the effective URL; the wallet's packaged config follows `IGNEUM_PACKAGE_NETWORK` |
Tests: `kaspa-consensus-core` and `igneum-app` suites on PC 2, build job `build-20261005-155547`, both exit 0
(cargo's own status; the relayed log keeps only the last `test result` line). `cargo test -p igneum-common` on the
Mac: 27 passed (the crate is not in the PC build inputs). The packager's self-test: all checks passed on both branches.
`cargo check --tests` of the app on the Mac: clean.
## The go: what the founder presses, in order
| # | Step | Who presses | State at 16:05 UTC |
|---|---|---|---|
| 1 | Seeds up at height 0, peered, the public RPC answering | nobody (done) | DONE: three seeds, 2 peers each, RPC live |
| 2 | Merge `testnet-infra` and `testnet-app` to master; the fork's `testnet-infra` into `release-0.3.6` (or the release branch the 0.4.0 cut uses) | the release engineer, on the founder's word | NOT DONE: branches ready, nothing merged |
| 3 | Cut 0.4.0 from `testnet-app` (`tools/ship-app.mjs 0.4.0 --node vendor/igneum-node-testnet-infra ...`); the Mac DMG, the Windows installer through the PC build job; the packaged file must say `"network": "testnet"` (the default) | the release engineer | NOT DONE: the packager writes the testnet by default; the fleet's devnet update, if any, needs `IGNEUM_PACKAGE_NETWORK=devnet` |
| 4 | The prover's fee-table mirror at `CALIBRATED_V1` (`proving/igneum-prove/core/src/config.rs`, `pgas.rs`; `docs/plans/release-0.3.6.md` section 5 step 6): on the testnet fees are v1 from genesis, so a prover with the prototype table produces shard statements the node refuses. Needed before the first testnet proof, not before the first block | the execution engineer | NOT DONE |
| 5 | History rewrite (`docs/plans/history-rewrite.md`, G14: the 40 commits with a personal name) | the founder, then the repository goes public | NOT DONE |
| 6 | Repository public (`gh repo edit igneum-network/igneum --visibility public`) | the founder | NOT DONE |
| 7 | Downloads public: the 0.4.0 manifest in the downloads folder, `publish-manifest.sh --deploy` | the release engineer | NOT DONE |
| 8 | The site's buttons: the download section points at 0.4.0, `site/wallet.html` carries `https://rpc.testnet.igneum.network` and chain id 4462 in place of the placeholder, the terms card (`#testnet-terms`) stays; `node site/build.mjs`, push to master (Vercel deploys) | the site agent | NOT DONE: the placeholder is still in `site/wallet.html` |
| 9 | Announcement text | the founder | PLACEHOLDER: "Igneum testnet-1 is open. Coins here have no value. Resets are announced seven days ahead. Download: igneum.network. RPC: rpc.testnet.igneum.network, chain id 4462." (the founder's words replace this) |
| 10 | The first miner: one app on the testnet (PC 1 or PC 2 with the 0.4.0 build, or `igneumd --testnet` plus `igneum-miner --network testnet` by hand) produces block 1; the seeds relay it, `health.sh` shows blocks=1 on all three, `synced=True` | the founder says go, the miner-community lead starts it | NOT DONE: nothing mines until the word |
| 11 | Watch: `NET=testnet ./health.sh --watch`, the RPC's `eth_blockNumber`, the DAA after 600 blocks (the launch difficulty `0x1d100000` is sized for a few hundred MH/s) | the infrastructure engineer | ready |
Legal is out of scope here (the founder: "all but legal").
## Cost
| Item | USD per month, net (Hetzner API, 5 October 2026) |
|---|---|
| seed 1, cx23 nbg1 | 6.49 |
| seed 2, cpx21 ash (4 GB; the only 4 GB type in the US at this price) | 37.49 |
| seed 3, cpx22 sin | 30.99 |
| three primary IPv4 | 1.80 |
| total | 76.77 net, about 92 gross; billed hourly, 20 TB traffic included per server |
A cheaper US seed is cpx11 (2 GB, 20.49), rejected because the node keeps up to four 256 MiB lottery caches once
the chain has epochs; the unit's `MemoryMax=3200M` would not fit. The devnet seed (`igneum-seed-1`, 6.49) is untouched.
## What was not done, and what to watch
| Item | Note |
|---|---|
| The explorer | not built; the public RPC serves the wallet and MetaMask |
| `site/wallet.html` RPC placeholder | still a placeholder; step 8 |
| The Windows WSL verifier wrapper, the prover's table mirror | `docs/plans/release-0.3.6.md` section 7; step 4 above |
| The app's Windows side | `testnet-app` compiles on the Mac and its suite passed on PC 2 (Linux); the Windows build is the 0.4.0 cut's job |
| Seeds and proofs | the seeds run no proof verifier (`verifier: Off`); they relay and hold the chain. A seed never includes proof records, which is fine for a seed |
| Build inputs zip | `build-inputs.zip` on the downloads host is ONE file for every agent: a second agent's push between a job's publish and its fetch fails that job's sha256 check. Both testnet jobs fetched the right zip (verified by sha256 before each fetch); the hazard stays until the zip carries the job id in its name |
| glibc | a PC-built Linux binary wants glibc 2.39 (Ubuntu 24.04); the seeds are Debian 13 (2.41) for that reason, and `provision-seed.sh` now refuses a binary the seed cannot run. The Mac's zig cross-build (glibc 2.36) stays the route for a Debian 12 host |
## How to redo any part
```
cd infra/seed-nodes
NET=testnet ./health.sh # one line per seed
NET=testnet ./dns.sh --check # the four A records
NET=testnet BUILD_WHERE=cross ./provision-seed.sh seed2.testnet # re-install the node from infra/cross/out (a new binary)
NET=testnet ./install-rpc-from-mac.sh seed1.testnet # the public RPC again (idempotent; certbot keeps its certificate)
```
The node binary for the seeds: `node tools/build-job.mjs run --node /Users/joshm/Projects/igneum/vendor/igneum-node-testnet-infra --target ae432dc7 --targets linux --no-tests`
then `node tools/build-job.mjs fetch <id>` (lands in `infra/cross/out/`).
## Launch gates (mission item 10, 7 October 2026, 10:1x UK)
Added by the launch-pack lane (branch `launch-pack`) from `docs/analysis/mission/mission.md` 2.10, with the owner's three decisions of the same morning written in: a signed proving customer is a MAINNET gate (not a testnet gate); the code-signing certificates are approved (Windows EV Authenticode and an Apple Developer organisation account, both under Igneum Labs LTD, executed the day the entity exists); the USD 50,000 disclosure prize is YES, staged until the entity address exists and the owner gives the publish word (`docs/plans/cryptanalysis.md` 3.3 on branch `cryptanalysis`). The runbooks, the signing-step specification and the text handed to the site lane are in `docs/plans/launch-pack.md`. Every row has its check; `node tools/ci/launch-gates-check.mjs` (in `tools/ci/pre-push.sh`) fails when a row loses it or names a script that is not there. "When" says which go the gate holds: T = before the testnet go (steps 1 to 11 above), C = a community gate after the go with no date (`docs/analysis/mission/reinvent.md` 4.1), M = before the mainnet go.
| Gate | What must be true | Check | When | State at 10:1x UK, 7 October 2026 | Who |
|---|---|---|---|---|---|
| LG-1 Per-tier income at three tariffs | `docs/analysis/income-tiers.md` is published before the testnet: one 8, 12, 16, 24 or 32 GB card, a rig and a pool user, IGN a day at three network sizes from the measured bench rows and `EmissionSchedule::TESTNET_1`, electricity a day and per mined IGN at USD 0.05, 0.10 and 0.25 a kWh (cheap industrial, US retail, UK retail; decided 7 October 2026), each tier with what it means and what is being done (the consequences rule) | `node tools/launch/income-tiers.mjs --check` (the page equals its inputs) and `node --test tools/launch/income-tiers.test.mjs` (the schedule arithmetic: 6,912 IGN a day for 100 MH/s on 100 GH/s at the launch rate, day 1 at 10 percent, one month step at 2^(-1/24)); the page is in the public export and passes `tools/ci/identity-check.sh` | T | DONE on the branch from the 6 October rented-card rows (ten-field class). OWED: re-generate at the testnet cut from class v4 rates; the RTX 4060 and Apple wall power; an Intel row | launch-pack lane, then whoever cuts 0.4.0 |
| LG-2 Hash-origin report on Devnet 2 for seven days before the go | The daily report (keys with a block, keys above dust, attested pools and shared payouts, the project fleet's share, the ten largest keys, the network step) posts from the Devnet 2 observer's tables on seven consecutive days before step 10 | `node tools/observer/hash-origin.mjs --prefix dn2_ --dry` prints a report; seven consecutive `hash-origin:<date>` keys in the poster's state for that prefix; `node --test tools/observer/hash-origin.test.mjs` (a known-finished day and a known-failed day) | T | The job exists and ran read-only on the live devnet tables today (113 keys, 0.76 GH/s). OWED: a Devnet 2 observer writing `dn2_live_*` (fleet lane), the fleet key file from the fleet registry, the systemd timer on the box (`docs/plans/launch-pack.md` section 3) | launch-pack lane (job), fleet lane (observer, key file), build-server lane (timer) |
| LG-3 Signed and notarised installers | The 0.4.0 DMG is signed with a Developer ID certificate of Igneum Labs LTD, notarised and stapled, and opens on a fresh macOS machine with no Privacy and Security visit; the Windows installer and every exe inside it carry an EV Authenticode signature of Igneum Labs LTD with a timestamp | `spctl --assess --type execute -vv <app>` prints `accepted` and `source=Notarized Developer ID`; `osslsigncode verify <installer>` (or `signtool verify /pa /v`) prints the signer `Igneum Labs LTD` and a timestamp; the shipper's `verify` step writes both into the manifest (`signed_by`, `notarized`) and the download page shows the signer and the sha256 (`docs/plans/launch-pack.md` section 2.4) | T | NOT DONE: certificates approved 7 October; the entity's documents and the two enrolments are the owner's (section 2, items for the owner); the signing step is a specification for the shipper (`docs/plans/launch-pack.md` 2.4) | the owner (enrolments), the shipper (the step) |
| LG-4 First-share time measured per release | Every release's Devnet 2 gate measures download to first accepted share on a fresh Windows 11 VM and a fresh macOS VM, as three timed steps (download and install, sync, dataset build), and the numbers are published on /evidence; the mission's bar is under 10 minutes in 9 of 10 fresh Windows installs | the gate log carries `FIRST-SHARE <platform> download=<s> sync=<s> dataset=<s> share=<s>` for both platforms (`docs/plans/launch-pack.md` 2.5 is the specification of the script that writes it, tools/fleet/first-share-time.sh, OWED: until it exists this row is OPEN); the /evidence row equals the log line | T | OWED: specification written, script not built; no fresh-machine time has been measured end to end (`docs/analysis/mission/reinvent.md` 3.1) | fleet lane with the shipper |
| LG-5 The launch text on the site | The front page leads with the three wants (hardware that stays useful, income without a cliff, a fair supply) and finality moves to page two; the litepaper carries "A block pays its miner whether or not anyone buys a proof that day"; the eight regulatory sentences of `docs/analysis/mission/future.md` 8.3 are on the litepaper under "not legal advice; counsel is engaged"; the journey's phase 4 gate no longer says a rollup signs for the testnet | `node tools/ci/launch-gates-check.mjs` (the handoff block exists, carries no served-page pattern, no em dash, the eight sentences numbered in order); after the site lane lands it: `grep -c "whether or not anyone buys a proof" site/litepaper.html` is 1 and `grep -c "automatically created as a reward" site/litepaper.html` is 1 | T | Text handed over in `docs/plans/launch-pack.md` section 4 (branch `launch-pack`); nothing on the live site changed | site lane |
| LG-6 First 100 keys | 100 distinct vote keys with a blue block in the last 24 h | the hash-origin report's `gates.first_100_keys` (`node tools/observer/hash-origin.mjs --dry --json`) | C | Devnet reading today: 113 keys with a block, most of them the project's multi-identity machines; the testnet counts from its own go | the report |
| LG-7 First block from a card the project does not own | A blue block whose vote key is in neither the intake-reporting workers' identity lines nor the fleet registry's key file | the report's `gates.first_block_outside_fleet`, valid only with `IGNEUM_FLEET_KEYS_FILE` loaded (without the file the devnet reads its own rented boxes as outside: today 77 "outside" keys, which is the missing file, not outsiders); the post needs the owner's permission (reinvent.md 4.1 G-C2) | C | Void until the fleet key file exists (OWED, fleet lane) | the report, the fleet lane |
| LG-8 First outside-reproduced benchmark | A row on /miners measured by someone outside the project, with driver, OS and version (`docs/benchmarks/repro.md`) | `grep -c '"by": "reported by a miner"' site/miner-bench.json` is at least 1 (today the rows are `measured by the team` and `reported by the fleet`) | C | No such row | the community lead (the bench-table ingest) |
| LG-9 First pool not run by the project | An attested outside pool (its operator published the signed member-key list X5 asks for) with 10 percent of blue blocks for 7 consecutive days | the report's `gates.first_outside_pool` with the pool's payout address in `IGNEUM_KNOWN_POOLS`; a shared payout address nobody attested never passes it (the test's third case) | C | No attested outside pool; the devnet's 13 shared payout addresses are multi-identity machines and the project's pool-0 | the report, the pool lane (the statement format) |
| LG-10 First 1,000 independent keys (X5) | N_ind of at least 1,000 over 30 days, independent in autonomous system, machine fingerprint and pool attestation, top-10 share of window weight under 50 percent (`docs/plans/ledger-decisions.md` section 3) | the report's `independent` block once the observer stores the autonomous system per announcing address and the fingerprint per key; until then the report prints the keys above dust as an upper bound and never passes the gate (`gates.first_1000_independent` is false by construction) | C, and the gate of mainnet genesis | The two observer columns are OWED (app-owner item, ledger-decisions.md section 3); today's upper bound on the devnet is 95 | the observer owner |
| LG-11 A signed proving customer | One customer paying for proofs at a published rate, or a signed letter of intent with a volume, before mainnet (the owner, 7 October 2026: a mainnet gate, not a testnet gate; the weight of the Devnet 2 gate: mainnet does not open without it) | the contract or the letter in the entity's records, a redacted copy linked from `docs/evidence.md`, the rate on the site; for the paying case the job market's payout contract shows a paid job for that customer; `grep -c "rollup signs for testnet" site/journey.json` is 0 after the handoff lands | M | NOT DONE: Taiko is named as the first customer and nothing is signed; the brief and the pilot progression are ledger X13 | the owner (the signature), the execution engineer (the paid job) |
| LG-12 Hash origin daily for 90 days | The report posts every day for the first 90 days from the go, with no gap | `SELECT count(*) FROM hash_origin_reports WHERE day >= '<go date>'` reaches 90 with consecutive days; the timer's journal on the box shows a run per day | C | The job and its `--go <date>` flag exist; the timer is OWED (section 3 of the pack) | build-server lane (timer), the report |
| LG-13 The disclosure prize | USD 50,000 for a reproduced break of the published hash class, paid in fiat by Igneum Labs LTD, announced only when escrowed and only when the entity's registered address exists on its documents and the owner gives the publish word | `docs/plans/funding.md` rule 3 (escrow before announcement); the staged text in docs/plans/cryptanalysis.md 3.3 on branch `cryptanalysis` (43d9700b, not on master yet); until the word, `grep -ci "50,000" site/*.html` is 0 | M (the announcement may come earlier, on the word) | APPROVED by the owner at 09:5x UK on 7 October 2026; STAGED; nothing public mentions it | the owner (escrow, the word), the cryptanalysis lane (the announcement) |