igneum/docs/plans/driver-check.md
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

7.1 KiB

Driver check: the app detects a missing or old driver and installs it on one click (branch driver-check, 7 October 2026)

the project lead: "can we package the drivers with the miner? for all cards? and the system knows which to install if not present". The answer given: not bundled (size, vendor licences, staleness), but detected and installed on one click. Built off the release-0.3.20 app tree (082f70fb) for 0.3.20's app or the next cut; every cargo build and test on the box.

1. What is built

Piece Where
The per-vendor table, validated in the signer and the app alike (Table::parse): min_version (what the worker needs), version, the vendor's own URL, size, sha256, the page the hash was read from, the silent arguments, the exit codes that mean "restart required", the Authenticode subject word, the Linux and HiveOS package app/igneum-app/src/drivertable.rs (pure, shared with src/bin/ota-sign.rs), packaging/ota/drivers.json (today's table)
The table rides the manifest: drivers object, parsed and validated with the rest, written as is to <app data>/drivers.json, re-read on every change; the app never ships a driver src/manifest.rs (Manifest.drivers), src/ota.rs (write_drivers, take_drivers_change, drivers_table), `packaging/ota/publish-manifest.sh --drivers
Each card's driver version: nvidia-smi's driver_version for NVIDIA, Windows' DriverVersion (the adapter row) for AMD and Intel; CardState.driver_os src/detect.rs (the query, the Adapter.driver field, assemble)
The check at first run and every detection, and on every table change: the offer per card (CardState.driver_offer: status missing, old, fine or none; the row's sentence; installable on Windows only) src/engine.rs (refresh_driver_offers, called from the Detected arm and tick_update)
The click: download from the vendor's server (curl with resume into <app data>/drivers/), size and sha256 against the table, the Authenticode signature (status Valid, subject carries the vendor), then the installer through ONE elevated prompt (platform::elevated_command, the PC 1 driver job's shape), the exit code read (0 installed, a table code = restart required, else an error), "Restart now" on the row; the app never restarts by itself; nothing else pauses (the miners keep mining) src/drivers.rs (start_install, download, exit_code_of, restart_now), src/engine.rs (driver_install, driver_event), src/server.rs (POST api/drivers/install {vendor}, POST api/drivers/restart)
The row: "Install the NVIDIA driver 581.57 (965 MB). Driver 566.36 is older than the 570.00 the worker needs." with the Install button on the dashboard's card row and on the first-run card list; the progress line; "installed, restart Windows to finish" with Restart now; the error with Install again; macOS "no driver step"; Linux and HiveOS the package line, no button ui/app.js (View.driverWords, the gl-driver strip, setupDriverHtml, the click handlers), ui/app.css
Dry run: IGNEUM_DRIVER_DRY_RUN=1 or dry_run: true in the table: the download and every check run, the installer does not (the row says so) src/drivers.rs, src/engine.rs
Tests: version compare, the table's parse and refusals, the offers per tier (missing, old, fine, Apple, Linux, HiveOS), exit codes and Authenticode verdicts, the download against a mocked vendor server (a std TcpListener on 127.0.0.1: the right sha256 passes, a wrong one is refused with the part file gone, the file in place is kept), the manifest's drivers validation; the UI's strip per state src/drivertable.rs tests, src/drivers.rs download_tests, ui/view.test.mjs
The mock's scenarios for the captures: drivers, drivers-running, drivers-reboot, drivers-error, drivers-mac tools/ui-mock/server.mjs

The captures (the installed Mac window's --snapshot on the mock, 1280 x 900, light and dark): docs/plans/driver-check-shots/01 to 12: the dashboard's Cards page with the offers (01, 02), the download running (03, 04), installed and Restart now (05, 06), the error (07, 08), macOS (09, 10), the first-run card list (11, 12).

2. The table today (packaging/ota/drivers.json)

Vendor min_version On offer Source State
Intel 32.0.101.9034 (the Arc driver the worker's rotate rewrite is proven on) 32.0.101.9034, 932,631,144 bytes, sha256 72ba7eea... downloadmirror.intel.com/929959, Intel's page 785597 (SHA512 printed there; the sha256 read on PC 1 on 7 October) measured, live
NVIDIA 570.00 (CUDA 12.8) 581.57, approximate size, sha256 of zeros us.download.nvidia.com, the driver page prints the sha256 placeholder: the app refuses to install it (the download's sha256 never matches) until the hash is read from the page and written here
AMD 32.0.32000.0 (Adrenalin 25.x) 26.9.2, approximate size, sha256 of zeros drivers.amd.com, the download page prints the sha256 placeholder, the same

Apple: none. The exit codes: Intel 14 and 1014 (the bootstrapper's wrap, measured on PC 1), NVIDIA 1 (approximate: NVIDIA's installer returns 1 for "restart required" in silent mode), AMD 3010 (the MSI code, approximate). A wrong code reads as an error on the row and the install is marked failed, never as a success; the table fixes it without an app cut.

3. Consequences per tier

Tier What the user sees
A home miner with a new card and no driver (Windows) the first-run card list says "Install the driver (). No driver was found, so this card cannot mine yet." with the button; one click, one administrator prompt, the restart line if the installer asks; the other cards mine through it
An old driver (Windows) the same row with "Driver X is older than the Y the worker needs"; mining on that card may already fail (the worker's self-test) and the row says why
macOS "Apple silicon: no driver step, macOS carries it." in the details; no button
Linux, HiveOS "Linux: install the package nvidia-driver-570 (the worker needs 570.00 or newer)." or the HiveOS line; no installer
A rig one install at a time (the engine refuses a second while one runs); each card's row carries its own offer
A pool user nothing changes

Sizes: the installers are 870 MB to 1 GB each; the download lands in <app data>/drivers/ and stays (a second click reuses it when its sha256 still matches). Time: the download at a home line of 50 Mbit/s is 2.5 to 3 minutes; the install 1 to 4 minutes; the prompt is the only wait on the user.

4. Not done, and what follows

  • The NVIDIA and AMD rows' hashes: read from the vendors' pages and written into drivers.json, then published with publish-manifest.sh --drivers packaging/ota/drivers.json. Until then those two rows are refused by the app's own check.
  • The Linux install path stays a line (the brief).
  • A PC 1 dry run of the Windows path (the installer not run, the download and the checks live) is one IGNEUM_DRIVER_DRY_RUN=1 engine start away; not run today (PC 1 is the project lead's desk and mines).