Commit graph

259 commits

Author SHA1 Message Date
igneum-labs
8b2c53e48d Driver check: every card of the vendor stops for the install (0.3.22; PC 2's Arc in the Razer Core X V2 read kind=discrete on 0.3.21, so the external-kind hold alone missed the card that crashed the box at 16:27Z)
drivertable::install_hold_keys holds every enabled card of the vendor being installed (the other vendors' cards keep mining; a card already off has nothing to stop); the row says so before the click and while it runs, with the enclosure warning kept on an external row; the toast and the engine's event name the vendor. The x1 gen1 link signature is not on the card state and was not added. Test known-failed first (the 5090 inside the case was not held for an NVIDIA install; red on build-2, then green); box gate 259 + 33 + 8; UI 51.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 18:20:14 +00:00
igneum-labs
4f24f81535 The miner's chain key from the shared legend export (key-22, 7 October 2026): IgneumDag.legend({mine}) and renderLegend(el, {mine}) in scene/live-dag.js (2.0.5) carry the one list of entries with each state's token and shape (Pending, Included, Excluded, Selected chain, Proven, Locked checkpoint; the app adds Your blocks, ringed, first); the app's chain card renders its key from it at mount with the source line kept (the Included swatch had been ember while the scene draws included blocks in --included, and "pending" was lower-case), its CSS colours a swatch only from the entry's token; the copies synced; tools/scene/legend.test.mjs on the gate's scene line: the export's entries, order, tokens and shapes, every colour the scene draws has an entry, the app key is the export, and the /live key equals the export minus the ruled exceptions (no Pending, no Your blocks) with the same wording, token and shape on every shared entry, binding on master where the site deploys from and a diagnostic on a release branch whose site tree is the frozen cut; the site is not edited (main's correction: the project lead's ask was the miner's key)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 18:02:56 +00:00
igneum-labs
11aeaf1d68 Merge driver-check f03b0e74 into release-0.3.22 (main: a 0.3.22 app item; the eGPU driver-install hold and warning)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 17:32:40 +00:00
igneum-labs
41caea6a89 Merge release-0.3.21 826dbf76 into release-0.3.22 (the 0.3.21 app tree as shipped over c4459193)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 17:32:40 +00:00
igneum-labs
f03b0e7415 Driver check: a card in an external enclosure has its worker stopped for the install (PC 2, 7 October 2026, 16:26Z: the Intel installer's display reset took the machine down with the app's worker mining on the Arc in the Razer Core X V2)
The rule (drivertable::install_hold_keys): a driver install on a card the app reads as external (the eGPU kind from update-return-21b) stops that card's worker before the installer starts, through the cards path with the restore choice kept (the --cards-off shape); the vendor's cards inside the case and every other vendor's card keep mining. The row says so before the click and while it runs (the display reset can take the machine for a minute and may need a restart; save your work first). When the installer ends the held card goes back as it was; a card the install took away comes back when the card does (driver_release_held on the detection that lists it again). The app never restarts the machine.

Tests: the known-failed rule test first (an install on an eGPU card with the worker still running held nothing: red on build-2, then green), the view test for the two sentences; box gate 258 + 33 + 8 (test --release on build-2). Mock scenarios drivers-egpu and drivers-egpu-running; captures 13 to 16 (light and dark). Branch rebased onto release-0.3.21, which already carries the driver-check commits; the earlier tip is kept as driver-check-0320.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 17:28:45 +00:00
igneum-labs
ab8e23c8cc Scaling (the project lead, 7 October 2026: "the miner needs some scaling so more is visible in the initial window"): the window opens at about 80 percent of the screen's work area, capped at 1440 by 900 on a display up to 1920 wide and scaled up with the display beyond that, remembered per machine once the user resizes (the Mac window's frame autosave name; the Windows host's HKCU Software/Igneum/Miner WindowW and WindowH, written on WM_EXITSIZEMOVE and used while they fit the work area); the Overview's vertical rhythm tightened so the rate band, the big button, the ladder strip, the chain card and the node card's first row sit above the fold at 1280 by 800 (gaps, paddings and the scene's height 220 to 184 px; no type below 13 px; the live scene and the GPU marks keep their look); fold.test.mjs measures the Overview's key elements inside the viewport at 1280 by 800, 1440 by 900 and 1920 by 1080 and the first object of Cards, Earnings and Prove, with Playwright on build-2 (known-failed on 0.3.21: the chain card ended at 836 and the node row at 900 of 800), skipping where there is no Playwright env; tools/ui-mock/fold-measure.cjs prints the numbers; captures at 1280 by 800 and 1920 by 1080
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 16:58:40 +00:00
igneum-labs
ddb3ef96af 0.3.22, Devnet 3 (7 October 2026): the package names the network its node joins (igneum-app.json node_devnet_suffix and node_peers; Runtime::from_env_with reads them when the environment is silent, node_dir devnet-N beside devnet-v4), no override file on a suffixed devnet from 3 (the node refuses it; the manifest's consensus override ignored with one log line), the version strings; app gate on build-2 258 + 32 + 8
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 16:49:21 +00:00
igneum-labs
4aa670aecb powertask: the registration test asserts the Power Helper's action is the app's own windowless exe (the Rust part of update-return dbbf0483; the relay/clients half lands through master on the relay line)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 16:31:07 +00:00
igneum-labs
dc1a81c791 Currency by locale (the project lead, 7 October 2026: "£/day is for UK; we need other currencies"): no IP lookup; the web view's language (the OS locale) picks the region, its currency and its default tariff at first run (GBP, EUR, USD, CAD, AUD and the long tail by ISO region through ISO_CURRENCY, names from Intl.DisplayNames, an EU member on the euro takes the EU average), a currency picker in Settings and on the first-run step whose override lives in the engine's settings file (config.rs currency, state.rs, Cmd::Region's third field, api/region currency; the Rust round-trip test) and wins over the locale; a region with no currency row falls back to USD with the prompt visible; every money line goes through one formatter (fmtMoney: Intl.NumberFormat with the code, narrowSymbol, the symbol placed as the locale places it); the user's own tariff is the number, so no exchange rate anywhere (the rent line says so for a currency without a USD rate); zero-decimal currencies typed in the unit (priceFactor), the price field's ceiling 100,000; three view tests known-failed first (de-DE reads EUR with the Eurostat tariff; the override wins and survives restart; a locale with no row asks); the mock's euro scenario
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 16:22:37 +00:00
igneum-labs
1fc98faa6e Merge remote-tracking branch 'origin/first-block-21' into release-0.3.21 2026-10-07 15:21:29 +00:00
igneum-labs
59edaad1e4 first-block-21, main's reading "seen once": the first-block card waits until a window has shown it. The flag first_block_shown is set when the page reports the card displayed or dismissed (POST api/card/seen with the milestone's count and at, ladder.rs card_seen; the window hiding to the tray with the card up counts as the dismiss), never when the card is raised; an unseen card survives restarts and auto-updates (start_run drops a card only once milestone_seen), so a first block found overnight greets the miner the first time they open the app and never again. Every other rule stands: the lifetime count 0 to 1 raises it, identities and card swaps leave it, a kept directory at 0 shows it on the first block, a count that starts over raises nothing, a 0.3.20 record (schema 0, no flag) whose first block already came takes the flag and loses its card. The view trusts a 0.3.21 engine (the ladder carries first_block_shown) and keeps the uptime refusal only against a 0.3.20 engine. Tests: ladder.rs eight (a_first_block_found_with_no_window_greets_the_miner_at_the_first_open_and_never_again added: no window, a restart, the first open shows it once, a second open does not; the round-trip helper gets one temp dir per call, the shared path let parallel tests wipe each other's file), the view test re-cut, the mock's firstblock card unseen (the capture's mock log shows the page's api/card/seen). Lines: build-2 app gate 255 + 32 + 8; UI 67; pre-push 56 green; captures re-taken to ~/Desktop/igneum-previews-2026-10-07/first-block.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 15:09:20 +00:00
igneum-labs
1ea13655d7 MF-11 follow-ups on release-0.3.21 (the app half of update-return 2d3d211a and 0b423697): the external card kind from a USB4 or Thunderbolt router in the device's parent chain (PC 2's RTX 5060 Ti in a Razer Core X V2 reads eGPU, not discrete); the Power Helper's registered probe wants the task enabled and its action exe on disk; a helper that gives no heartbeat or no line inside its window is a FAULT power-helper line with the registration re-read; a same-length rewrite of the command file is a new command (effective_skip; PC 2, 7 October 2026: every tune refused since the 14:35Z boot)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 15:07:17 +00:00
igneum-labs
b3bca507a4 first-block-21 (the project lead, 7 October 2026: "the 'you got your first block' situation only shows for the miner's first ever block"): the first-block card once in the app's life. Engine: ladder.rs carries a persisted first_block_shown flag set when the lifetime count settings.json holds crosses from 0 to 1 (survives restarts, updates and a kept data directory; never touched by a key changing identities or a card swap; a count that starts over on a shown record raises nothing); Ladder::start_run at engine start drops a milestone an earlier run persisted (a card is for the run that raised it) and takes the flag on a 0.3.20 record whose first block already came; the new-card card never fires at a count of 1; the state carries started_at (the run's wall-clock start). View: blockCard refuses a milestone raised before this run (staleCard, a minute of slack, uptime_s when the engine has no started_at), firstWait keeps the count-up off once the ladder records a first block, the first rung reads the flag. Tests: seven in ladder.rs (the known-failed second run first: a 0.3.20 record with the card persisted and the count at 1 showed it again; the first ever block; a restart at 1; an update at 1 over the older shape; a kept directory at 0 with the flag unset; a count that starts over; block 2 ordinary) and one view test in the same order. Mock: the secondblock scenario and started_at. Lines: build-2 app gate 254 + 32 + 8 (test --release); UI 67; pre-push 56 green; captures in ~/Desktop/igneum-previews-2026-10-07/first-block.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 14:57:34 +00:00
igneum-labs
e68ba08ccc MF-11 update-return (0.3.21), the app half on release-0.3.21: the Windows update helper owns the return (the exe set kept beside the app, the app launched by the helper, api/state polled 120 s, the kept set restored when nothing answers, one intake line either way; the installer stays silent under /IGNOTA=2), the window host restarts a dead engine and answers the Restart Manager, the first act after an update is the read-back line and a FAULT pc-restart line when the PC came up from a power loss; the tuner never asks above a card's measured efficient point (the 5090 at 308 W, floored at the vendor's 400 W) unless Power control is on and the user raised the cap, and a refused cap is asked again at 2 and 10 min then reported as FAULT power-cap; the job-channel ping on every wake request (7 October 2026, PC 2 lost power at 10:46Z; the relay half stays on update-return)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 14:29:41 +00:00
igneum-labs
f108f32a3a Prove instead of mining (main's routing, 7 October 2026): on a machine whose every NVIDIA card is under 12 GB the Settings switch prove_instead lets the prover run with those cards' miners held off (Cmd::ProveHold through the cards path, the restore choices kept, given back when proving or the switch goes off); the Prove page's row shows only on such a machine with the sentence naming the choice; provedefault::prove_instead_cards and prove_instead_line with their test, proving.under_12gb on the state, api/prove/instead, the view test; the fleet's 3080 hour: a 10 GB card completes the compressed step alone at 8.6 GB and never beside its miner
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 14:16:23 +00:00
igneum-labs
945e6b2b6c Chain scene 2.0.4: the box's height follows the lanes (onSize, autoHeight, the lane geometry in stats) (7 October 2026, 16:3x UK)
the project lead's /live screenshot: a fixed tall box with the lanes in its top third and dead space under them. The renderer now knows
the height it wants: top padding + axis padding + lanes shown (at most maxLanes 7, narrowLanes 4 on a phone, never under 2)
times laneHeight (46 px, 40 on a phone, 26 compact; the mount option laneHeight overrides). It reports it through
onSize(heightPx, {lanes, laneHeight, narrow, compact}) whenever it changes and through getWantedHeight(); stats() carries
laneHeight, padT, padB, capacity, wantedHeight and autoHeight, so a page that sizes its own box reads no constants. With
autoHeight (on by default when the host set no CSS height on the canvas, which is read before the first size(); forced either
way by the option; never in compact mode, the app's card keeps its own height) the renderer sets canvas.style.height itself
and lets every lane through instead of fitting the lanes to the box. Every current host sets a height (/live 420, the hero
500, the app's card 220 and its Inspect view 420), so the frames are unchanged: the parity test on build-2 stayed equal on
every comparison. The site lane switches /live and the home fold to the hook.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 1546b61fa1)
2026-10-07 14:02:19 +00:00
igneum-labs
1ba6eb1a0b Miner app: the chain scene is the site's scene (scene/ 2.0.3), one feed contract, the viewpoint as an overlay (scene-parity for 0.3.21, 7 October 2026, 15:5x UK)
The drift the app carried against the site's home fold and /live, and what moved:
- renderer: both were 2.0.2 byte for byte; the app now takes the shared scene/live-dag.js 2.0.3 (paint on push whatever the
  document's visibility says: the blank /live; the phone rule on the viewport width) and proof-core.js through tools/scene/sync.mjs,
  and the gate refuses a drifted copy.
- palette: the dark tokens were equal; the light theme's --ember was #E04A14 and --ember-hi #F2541B against the brand package's
  #D0420D / #E04A14. The fourteen scene tokens now sit in the scene-tokens block app.css takes from scene/tokens.css (dark,
  [data-theme="light"], prefers-color-scheme light) and are defined nowhere else in the file.
- phone rule: the app passed narrow: window.innerWidth < 720 at mount time and never again; the site keyed it on the canvas
  width (a 640 px hero on a laptop rendered as a phone). Both now leave it to the renderer: the viewport, live on resize.
- feed window: the app asked the engine for 120 s, the site 300 s; both 300 now, so the viewer can pan the same range.
- Inspect view: 360 px tall against /live's 420 (five lanes against seven); 420 now.
- feed shape: the engine rewrote this machine's blocks to miner: "you" (a word the observer never emits) and its node-only
  fallback carried now as a float of seconds, rows with timestamp_ms / is_chain_block / vote_key_hash / timestamp_source and no
  number or rx, miners as {id, vote_key_hash, blocks_10m}, no proving, a finality with checkpoints alone. live.rs now passes the
  observer's rows through untouched (state.you_blocks counts them; the UI's mine function marks the lane from the card ids, which
  is the overlay: own blocks glow, the lane reads YOUR KEY) and node_only_reply builds the fallback in the contract's shape
  (every key of scene/feed-contract.json, null where the node cannot know, partial: true, state.source "node", ISO now). The
  test the_node_only_reply_has_the_contract_shape reads the contract file itself (include_str!), so the Rust side and
  tools/scene/feed-contract.mjs cannot drift.
App gate on build-2 (test --release, --priority gate): 228 + 32 + 8 passed. Parity on build-2: app Inspect = /live = home fold
at T+0, T+2, T+4 s, the overlay identical when both surfaces know the key.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:51:47 +00:00
igneum-labs
1e1e257580 Merge remote-tracking branch 'origin/miner-reliability-21' into release-0.3.21 2026-10-07 13:46:25 +00:00
igneum-labs
fad7ee5288 Earnings card tidied (the project lead, 7 October 2026: "remove all the type a price stuff"): the £ per IGN input, Use it, the remembered igneum.ign_price, the price line, the balance-in-pounds line, the share line, the IGN per kWh line and the cost-of-hash row are gone from the card (rentLine stays in View for the site's hash-cost model); the card is now the day rate in ember with its reason line, blocks and IGN this run, a quiet row of three (weight: rank, window, days, share; electricity: £ a day at the Settings price or the draw, IGN per kWh; lifetime: blocks and their IGN), the dev-fee switch last with one sentence; View.earningsLines(s, chain, pence, now, minor) carries every line and names its field; three view tests known-failed first (no price input anywhere, the headline and run line, the row of three), the old price test retired
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:40:19 +00:00
igneum-labs
a94dd192aa brand/marks/vendor-marks.mjs: the app's vendor marks and tokens exported verbatim for the site (site-ui-5), with the Windows mark in the same treatment and macOS as the Apple glyph, regen.mjs to refresh it from app.js, a view test that fails on drift; the review shots re-taken on build-2 against gpu-logos-21 (the Prove page on, off and light added: the switch fix in the picture)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:28:36 +00:00
igneum-labs
b900fb585f Prove page switch fix (the project lead's 0.3.19 Mac screenshot, 7 October 2026): the thin white rectangle above-left of "Prove on this machine" was the DAG legend's bare .lg rule hitting label.switch.lg, the knob outside the track at off was the inspector's bare .track rule (flex, 10 px margin) hitting every switch track; both scoped (.legend .lg, #i-track), the switch's size class is its own (big), the native input is hidden the accessible way (1 px clip, focusable, label kept) under a positioned label; three view tests, known-failed first on the old CSS (bare rules, input hiding, knob inside the track at off and on in both sizes with the theme blocks untouched)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:26:45 +00:00
igneum-labs
41441a8fdf GPU vendor marks on every card row (gpu-logos, 7 October 2026): NVIDIA, AMD Radeon, Intel Arc and Apple as hand-drawn monochrome inline SVG glyphs (under 460 B each, currentColor), each in a soft rounded well tinted by its own --mark-* token (dark and light sets, ember never tints a brand), the series line under the name in mono (RTX 50 series · Blackwell, RX 9000 series · RDNA 4, Arc B series · Battlemage, M5 series · integrated), an integrated row keeps the same glyph with the integrated line, a neutral chip glyph for an unknown vendor, the block card's mini mark; one contiguous View block and one CSS block for the apps-harmony rebase; five view tests (every vendor, the fallback, never twice on a row, the series line, light contrast at 3:1 or better with app.css checked); the mock's rig scenario and tools/ui-mock/capture.sh for the box
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:25:52 +00:00
igneum-labs
4da5edf24f MF-10: the prover reads the card's compute capability and the GPU server's sm_ words and refuses a mismatch with the reason (and reads a named-symbol proof failure as the same class); MF-8: the injector's kept-datadir step (a previous release's node writes the datadir, the new node must open it)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:25:08 +00:00
igneum-labs
fefab015e3 platform: kill_pid spawns taskkill and kill with the hidden console (master's windows-spawn check on the reliability merge)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:18:20 +00:00
igneum-labs
59fe7d08b4 Merge remote-tracking branch 'origin/miner-reliability-21' into release-0.3.21 2026-10-07 13:16:12 +00:00
igneum-labs
0730606201 engine (0.3.21): the heat-mode release restarts every slot; there is no faulted state to skip
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:14:13 +00:00
igneum-labs
e78ace39bc execrpc: 0.3.21's two callers classified (igneum_getRecentBlocks gated, eth_getBalance safe)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:12:26 +00:00
igneum-labs
ced26986fd execrpc: an empty or unparsable reply is no answer, so a stopped node reads as silent to the watchdog's probe
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 073fbea1d1)
2026-10-07 13:12:08 +00:00
igneum-labs
313059f6bd engine: the row's countdown is set the moment a watchdog restart is scheduled; injector reads the rung over two seconds
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit e1aeecad40)
2026-10-07 13:12:08 +00:00
igneum-labs
164dc99413 execrpc: one gate for every execution-layer RPC call the app makes (ledger N7, main's rule for 0.3.19)
A node before the exec RPC bounds fix (every 0.3.17 node) dies when a method that resolves a block number or indexes the record vector is asked while its exec follower holds no record; PC 1 crash-looped on two callers in one night (eth_getBlockByNumber from the clock sample, then igneum_getAssignedShards from the prover loop: 'panicked at igneum/exec/src/rpc.rs:808:35: range start index 1 out of range for slice of length 0'). Every caller (prover.rs's evm_rpc, update.rs's clock sample, extnode's rpc for chainfacts and the external-node probe) now goes through execrpc::call: SAFE_ON_EMPTY methods go out, GATED ones wait for igneum_getExecStatus's executedTipHash, an unclassified method is refused. The test every_caller_goes_through_the_gate scans src/ for JSON-RPC requests built elsewhere and for unclassified exec method names.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:12:08 +00:00
igneum-labs
089b078a3a Miner app: plug, tune, play (the project lead, 7 October 2026): node readiness gate, the retry ladder, no permanent fault, fault lines to the intake, the signed cards job, the fault-class register
docs/plans/miner-faults.md: MF-1 to MF-7, each with its rule, test and gate line.
- MF-1/MF-2: a worker starts and is judged only when the node is READY (synced and igneum_getExecStatus reports an
  executed tip; execrpc::probe every 5 s off the engine thread); the node watchdog never counts the catch-up (settled
  once read synced; 30 min cap before that; any RPC answer is a sign of life); the watchdog restarts on a ladder 10 s,
  30 s, 2 min, 5 min, then every 5 min for ever (watchdog::RETRY_LADDER_S); the faulted state and the one-restart
  budget are gone (tools/ci/permanent-fault-check.sh in the gate); a node-caused restart resets the ladder at sync.
- MF-3: the hot-plug pass starts a recovered or revived card's worker (unchanged rule, now in the register).
- MF-4: the status clock starts at ready (program loaded), loading bounded by 300 s; a self-test failure holds the
  card 30 min with the reason on its row, released on a driver change; a crash loop climbs the ladder; the pack is
  exported once a minute for every card (a refused pack forces one).
- MF-5: the app reads template_wait=, template_ms=, identities_active= from the 0.3.20 miner's STATUS; waiting on
  the node is never the card's fault; the row says node slow; every node-wait label clears on the first rate.
- MF-6: a miners hold belongs to the job that took it and releases when that job is gone or at its own cap.
- MF-7: the engine owns every igneum-miner it started: an untracked one on this engine's node RPC is killed at start,
  after every stop and every minute, one line and one fault report per kill; a restart kills the old process first.
- Every fault line posts one FAULT line to the log intake (label fault-<id8>, app and node version, 60/h cap).
- The signed cards job kind (per card enabled, identities, power_pct; refused for a card the machine lacks; applied
  through the app's own card path, persisted, read back): packaging/ota/publish-jobs.sh add --kind cards.
- LG-4 as a job: relay/playbooks/first-share.ps1 and tools/fleet/first-share-gate.mjs (no Windows box yet).
- tools/reliability: the fault injector with one step per class (catch-up, card-appears, own-restart, zero-ladder,
  no-status, node-silent, one-card-fails, orphan-miner); fake-worker.mjs lists devices and fails self-tests on command.
- master's build tooling (97255a4e) and release-0.3.20's igneum-pow taken into the worktree for the box routes.
Box: app 198 + 27 + 8 tests green on igneum-build-2; the tree gate green (33 checks).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:11:48 +00:00
igneum-labs
cc444e8551 0.3.21: version strings (the tree after 0.3.20's cut: driver-check edac467d first; miner-reliability's app half, the under-12 GB prove-instead routing and the per-architecture prover server follow)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 13:10:44 +00:00
igneum-labs
53cd1ee767 Driver table: a referer per row, sent as curl -e (drivers.amd.com answers 403 without an amd.com one; the AMD row carries it); a plain user agent on the download
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit edac467dbd)
2026-10-07 13:09:47 +00:00
igneum-labs
015e6d5a6a Driver table: the NVIDIA 617.42 and AMD 26.9.2 rows measured on igneum-build-2 (sha256, size, Authenticode subject from the vendors' own files); the stray #[test] above the Intel test's doc comment removed
NVIDIA GeForce Game Ready 617.42 WHQL (6 October 2026): us.download.nvidia.com/Windows/617.42/..., 990,853,168
bytes, sha256 f115c927..., subject CN=NVIDIA Corporation (DigiCert G4). AMD Software Adrenalin 26.9.2 WHQL
(29 September 2026, the win11-b build): drivers.amd.com/drivers/whql-amd-software-adrenalin-edition-26.9.2-win11-b.exe
(an amd.com Referer required), 1,000,800,840 bytes, sha256 593c1d73..., subject CN=Advanced Micro Devices (Sectigo).
Read on the box: curl, sha256sum, the PKCS7 out of the PE security directory through openssl pkcs7 -print_certs.
The table's placeholders are gone: every row installs. The drivertable test sample, the mock and the view test name
the real NVIDIA release. detect.rs:990 carried a #[test] above the doc comment of the Intel test from the cherry-pick,
the test build's one warning ("duplicated attribute"): removed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 80787ea024)
2026-10-07 13:09:47 +00:00
igneum-labs
d00772bf20 Driver check: the app detects a missing or old driver per card and installs it on one click from the vendor's own server (branch driver-check, 7 October 2026)
the project lead: can the drivers be packaged with the miner, for all cards, with the system knowing which to install if not
present. Not bundled: detected and installed on one click. A per-vendor table rides the signed manifest (drivers.json:
min_version, the version on offer, the vendor's URL, size, sha256 and its source page, the silent arguments, the
restart exit codes, the Authenticode signer, the Linux and HiveOS package), validated by the signer and the app alike
(src/drivertable.rs, shared), written to <app data>/drivers.json by ota.rs. Each card's driver version is read at
every detection (nvidia-smi's driver_version; Windows' DriverVersion for AMD and Intel) and compared; a missing or
old driver puts the offer on the card's row, on the dashboard and on the first-run list. The click downloads with
curl (resume), checks size, sha256 and the Authenticode subject, runs the installer through one elevated prompt
(platform::elevated_command, the PC 1 driver job's shape), reports restart required with a Restart now button, and
never restarts by itself; the miners keep mining. macOS: no step; Linux and HiveOS: the package line. Dry run through
IGNEUM_DRIVER_DRY_RUN or the table. Tests: the table, the versions, the offers per tier, the exit codes, the
Authenticode verdicts, the download against a mocked vendor server on 127.0.0.1, the UI's strip per state; the mock's
drivers scenarios; captures light and dark in docs/plans/driver-check-shots. publish-manifest.sh --drivers carries the
table. Also the doubled #[test] in detect.rs from the cherry-pick.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 3f0ef65786)
2026-10-07 13:09:46 +00:00
igneum-labs
147fa07358 Proving refuses a card under 12 GB and says why (main's rule, 7 October 2026): MIN_VRAM_MB_PROVE_ANY 11,800 and the sentence "proving needs a 12 GB card; mining continues" in provedefault.rs with its test, the prover loop refusing before the sync wait when every present NVIDIA card is under it, the tile sentence in the UI with its view test; the fleet's p1-3080 died at the compressed step 29 of 29 with 0 paid; the measured SP1 threshold moves the line
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 12:13:33 +00:00
igneum-labs
00e8c2d1b4 Remote jobs: cards_leave_off, a run job's --cards-off cards restored as OFF on any exit (persisted by the app's own card path)
The way to hold a card out of mining past a job without a script on api/cards (the 6 October rule): the runner's hold
is built with enabled=false (identities and cap kept), the report line says LEFT OFF, publish-jobs.sh carries
--cards-leave-off. For the Arc B580 on PC 1 while its worker fix rides to the shipped app. Test:
cards_leave_off_restores_the_card_as_off_with_its_settings_kept (igneum-app 157 of 157 on the box).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 9e794503d2e9689ae3a0996e703cb97ea6d95cef)
2026-10-07 11:31:55 +00:00
igneum-labs
0539eeb252 Intel Arc in the app (0.3.20): vendor intel from the OpenCL vendor string and the Windows name, the INTEL badge and its token, the no-cap row naming IGCL, the measure-only tune words, the view test and the ui-mock scenario (the six app files of intel-arc 18453bb1, applied as its own diff; the test's prove sentence in this tree's wording)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 11:25:05 +00:00
igneum-labs
20796156e1 ember-heat (0.3.19): the region and price prompt, the heat cards and lines, the cost-against-rent row
First run gains step 2 of 3 (the region list, the price per kWh prefilled from the public table and typed, never
fetched, the restricted line for Russia's regions and China from future.md 4.4 and 8.3 with the standing sentence);
Settings gains Electricity and Heat mode; the Cards strip and every row's Ember line show the duty and the heat in
watts; a resting card, the pill and the big button say heat mode; Earnings gains the miner's cost per MH/s-hour at
their price beside the bench log's measured rental rate with the verdict. The money symbol follows the region.
heat-region.test.mjs checks the Russian entry, the bench-log rate and the words; the mock gains heat and heat-rest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 8099bbfd46)
2026-10-07 10:50:05 +00:00
igneum-labs
38486b01f8 ember-heat (0.3.19): heat mode in the engine, the loop, the rest and the release (mission item 7)
Ember holds a room temperature or a schedule and the hash follows the duty cycle: the miners run for a share of
every 10-minute period and stop for the rest (src/heat.rs, the PI loop decided once per period; engine.rs tick_heat,
heat_rest and heat_release the way a remote job holds the cards). The temperature source is a typed reading (fresh
two hours) or the coolest card's sensor after 3 minutes of rest with the cooling tail taken off by its slope; no
hardware the app does not have. Settings carry the region, the switch, the set point, the schedule with the window's
clock offset, the typed reading and the learned idle offset; state.heat carries the phase, the duty, the watts and
the one line; POST /api/heat and /api/region. One HEAT line in the log every 30 s for the gate reader. 8 tests with
a model room: a typed reading and the card sensor alone each hold within a degree for four hours.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 85c619f578)
2026-10-07 10:49:50 +00:00
igneum-labs
8debc7262a ui-ota (0.3.20): Settings > Interface, the health ping, the first-paint error and the gentle reload
"Interface <version>, over the air, <date>" or "built in", with the help line for pending, refused, held back and
skipped; the "Use the built-in interface" switch (POST /api/ui/builtin). The page posts /api/ui/health once after its
first paint, or the first script error it catches before that; when the served interface changes under it, the page
reloads itself only when idle (no input focused, no sheet or update card open, on the dashboard). ui-ota.test.mjs
covers the words, the reload rule, the ping and that the page loads no remote script.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit b6a0fd0d75)
2026-10-07 10:43:52 +00:00
igneum-labs
e342b270b1 ui-ota (0.3.20): the manifest's interface channel and the engine that swaps a signed dashboard bundle in
The signed manifest gains a "ui" object {version, sha256, size, url, min_engine, signature}; the entry's own Ed25519
signature (the release key, manifest::ui_sign_bytes) and the manifest's cover it. src/uiota.rs: the hourly check hands
the entry over; a bundle for this engine is downloaded, checked (size, sha256, signature), unpacked next to the current
one and swapped by an atomic pointer; the server serves the bundle's fixed file names in place of the embedded ones;
the first page load starts a 10 s wait for the page's health ping, and silence, a first-paint error, a missing
index.html or a renamed bundle rolls back to the embedded interface and marks the version bad for good. No "ui"
object retires the bundle (the kill switch). settings.ui_builtin and state.ui carry Settings > Interface.
igneum-ota-sign gains sign-ui and verify-ui. Tests: a good bundle applies, a bad signature is refused, a too-new
min_engine is ignored, a broken bundle rolls back, every bad manifest field fails.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit d7e6c65414)
2026-10-07 10:43:51 +00:00
igneum-labs
6908631196 miner-ui-5: live-dag.js 2.0.2 (master 6c70b948, byte-identical), fps 60 and narrow on the phone-width card, four captures reshot
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 0cb2d9a676)
2026-10-07 10:43:51 +00:00
igneum-labs
ba329e3273 0.3.20: this feature tree renumbered (0.3.19 is the app-only miner-ui-5 cut); plan moved to release-0.3.20.md
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 09:35:42 +00:00
igneum-labs
4ae63ca444 prover loop: no records-indexing poll until the node's exec follower holds a record (ledger N7, PC 1 on 0.3.18)
The 0.3.18 clock-sample gate stopped one caller; the prover's first igneum_getAssignedShards after the node reads synced killed PC 1's 0.3.17 node the same way (rpc.rs:808, records[1..=0] on an empty vector) because its follower loads after the sync flag. The loop now waits on igneum_getExecStatus's executedTipHash, the same gate.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 09:34:08 +00:00
igneum-labs
df4a90e1d8 miner-ui-5: live-dag.js 2.0.1 (the site lane's real-data options, byte-identical), window 60 on both scenes
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 49db28fb9c)
2026-10-07 09:12:43 +00:00
igneum-labs
fa64025de5 miner-ui-5 (0.3.19): the ladder on every page, the count-up, the block card, Earnings in IGN first, EMBER 02 scene
View: poisson, ignPerDay, ladderRungs (every threshold from the node's params: dust, weightWindow, presenceWindow),
blockCard, earningsLines (IGN first, the typed price never fetched, the share and rank, IGN per kWh), cardIgnDay,
timeline, profileWords; FIELDS names every number's RPC field for the title on hover. Overview: the Poisson
count-up until the first block, the block card in place with Save the card (a canvas PNG, no network call), Copy the
link and the explorer, the ladder strip. Earnings: the six lines, the ladder card, Your first hour. Prove: the shard
card. Cards: IGN a day per card. Settings: Make my page public. The chain scene is the site lane's EMBER 02 pack
(live-dag.js and proof-core.js byte-identical): the compact card fed by the page's own api/live read, Inspect opens
the full scene with the block inspector in the site's words. ui-mock: scenarios firstwait, firstblock, ladder,
api/ladder, api/card. view.test.mjs: a Devnet 2 key walks every rung; 47 UI tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 32793b686a)
2026-10-07 09:12:43 +00:00
igneum-labs
8a8be1da92 miner-ui-5 (0.3.19): the ladder's engine half: ladder.json, api/ladder chain facts, the block card's PNG
src/ladder.rs: this machine's record (first block by card, hash joined to the miner's ACCEPTED line by nonce from the
node's PoW accepted line, blocks per UTC day, VOTE and LOCK lines as the signing record and streak, paid shards, the
milestone at 1, 100, 1,000, every 10,000th and the first block of a new card, the first-hour marks); persisted, in
api/state.ladder. src/chainfacts.rs: GET /api/ladder, getFinalityWeights through the node's EVM port when it answers
igneum_getFinalityWeights (owed), else the observer's relay plus /api/stats; this machine's keys ranked; the source
named. src/card.rs and POST /api/card: the page's 1200x630 PNG written under <data root>/cards/ and revealed.
settings.profile_public behind api/settings. Hooks in engine.rs (block, node line, vote, lock, synced, mining) and
prover.rs (paid shard). Box: 190 + 27 + 8 tests.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 959c4a5fa9)
2026-10-07 09:12:43 +00:00
igneum-labs
f4ddfe5b0a miner-ui-4: carry the clock sample's exec-record gate (0f6b4650, ledger N7); version words follow the 0.3.19 renumbering
Only update.rs from 0f6b4650; its version bumps stay with the shipper's cut.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 032e1f8717)
2026-10-07 08:33:27 +00:00
igneum-labs
f223ebc9ed 0.3.19: this tree renumbered again (0.3.18 is the app-only N7 cut); plan moved to release-0.3.19.md
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 08:28:05 +00:00