igneum/CLAUDE.md
igneum-josh 179317c122 Kill by exact command line or pid file, never by a name: tools/ci/kill-by-name-check.sh in the gate; the 36 pgrep/pkill literals in the tree fixed
The fleet's 22:09 UK incident (a Mac-side pkill -f <log file name> matched nothing, the roll-everything script lived on and wiped a held box) and the day's two pgrep self-matches are one class. The check flags pgrep -f / pkill -f with a plain literal (every one on a line), any pgrep/pkill on a file-name shape, and ps | grep with a literal; it allows the bracket form, -x, -F pidfile, kill $(cat pidfile), a variable and a full path; 11 banned and 16 allowed shapes in its self-test; 0.15 s over the tree. The 25 pkill -f sp1-gpu-server inside bash -c bodies (which matched the calling bash) are pkill -x; the other 11 literals take the bracket form; prover-socket-check accepts both. Row R in the record; the CLAUDE.md rule names the check and covers pkill and file names.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-06 23:10:31 +01:00

23 KiB

Igneum

A GPU-mined layer 1 whose miners are also the ZK provers for its own zkEVM and for other chains. Josh Malone's project, started 3 October 2026. Named Igneum (Latin: fiery, proven by fire) on 3 October 2026. Repo, Vercel project and Neon database are all "igneum".

Source of truth

