doc: mainnet cutover runbook for 2026-09-10

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CBgs2nSi4H2mdh8kD8vMX5
This commit is contained in:
Rob Thijssen
2026-09-09 08:06:25 +03:00
parent 7a7090b28b
commit f47efadc9b

65
doc/mainnet-cutover.md Normal file
View File

@@ -0,0 +1,65 @@
# Mainnet cutover runbook
Launch announced for **2026-09-10 09:09 UTC** (12:09 EEST). The foundation's
sequence: node binary release on GitHub, genesis hash published, their
bootnodes up, then chain spec + bootnodes + verification instructions shared,
then a later release with the spec embedded. Nothing of ours is switched until
the genesis hash and chain spec come through the official channel.
Keys: the planck reward key (bob's `inner_hash` in the deploy matrix) is reused
on mainnet — decided 2026-09-09.
## Before the announcement (done 2026-09-09)
- lair/quantus#24: node deploy runs from a chain spec file, asserts the genesis
hash, prints the spec id, dials bootnodes as reserved peers, out/in peers
32/64. Soaked on planck overnight.
- quantus/miner#19: miner deploy takes a `chain` input for the credential path.
- bob's sudoers grant the runner `/etc/quantus-node/chainspec.json`.
## Cutover, in order
1. **Collect** from the official channel: release version `vX.Y.Z`, chain spec
URL, genesis hash, bootnode multiaddrs. Verify the spec the way their
instructions say (checksum against the release). Do not proceed on a
spec or hash from anywhere else — see their scam warning.
2. **Node.** Dispatch lair/quantus `deploy` with:
- `mode`: deploy
- `node_version`: `X.Y.Z` (no `v`)
- `chainspec_url`: the spec URL
- `expected_genesis`: the published 0x hash
- `bootnodes`: the multiaddrs, space-separated
Validate must print `genesis matches expected` and
`miner credentials present under chains/<id>/`. A genesis mismatch rolls
back to the previous binary and config, and planck resumes. Note `<id>`.
3. **Miners.** Dispatch quantus/miner `deploy` with `chain: <id>`. The binary
is unchanged; the new token and TLS pin trigger the checksum-gated restart.
Validate waits for the miner to connect and for the hash counter to move.
A wrong `<id>` shows within a minute as a restart loop on benjy and
quadbrat (permanent connection error on certificate mismatch).
4. **beast** (if joining): stop `neuron.service` on beast, uncomment the beast
row in quantus/miner's deploy matrix, merge; the push deploys it.
5. **Commit the values** so push-triggered deploys keep them: in lair/quantus
`deploy.yaml` set `CHAIN: <id>`, `NODE_VERSION`, `CHAINSPEC_URL`,
`EXPECTED_GENESIS`, `BOOTNODES`; in quantus/miner `deploy.yaml` set
`CHAIN: <id>`. Once the foundation ships the release with the spec
embedded, `CHAINSPEC_URL` can go back to empty with `CHAIN` as the built-in
name, keeping `EXPECTED_GENESIS`.
6. **Watch**: the arena dashboard follows the new genesis on its own (the
exporter discovers it from the node). If `quantus_telemetry_up` drops or
the node population looks like planck's, the feed URL differs for mainnet:
update `TELEMETRY_URL` in `deploy.yaml`.
## What does not change
- Miner binaries: a node upgrade on the same chain is invisible to them (they
reconnect with a 130 s backoff). Only the chain switch needs step 3.
- The arena exporter, Prometheus rules and dashboards. Leaderboard history
simply starts over at the new genesis; attribution state is kept on disk.
## Rollback
The node deploy keeps `quantus-node.prev` and the previous `node.env`; a
failed validate restores both and restarts. Miners stay on planck credentials
until step 3 succeeds, so a failed node cutover leaves them idle-reconnecting,
not mining a wrong chain.