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)
Intel's compiler turns rotate(x, (0u - n) & 31u) into a rotate LEFT by n: lane 0's register trace on the B580 diverged
at instruction 6 of iteration 0 (rotr) and nowhere before, in both exchange modes, with every other family and the
dataset kernels bit-exact. proto-opencl/intel_rotr.h rewrites the one helper line when the device's vendor or
platform string holds Intel (host.c's buildProgram and the prepare path), no other vendor sees a change, no pack or
consensus text moves. proto-opencl/test_intel_rotr.c (the pre-push gate runs it) feeds the line through the rewrite
under Intel, AMD and NVIDIA strings and asserts the outputs.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 26e135a362718a68a842da59080b43e93afd9dc2)
tools/heat-gate.mjs reads the HEAT lines of an app log and passes a hold within 1 degree for 4 hours with the hash
following the slice; its self-test fires on a known hold, a drift, a hash through the rest, a short log, an empty log
and a log without readings, and sits on the one gate beside heat-region.test.mjs. docs/plans/ember-heat.md carries
the words, the loop, the sources, the per-tier table and the runbook for the project lead's desk (this lane never touches PC 1).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 0d5fc6d258dee4774ebe7ea760736c9f05026d06)
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 a9565036e5)
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 ce42c027cf)
publish.mjs packs the fifteen served files with one fixed mtime (reproducible; the self-test checks it), hashes, signs
the entry through igneum-ota-sign sign-ui with the key in ~/.config/igneum (never read or printed here), copies the
bundle into the folder's ui/ and hands ui.json to publish-manifest.sh --ui, the one writer of the signed manifest,
which verifies the entry and the bundle's hash before signing; --dry-run writes nothing, --verify reads the live
manifest back against dl/<token>/ui and dl/public/ui; --no-ui withdraws the channel. Both self-tests sit on the one
gate. docs/plans/ui-ota.md: the shape, the engine, the security notes, the operator recipe, the tests, per tier.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 3b6ccfc3ce)
"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 a9ca84c90f)
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 3417f1e1fa)