the project lead, 5 October 2026, 22:45 BST: "make sure we have ember tuning every single card for efficiency out of the box, the
more data = the better the tune, make an awesome system." Built on lever 3 (docs/plans/miner-eff.md), lever 2's signed
tuning section (docs/design/miner-tuning.md), the AMD telemetry helper (ce28158, its --tune/--set-gmax/--set-plimit/
--reset contract) and the Power control switch (22b34e0). Design, data flow, tiers and the privacy line:
docs/plans/ember-tune.md.
- src/ember.rs (new): two knobs per card (power limit %, core clock cap MHz; memory clock never touched), the full plan
(power ladder 100..50%, then the clock ladder 90..60% at the chosen power), the confirm plan (the fleet prior and one
neighbour), the baseline plan (measure only), the marks (faulted, hot, memory_clock_dropped, unapplied, no_readings),
the choice (best MH/W within 1% of the top rate, then rate, then draw), the fleet record (a hash of the install id,
no address), the prior lookup and the kill switch (tuning.ember), the state machine on a fake clock. 9 unit tests.
- engine.rs: tick_sweep schedules every NVIDIA, AMD and Apple card (120 s steady, 600 s to the boundary, no job hold,
no pause, weekly, again after a driver major or program-class change, never under the manifest kill switch); the
probe (nvidia-smi clocks.max.gr + driver_version and the direct/helper mode; igneum-gpu-telemetry --tune for AMD);
tune_apply (nvidia-smi -pl / -lgc 0,<MHz> / -rgc directly or through the helper; the AMD helper per request);
Cmd::TuneProbe, Cmd::TuneSet; faults from rejected and mismatched hashes mark the step; the TUNE lines and the TUNE
{json} record, uploaded with the log; the Tuned line on the card state. The NVIDIA helper starts only with Power
control on: the --sweep job never counts as permission (no prompt on a PC with nobody there).
- sweep.rs: the helper protocol gains lgc/rgc (clock cap and reset) and resets the clocks after 20 idle minutes.
- state.rs, config.rs: the tune fields (clock cap, driver, class, source, the Tuned line); the nvidia-smi telemetry
query carries clocks.gr and clocks.mem; the AMD sample line's plimit_pct and gmax_mhz are parsed.
- ui: "Tuned: X MH/s at Y W (Z MH/W)" with the point, the source and when; measure-only cards say why; the Ember Tune
switch; tune-line.test.mjs.
- relay/lib/ember.mjs + relay/test/ember.test.mjs: the aggregation per (card model | driver major | program class):
median point, MH/W, spread, samples, machines; five samples converge, an outlier does not move the median, baselines
make no prior, de-duplication, the manifest merge keeps lever 2's cards. api/console.mjs fn=tuning and
tools/console.mjs tuning; tools/tuning.mjs --priors [--write tuning.json] [--site] [--tuning-off].
- site: the fleet priors table on /miners (site/miner-priors.json), the lever text.
- relay/playbooks/ember-tune-pc1.ps1: the PC 1 run (second engine with --sweep from a scratch copy of the install).
Measured tonight: see the bench log entry that follows the PC 1 run. The 9070 XT left PC 1's bus at 20:40 UTC and the
5090 needs the administrator prompt the project lead cannot answer asleep, so tonight's PC 1 run is the baseline plan on the 5090
through the whole pipeline; the two-knob tune on both cards is owed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
the project lead, 5 October 2026: "if we don't have to ask then don't ask". The NVIDIA power cap and the efficiency sweep need
administrator rights (one UAC prompt); PC 1 raised that prompt for cmd.exe at every app start and every sweep attempt
(17:00, 17:30, 18:12, 19:04 UTC today, each cancelled unanswered after 2 minutes; the "Windows Command Processor"
the project lead saw).
- config.rs: `power_control` (default OFF on every machine); `sweep` default becomes off and is implied by it (an
install carrying sweep = true without power_control is migrated to off on load).
- engine.rs: `elevation_allowed(power_control, sweep_only)` gates the power cap (`power_cap_plan` builds nothing when
off, the card note says so), the sweep scheduler, Sweep now, the sweep helper; no prompt on quit (the limits reset at
the next reboot); no second prompt through PowerShell when the window host's prompt goes unanswered.
Cmd::PowerControl(on): on = ONE prompt at that moment (every NVIDIA cap in one step), off = nothing asks;
`power_control_after_prompt` turns a refused, cancelled or unanswered prompt into "power control off:
administrator rights were not given" (switch back off, sweep off, no retries). Unit tests: off builds no elevated
command; on + refusal gives the notice; rights given keeps it on.
- platform.rs: `elevated_failure` maps the launcher's exit 251 and the "canceled" wording to the prompt, any other
code to the step itself.
- server.rs: POST /api/power/control {on}. ui: the Power control switch with the line "Windows asks for administrator
rights once; the cap and the sweep need them", the note beside it, the sweep switch disabled while it is off.
- The clock-sync prompt stays behind the Sync clock button only (unchanged).
- tools/windows/power-prompts-off.ps1: the 0.3.9 job that switched PC 1's sweep off through the API it has
(run-20261005-192313: sweep True -> False; the 0.3.9 cap has no off switch, it asks at an app start only).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
the project lead watched the 9070 XT at 90% usage with its fans barely turning and the app could not say what it drew: the
draw, temperature and MH per watt line came from nvidia-smi only, and the earlier per-watt figure used the board
rating. proto-opencl/gpu-telemetry.c prints one line per AMD card per sample (bus from SetupAPI by the display
device's name, kind, name, watts, temp_c, fan_rpm, fan_pct, mclk_mhz, gclk_mhz, util_pct, source), built by
build-windows.sh against vendor/adlx (the SDK clone), shipped by make-payload.sh and push-inputs.sh. The engine
runs it with -l 5 beside nvidia-smi (Source::AmdTelemetry, tick_amd_telemetry), parse_amd_telemetry fills
power_w, temp_gpu, fan_pct, fan_rpm, mclk_mhz, util_pct and telemetry_at on the AMD card matched by kind and
ordinal, so eff_mhw and the dashboard's existing line show it; app.js shows fan and memory clock when present.
Tests: three on the parser with lines captured on PC 1 and the Mac fixture; the sysfs path ran on a fixture tree.
Measured over 20:27:45 to 20:29:41 UTC with both cards mining (docs/bench-log.md, under the 9070 XT ceiling table):
9070 XT 198.9 W (193 to 212), 64 C, 657 rpm, 2,505 MHz memory, 3,290 MHz shader, 100% busy, 17.73 MH/s =
0.089 MH/W; RTX 5090 307.6 W, 69 C, 44% fan, 122.30 MH/s = 0.398 MH/W.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fed by /api/explorer from the observer's tables. Latest blocks (hash, number, DAA, blue score, miner, txs, proof
records, time); a block's header, parents, children, mergeset, coinbase outputs, EVM transactions, shards, checkpoint
and certificate; an address's blocks, what they earned, vote keys and balance (eth_getBalance when EXPLORER_EVM_RPC is
set). Same tokens as live.html. vercel.json rewrites /block/:id and /address/:addr; the footer links the explorer; the
link checker skips template literals and resolves /api/<name> to its function. node tools/site-serve.mjs previews the
site with the functions in-process.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The numbers profitability sites and pool software read (WhatToMine's form: explorer or pool with an API, the halving
schedule, a source for total coins). Reward and supply from the emission rule at the node's DAA score; the halving table
(33 rows), the 30-day ramp and the observer's coinbase check. Cached 10 s, CORS open. FIELDS in each handler is the
contract; public-stats.test.mjs checks it from a fixture, tools/ci/public-api-check.mjs checks a deployment.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
site/lib/emission.mjs is the emission rule as igneum.rs computes it (block_subsidy, launch_ramp, an exact floor-sum for
minted-so-far); its tests reproduce the node's own test values and a devnet coinbase (block 2622db76: payload 454,486,399
at DAA 125,064, outputs 454,485,299 = E(125,063), what the merged parent declared). Every live_blocks row gains tx_count,
evm_miner (the IGNA tag, else the vote key's low 20 bytes), proof_records (IGNP section), subsidy_sompi, paid_sompi,
selected_parent, number, detail. No extra RPC per block: measured 282 against 283 wRPC and 785 against 776 EVM calls
per minute before and after. live_state.rpc_load and live_state.supply_check are new.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
docs/security/keys.md: every key the project depends on (the folder, the gh
keyring, the Vercel env of three projects, the GitHub secrets) with where it
lives, what it unlocks, the blast radius lost and leaked, who rotates it and
the rotation status, written from the files and the scripts that read them.
No value, no private fingerprint. Section 4: the second OTA signing key kept
offline, the app change (a key list plus revocation in the manifest), 0.3.9
as the carrier, and the emergency path if the one key leaks today (a manifest
signed with a new key is useless to 0.3.x apps; the mitigation in order).
tools/keys/backup.sh: ~/Desktop/igneum-keys-<date>.dmg, AES-256, hdiutil's
own prompt (never argv, history or a file), the folder minus build-slots,
dlsite-dir and pytools/, plus a README; attached read-only, every file
compared by sha256, listed, detached. --dry-run lists. restore.sh: --check
compares the image against the live folder without printing values, --to
copies back with 0600/0644 and 0700. test-backup.sh: the end-to-end test on a
scratch folder with a throwaway passphrase, 8 steps, passed.
tools/ci/no-secrets-check.sh, in ci.yml: no tracked file named like a key of
~/.config/igneum, no 64-hex value assigned to a token/key/secret name outside
tests and the allowlist (the OTA public key, the published Hardhat and Anvil
accounts); a --self-test fires on a known-bad tree first. 776 files, 0 hits.
Also: ~/.config/igneum, vercel/ and txgen/ are 0700 now (were 0755).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Footer partial: imprint line with the registered address and the mailbox; Report a flaw mails hello@igneum.network with the spec issues as the second route. Litepaper: Who are you names the entity that ships the software, the team is pseudonymous with no team page, the ledger and the benchmark source are public with the repository at the public testnet, the last paragraph gives the mailbox and the address. Miner: the dev fee goes to Igneum Labs LTD. Evidence (md and page): repository private until the public testnet. Trademark FILING.md: applicant Igneum Labs LTD at the DIFC address. Identity check: the ledger and fixes file join the export list; the forbidden list notes that the registered address is allowed. Site rebuilt (bench page and journey picked up the txgen log entry).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The ledger's header and submission lines, G3's status line, and the fixes file's legend, row 9, decision (b) note and section 5 record the four decisions. Two literal pattern mentions reworded so the identity check passes with both files on its export list.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
igneum-prove-core carries the node's fees.rs (PgasTable, FeeParams PROTOTYPE and CALIBRATED_V1,
FeeSchedule::at); the shard input and every fixture carry the schedule and the block's DAA score; the executor
reads the set at that score, raises the base fees to its floors and meters with its intrinsic, B_p and modexp
entry, as the node's execute_segment does. The 328-byte statement is unchanged: the node's native veto pins the
schedule (a new layout would be a consensus change for every node). Exporter: schedule and daaScore from the
dump (gen.mjs writes them), per-segment switch on replay, S_p from the set. Fixtures from one simnet chain across
the switch at DAA 800: fees-switch-prototype (block 51), fees-v1-shards2 (351), fees-v1-shards3 (355); 358
segments replayed, every state root the node's. Host tests on both sides. Guest re-pinned: shard
0x2b1a81cb..., aggregator 0x474678f3...; pinned-guests-check passes.
Node fork 2b6d23ef unchanged (igneum-exec tests 11 passed). Digest for the override with
fees_v1_activation_daa 210000: ab8847da538dead1dc10e046dfaadab3c1c35928e3748810c4e050d4a886087a.
Runbook docs/plans/fee-switch-devnet.md; infra/devnet/restart-hand-nodes.sh and restart-seed.sh take the
override object (the hand nodes and the seed run 20139145 today and must move to 2b6d23ef first). One line on
the live page, spec 5.11, the testnet README, the floor analysis, the bench log and the journey.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/txgen/run.mjs funds generated wallets from the devnet dev-fee key and sends transfers at a steady rate through
one node (nonce tracking from the pool's pending nonce, two-strike drop verdict, pool back-pressure counted as
deferred, spend cap, clean stop, summary JSON); tools/txgen/proving-watch.mjs watches the proving layer and builds the
per-block report. Two runs through the Mac node: 2,275 sent at 2/s, 2,161 included at 1.86/s (run 1), 1,650 sent,
1,633 included at 1.71/s with no failure (run 2, fixed code). Block 72704 shard 0 (29 transfers, 5,800 pgas) proven on
PC 2 in 34 s, verified on the Mac in 0.297 s, paid 1.7623 IGN.
Block 72803 (seven skipped copies, no executed transaction) failed the native-execution veto: the exporter rebuilt the
including blocks from an export that names no block, position or skipped copy's miner, sorting skipped copies out
of their block, merging consecutive blocks of one miner, dropping empty blocks (the node counts them in the link's
block index) and guessing the zero address. blocks_of now rebuilds from the 0.3.9 export's "blocks", "block" and
"position" fields (the fork change on vendor/igneum-node-txgen branch txgen-export), keeps an old export in its
order and refuses a skipped-only block without a miner. Fixtures block-72803-skipped-copies and
block-72854-empty-block-first with the node's shard plan beside each; the fixture test now checks the cut's links,
roots, gas, pgas and counts against the node's plan (shown failing on the old 72854 cut). No change under core/.
Bench-log entry and evidence rows 15 and 21.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Downloads: packaging/ota/publish-public.sh publishes the current installers, the HiveOS package and the two signed
manifests into dl/public/ with no token in any URL, writes the four /public/ aliases as vercel.json rewrites and an
unsigned index for the site; publish-manifest.sh --public and ship-app.mjs --public run it on every release (dry run
and self-test cover it). Nothing removed from the token folders.
Site: the miner and wallet buttons link the public aliases and show the version and size from the index, read at
build time (site/downloads.json is the offline snapshot); TESTNET_OPEN in build.mjs drops the "Public testnet: not yet
open" line on the go; the HiveOS Flight Sheet install line on the miner page; /faucet page.
HiveOS: igneum-hive-0.3.8.tar.gz from the 0.3.8 node (2b6d23ef, PC build job) and the zig-built Linux workers.
Faucet: site/api/faucet.mjs (10 IGN per address and per IP per day, Neon table faucet_grants, EIP-1559 transfer signed
by site/lib/eth.mjs with no dependencies: keccak, RLP, secp256k1 with RFC 6979), FAUCET_KEY and FAUCET_RPC from the
Vercel env only; 15 unit tests with a fake database and node, run in CI.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>