The design document (Claude Doc "Igneum", formerly "GPU Prover Network") plus the public litepaper (https://claude.ai/code/artifact/edcf47f6-e918-48c7-95c3-b98e0d65583f) and the brand canvas (https://claude.ai/artifact/CPixnvctTKbrwBwWck3iFj): https://claude.ai/code/artifact/08fa9e06-9240-4964-96f4-76ff1d2f796c Read it with the docs tools before any design discussion. Decisions already taken live there (hard cap 4 billion halving every two years, 80/20 lottery/proving split, NO emission treasury, NO dev fund (removed 3 Oct 2026: the protocol carries no fee to any team, foundation or fund; priority fee 80/20 miners-and-provers/app, external jobs 90/10 provers/burn, 60% signalling kept only for parameters genesis leaves to miners), no stake, miner-only self-contained finality (NO Bitcoin anchoring), 1 block/s at launch, SP1 behind a swappable proving interface, Taiko as first proving customer, 30-day launch ramp).

The design in one paragraph

Leader election by a random-program GPU hash (RandomX idea rebuilt for GPUs, new kernel each ~1h epoch, era parameters drawn automatically every 6 months from chain state inside rules fixed at genesis, NO scheduled human releases; dataset grows on a genesis-fixed schedule and instruction families unlock by height from a genesis reserve (automatic schedule changes against fixed datapaths and human forks; against a chip that stores the dataset every drawn parameter is firmware, and the defence is the latency-shadow work of class v4 and the price per joule, per the Horizon algorithm lane, 6 October 2026); only writing new code is human, via miner signalling (the three thresholds, one sentence everywhere: 60% for a parameter, 90% for an upgrade, 95% with a floor height for a class change, the P2 mechanism), never required; warp-unit CPU-verifiable). Ordering by a GHOSTDAG BlockDAG forked from rusty-kaspa. Execution by a zkEVM. Every block ZK-proven by miners in chunks, aggregated 20 to 60 s behind the tip at launch (target under 10 s as provers improve). Finality is miner-only and self-contained: FINALITY RULE V2 (review round 2, 3 Oct 2026): vote weight = blue blocks per BLS vote key (in header) over a flat 30-day DAA window, no damping (the 2x cap was Sybil-void), dust threshold 100 blocks; every voter signs every 30-s checkpoint (VRF picks 8 aggregators only); lock = 2/3 of ALL 30-day weight (DECIDED 4 Oct 2026, O-3.15: the floor was raised from 56.7% of total to 2/3 of total, which makes the 2/3-of-active test implied; finality pauses whenever under 2/3 of the window is connected and signing, and the node reports it; the old floor 0.85 x 2/3 had been added after sim v2 showed the bare active denominator locks both sides of a 50/50 partition after 60 min; with the floor: 0 conflicting locks in every partition and eclipse scenario); equivocation evidence strips weight 30 days; fork choice = GHOSTDAG among tips through all certified checkpoints under Kaspa merge-depth 3,600 s; NO hidden-block n^2 penalty (removed, breaks DAG determinism); epoch seed = 10-min class-group VDF of a certified checkpoint, era draw = 1-h VDF; dataset = 256 MB RandomX-style cache, 8 dependent reads per item (not closed-form, not 64 MB); fees: base fee burned in full on both gas dimensions, priority fee 80/20 (miners and provers / app, attributed per call frame, unregistered share burned), external jobs 90/10 (provers / burn), no dev fund and no fee to any team. Headline: 10 days of 100% hashrate to reach 1/3 of weight, 20 days for 2/3; 51% never reaches 2/3 while honest miners stay. NO stake and NO other chain anywhere in consensus (Bitcoin anchoring was considered on 3 Oct 2026 and REJECTED by Josh: no reliance on Bitcoin). The same prover network sells proofs to rollups and bridges, priced in dollars, settled in the token. The lottery and the proving are kept separate on purpose (Aleo lesson).

The team, as agents

Each role from the design doc's build plan is an agent in .claude/agents/. Ask them by name.

  • cryptographer: lottery hash, chunked proving protocol, proof systems, finality on a DAG. Owns gates 1 and 3.
  • consensus-engineer: Rust, rusty-kaspa fork, GHOSTDAG, difficulty, P2P, the hash swap. Owns gate 2.
  • execution-engineer: Rust, Ethereum clients, zkEVM integration, SP1, the proving interface, external job market.
  • miner-community-lead: miner software, pools, launch ramp, what GPU miners will and will not accept. Owns gate 4. They review each other's work. A claim about another chain must cite the repo and file, or be labelled approximate.

Rules that apply to every agent and every file here

  • Josh's copy law: no em dashes, no two-beat antithesis, no aphorisms. Short sentences. Numbers in tables.
  • Figures from memory are labelled approximate. Figures from a source cite the source.
  • The project is Igneum. Never claim an ASIC gain, a proving time or a market size without a measurement or a citation.
  • Vendor source lives in vendor/ (git clones of rusty-kaspa, RandomX, SP1, decred dcrd, etc.). Read real code before describing it.
  • Nothing here is a token sale and nothing should become one.
  • Transactions are public, like Ethereum. Privacy features and shielded pools were considered and REJECTED by Josh on 3 October 2026. Do not add them.

Infrastructure (no URLs yet, by Josh's instruction)

  • GitHub: https://github.com/igneum-network/igneum (organisation igneum-network, created 3 Oct 2026; owners igneum-josh (Josh, the igneum.network Google login) and joshmalone117; private, branch master). Commit as igneum-josh 337424239+igneum-josh@users.noreply.github.com (the repo's git config; standing rule 3 Oct 2026: the organisation owner is never publicly visible, so no personal name or email in the history; the 40 commits before this rule carry Josh's name and must be rewritten before the repo goes public). Push only when Josh asks. RENAMED 5 October 2026 (18:00 UTC, by Josh's decision): the owner login igneum-josh is now igneum-labs (GitHub rename; the noreply id 337424239 is unchanged, so the commit address becomes 337424239+igneum-labs@users.noreply.github.com at the fresh-repository step, docs/plans/rotation-phase-2.md 8g; until then commits keep the igneum-josh address). gh on this Mac still stores the token under the OLD name: gh auth token --user igneum-josh is the only way to read it until a re-login as igneum-labs. This checkout's .git/config (shared by every worktree) resets credential.helper and then adds one helper that returns username igneum-labs with that token, so git pushes from here work whichever gh account is active (the global gh auth git-credential helper answered first before this fix and handed out joshmalone117: "repository not found"). Before any gh call: gh auth status must show igneum-josh (the stored name) as the ACTIVE account (gh auth switch --user igneum-josh if not); the joshmalone117 login on this Mac belongs to other projects and has no access to this repository.
  • Vercel project: igneum in the vivanmn team, because Vercel refuses the personal account as a scope. Move it to its own team when the venture is named. For the site, explorer and job-market API later.
  • Neon database: igneum, id soft-voice-31914738, London (aws-eu-west-2), Postgres 17. Connection string in ~/.config/igneum/env, never in the repo.

Domains (purchased by Josh, 3 October 2026, registrar with "Full Protection"; nothing pointed yet)

igneum.net, igneum.io, igneum.network, igneum.info, igneum.store, igneum.online, igneum.app, igneum.co.uk, igneum.xyz. Also bought 3 Oct 2026 (Josh: "bought all the other domains"): igneum.org and igneum.com, so the full set is held. Applied 3 Oct 2026: all 15 Igneum domains at GoDaddy (also .art, .email, .pro, .shop, .vip) on Vercel nameservers (ns1/ns2.vercel-dns.com) and attached to the Vercel project igneum: igneum.network is the primary site, every other domain 308-redirects to it. igneum.com is still on Afternic nameservers (purchase in transit), attach when it arrives. Site source: site/ (static). Since the evening of 3 Oct 2026 the live site is the igneum project in the igneum team (igneum-josh login, ~/.config/igneum/vercel), deployed by the GitHub integration on every push to master; the vivanmn project of the same name only holds the 13 redirect domains. Link, env and hand-deploy commands: packaging/README-ship.md (checked 4 Oct 2026).

Browser profile (standing rule, 3 October 2026)

Every Igneum task in Claude in Chrome runs in the Chrome profile "josh (igneum.network)". Josh also has profiles for VIVANMN, QUANTUM, PEASEHILL, THRSTY, GEMVEN and JBM EXEC. Confirm the active profile before acting; if it is the wrong one, switch or stop and say so. Never carry Igneum sign-ins, posts or purchases through another brand's profile.

Running agents on this Mac (standing rule, 4 October 2026; builds moved to igneum-build-1 on 6 October 2026)

  • Code and documents in parallel; the Mac's own BUILDS and MEASUREMENTS one at a time through tools/lock/with-lock.sh build|measure|run <cmd> (measure blocks builds too: hash rate, latency in ms, power; run is for functional runs such as test networks, attack harnesses and simulators whose outputs are counts, locks, forks or seconds, and lets builds continue; use the MAIN checkout's script, /Users/joshm/Projects/igneum/tools/lock/with-lock.sh, from any worktree). A number taken while another build or simulation ran is not a number. ~/.config/igneum/build-slots (1 to 3) caps how many Mac builds run at once.
  • BUILDS GO TO THE BOX (standing rule, 6 October 2026, main's decision after the measurements in docs/plans/build-server.md): every Linux and Windows cargo build and every Linux test suite from every agent runs on igneum-build-1 (Hetzner AX162, 96 threads, 128 GB, ssh -i ~/.ssh/igneum_ed25519 build@188.40.146.49) through tools/build-remote.sh [-- cargo args] and tools/cross-remote.sh from the crate directory of the agent's own worktree. Measured 6 October: clean node build 1 min 27 s (Mac 12 to 18 min), incremental 7 s (Mac 2 to 15 min), Windows cross 1 min 44 s (Mac 4 min 49 s to 12 min 28 s). The box has its own slot files (/srv/builds/_locks/build-<k>, count in /srv/builds/_locks/slots, 1 today); a remote build takes one of those, never a Mac slot. Sources travel as HEAD through the bare mirrors /srv/igneum.git and /srv/igneum-node.git plus an rsync overlay of uncommitted changes (re-stamped); /srv/builds/<worktree> mirrors the worktree root; artefacts come back into <crate>/target-remote/, never target/ (they are x86_64 Linux and Windows binaries). Every run writes one line to /srv/builds/_log/builds.jsonl (the worker dashboard reads it); IGNEUM_AGENT=<name> tags it. The PCs keep only jobs that need their GPUs or the Windows runtime (measurements, Windows test suites, installer smoke runs: node tools/build-job.mjs run --target ae432dc7|1ccfe586 ..., PC 1 = ae432dc7, PC 2 = 1ccfe586). The Mac keeps macOS binaries, the DMG and Metal tests, under the build lock. THE MAC RUNS NOTHING THE NETWORK DEPENDS ON (Josh, 6 October 2026, evening): after the 0.3.15 cut the two devnet hands, node 1 and the observer (its node and tools/observer), run on the box as systemd units (igneum-node1, igneum-observer-node, igneum-observer; docs/plans/hands-on-build-1.md; infra/build-server/hands/), node 1's p2p on 26611 with --externalip, every RPC on loopback, the observer's Neon string in /srv/observer/env (mode 600, copied from the Mac, never in the repo); that file is the only secret the box holds. The Devnet 2 seed, when it starts, gets its own unit the same way. Setup and re-provision: infra/build-server/run-from-mac.sh <ip> (idempotent); the rustc pin is RUST_TOOLCHAIN in infra/build-server/provision.sh (1.99.0; there is no rust-toolchain file, add one) and build-remote.sh refuses a version mismatch. Nobody deletes another worktree's target dir on the box. Windows exes are reproducible (-Wl,--no-insert-timestamp in cross-remote.sh, the Mac's cross-build.sh and the PC job alike); a node binary whose strings lack its commit fails tools/ci/commit-string-check.sh (the empty-commit class, 6 October 2026: kaspa-build-info embeds the hash only from a .git directory on a branch and never re-runs once empty, so every Mac worktree build and every PC job build had shipped without it; build-remote.sh, cross-remote.sh, cross-build.sh and the PC job now carry the two-step: a branch or minimal .git, and cargo clean --release -p kaspa-build-info on a new commit).
  • Every agent works in its own git worktree (git worktree add ../igneum-wt-<name>), never the shared checkout, and stages only its own files. Mac builds (macOS binaries only): nice -n 19, at most 4 cargo jobs.
  • Never launch /Applications/Google Chrome.app headless (it blocks the owner's Chrome); use the built-in browser pane.
  • Keep the Mac on mains with the 140 W charger; on 4 October it hibernated at 1% battery and took node 1 and the observer down.
  • A source tree copied to another machine (rsync, zip, tar, scp) is re-stamped with touch before anything builds it, because cargo rebuilds by mtime and the far side keeps its target dir (the stale-build class: shard run 2 on 4 October, the 0.3.6 PC build on 5 October). tools/ci/copied-sources-check.sh fails CI on any script that copies and builds without it. When a bug is fixed, fix its CLASS: grep for every other script with the same shape the same day, and add a check that fails when the shape comes back (Josh, 5 October 2026: "we should not be having same bugs repeated").
  • A watcher or gate is trusted only after it has been shown to fire on one known-finished and one known-failed case (4 October 2026: three job watchers waited for a line the closing report never starts with, and a failed shard run reported exit 0; the failure was found by hand half an hour later). Every job's outcome and its error lines are read the moment it ends, done or not.

Every number carries its consequences (standing rule, 5 October 2026, 21:30 UTC)

Josh: "this question and answer should have not needed to be asked ... so that suggestions like this get made without me" (the 12 GB mine-and-prove question, which followed from the 15.6 GB measurement and should have been raised by the agent that measured it). Rule: an agent that measures or reports a number also states, in the same report, what the number means for each user tier and what it will do about it, before anyone asks. The tiers: a home miner with one 8 GB card, one 12 GB card, one 16 GB card, one 24 or 32 GB card; a rig; a pool user; each on Windows, Linux and macOS; each on NVIDIA, AMD and Apple (Intel when it exists). A report that says "peak 15.6 GB" without "so 12 GB cards cannot do both; here is the profile that fits them, measuring now" is incomplete and goes back. The same for hash rates (per watt and per pound for the tiers), times (what deadline it fits), sizes (what disk or memory it needs), and prices. A standing reviewer agent reads every status file, bench-log entry and plan for missed consequences and opens the work; the coordinator does not wait for Josh to notice.

A job never quits or restarts the installed app it did not start (standing rule, 5 October 2026, 23:05 UTC)

Ember Tune's PC 1 playbook started a second engine, that engine's own updater saw itself as 0.3.9 and launched the per-user installer, and the installer's stop step POSTed /api/quit to the installed app, taking PC 1 off the network from 22:31Z (141 MH/s gone, the 0.3.11 Windows build blocked) with nobody awake to relaunch (corrected 6 October 2026 from the collected log; the playbook's own quit never fired and pointed at its scratch engine; fixed at e600e63: a second engine never runs the updater). Rule: a test engine started by a job runs on its own port and data dir with its own URL file, and a job may quit, pause, resume or restart only an engine it started itself (the URL it created); the installed app is touched only through the signed restart and update-now job kinds, and a job that needs the installed app's miners out of the way uses the runner's --stop-miners (the runner stops them before the script and restarts them on any exit), never /api/pause or /api/resume from the script, not even with a finally block (ruling 6 October 2026: a script that dies before its finally leaves the box paused unattended). tools/ci carries a check (playbook-quit-check) that fails a playbook which reads %LOCALAPPDATA%\igneum\app\app.url or ~/Library/Application Support/Igneum/app/app.url and sends quit, pause or resume to it; the reviewer's row C35 is the record.

Devnet 2 gate and activation rules (standing rule, 6 October 2026, 16:4x UTC)

Josh's ruling after the DAA 198,000 incident (a fixed-height activation crossed while the fleet was still updating: a two-sided chain, a 229-block reorg, execution reset to genesis on every node, proving at zero for an hour): releases stay hourly; what changes is where they land first.

  • Devnet 2 is the rented fleet as its own staging chain (own genesis and network id, refused by live peers at the handshake). Every release, activation and tuning kit crosses Devnet 2 through tools/fleet/devnet2-gate.sh (PASS = zero rejected blocks across the activation, no reorg over depth 3, exec roots agreeing on every box, a segment record paid, every node on the new version) before the live devnet or any of Josh's machines sees it. The shipper does not build the live object before the PASS line.

  • No fixed-height activation on the live devnet. A consensus change flips when 95 percent of mining weight over a window signals the new object, with a floor height as the backstop; the class v4 cut is the first to carry it (status file gates P1 and P2).

  • No "clean day" waits (Josh, 6 October 2026, 19:3x UK: "we dont need a clean day for anything this is just delaying things"): a cut's only gate is the Devnet 2 crossing (the class v4 cut's gate is its P1 rehearsal on the fleet chain); digest moves are bundled into one cut (0.3.15 = class v4 + the fourteenth field), miners first, hands last.

  • A deep reorg never resets execution; a snapshot a node cannot read fails loudly; the p2p snapshot path refuses a snapshot below the node's tip or the restart; a hands script never pgreps its own command line.

  • Main checks an agent's number against the log or the chain before relaying it to Josh, or labels it unverified.

  • Never remove more than 10 percent of the live devnet's 30-day vote weight in any hour (Horizon finality lane, 6 October 2026: the class v4 rehearsal took 13 fleet keys off the live chain at 18:27Z; with seven earlier leavers that was 42.7 percent of the voter table frozen at the last lock, and rule v3 holds the pause for a full window; under v3 a sudden departure of a third of weight is a 30-day pause on mainnet). Experiments that borrow live miners do it in slices with an hour between. The protocol fix is the signed LEAVE item (0.3.16).

  • Every NODE cut's Devnet 2 gate includes a MINING new node beside an old node on the live file for ten minutes (the old node accepting the new node's blocks, the hub's reject count unchanged), and a new node restarted mid-window re-syncing from an old peer. Found 6 October 2026, 20:5x UK: 0.3.15's node stamped the class v4 signal bit into the block version (1026) on the thirteen-field file; every 0.3.14 node rejected it; the digest-compat test passed because the handshake peers while the block version splits; the canary caught it before any live box moved.

  • Standing fleet (Josh, 6 October 2026, 20:0x UK: "cant we keep rented cards up longer"): 16 live-devnet boxes and 6 Devnet 2 boxes are kept up permanently and re-rented on host death; only benchmark and wave boxes are one-shot; a standing box never leaves the live devnet for an experiment (the class v4 rehearsal took the 15 prover boxes and paused live finality at 18:42Z; experiments use wave boxes only). The Mac runs nothing the network depends on: node 1 and the observer move to igneum-build-1 as systemd units (docs/plans/hands-on-build-1.md).

  • Secrets on igneum-build-1: none that sign releases, move funds or reach the hands. Exception recorded 6 October 2026: Discord webhook URLs at /srv/discord-hooks/env (mode 600, rotatable in one click) for tools/community/discord-hooks.mjs.

CI red is stop-the-line (standing rule, 6 October 2026, 22:0x UK)

  • Whoever's merge turns master or a release-* branch red owns the fix inside 15 minutes or reverts the merge; the red watcher posts every failed run to the hidden updates channel and to /srv/ci-red/red.jsonl on the box (tools/ci/red-watch.mjs); the box's own red builds land in the same file with a class (remote-run.sh pre-flight, kept run logs) and the 09:00 UK digest counts them per class with each class's guard.
  • The pre-push gate is the same script CI runs: tools/ci/pre-push.sh (installed by tools/ci/install-hooks.sh; --hook before a push to master or release-*, --ci in the workflow). A check is added there, never only in ci.yml.
  • Research and operations documents live outside the public export list: name them in tools/ci/export-exclude.txt (read by the identity check and by the mirror's sync.sh). What stays in the list is read by the public and must pass the identity grep.
  • A path Windows cannot hold (colon, trailing dot or space, reserved name, over 240 characters) never enters a commit: the pre-commit hook runs tools/ci/windows-paths-check.sh --staged.
  • Record: docs/analysis/ci-failures-2026-10-06.md (168 non-green runs in three days classified; 126 on master; all but two classes were tree checks that the gate now runs locally first).

A rule row closes only with its check (standing rule, 6 October 2026, 18:4x UK)

Josh, after the pgrep self-match hit twice in one day (the shipper's hands script at lunchtime, the fleet's wave script at 17:1xZ: a pgrep -f "<pattern>" whose literal sat in the calling shell's own command line, so the check always passed and no node ever started): "again wasted time". Rules:

  • A bug class found today gets its tools/ci check merged on master the same hour, or the rule row stays OPEN and main says so. A rule row without a check is not closed.
  • Box operations (ssh to a rented box, install a payload, start a node, wait for sync, read height, peers and exec tip, start a miner or prover) live in ONE shared, tested library (tools/fleet/lib/), exercised against a Devnet 2 box by a test; agents call it and never write their own copy in bash or PowerShell.
  • A watcher or collector verifies the chain-side fact (height, peers, exec tip, paid records), never a reported rate or a process name.
  • pgrep -f / pkill -f / ps | grep with a literal pattern is banned in scripts; use the bracket form [i]gneumd, -x on the binary name, or a pid file (pkill -F, tools/fleet/fleet-bg.sh). Kill by exact command line or pid file, never by a name: at 22:09 UK on 6 October a Mac-side pkill -f <log file name> matched nothing (a redirect is not on the command line) and the roll-everything script wiped a box it had been told to hold (CI check and gate: tools/ci/kill-by-name-check.sh, which also flags a file-name shape under pgrep/pkill).