diff --git a/docs/bench-log.md b/docs/bench-log.md
index 0332d32b..bbdd24c8 100644
--- a/docs/bench-log.md
+++ b/docs/bench-log.md
@@ -770,3 +770,16 @@ millisecond numbers and never the one line a person needs.
Checked on the Mac with a fake 60 s skew (`IGNEUM_APP_FAKE_SKEW=-60`): the banner, the node card, the blocked Start
button and the held miner all showed; with the real clock the HTTPS source read +0.4 s and the block source agreed.
+
+## 4 October 2026, first machine on the Igneum Miner app: PC 2's RTX 5090 at 118 MH/s, via Setup.exe
+
+the project lead's second PC (a clone of the first; the app's per-install machine id `1ccfe586` keeps its keys apart), installed from the
+runner-built `Igneum-Miner-Setup-0.3.0.exe` (unsigned, SmartScreen "run anyway"), the one-click package: prebuilt NVRTC
+worker, no toolchain on the machine. First attempt sat at "waiting for peer": the PC's clock was 62 s slow after a power cut
+and `igneumd` rejected every relayed block ("the block timestamp is too far into the future"; the 10-s skew bound from the
+hardened timestamp rule) and processed 0 blocks for 12 minutes with no visible reason. Clock set by hand; the node caught up
+(46 blocks in the next 10 s at 12:27:53 BST), the 5090 started inside the app and ran at 117 to 119 MH/s with 34 accepted
+blocks in the first minute, CPU re-check OK on every share, the integrated AMD chip at 3.3 MH/s beside it. Two defects
+from the run, both fixed in the app the same hour: no clock-skew warning (now detected from the node's warning, block
+timestamps and an HTTPS Date header; Start is blocked above 10 s), and the node card stayed on "syncing" after the late
+catch-up while the miner was already accepted (state now re-derived every poll).
diff --git a/site/bench.html b/site/bench.html
index 4cfb840c..de8c1f6e 100644
--- a/site/bench.html
+++ b/site/bench.html
@@ -68,7 +68,7 @@ footer{border-top:1px solid var(--line);padding-block:32px 48px;font-size:13px;c
Engineering log
Every measurement the project has made, newest at the bottom, written by the people and agents who ran it, with the commands and hardware. Prototype numbers are not mining numbers and say so.
-
+
Igneum bench log
Append-only. Every number here was measured on the machine named, on the date given.
CI. .github/workflows/ci.yml runs on every push and pull request of the private repository: igneum-pow cargo test --release and the igneum-census build (49 s), the two simulators' --quick modes under a 120-s timeout (49 s for the job; sim/finality_v2.py --quick is now a true smoke run, 149 s at nice 19 on this loaded Mac and under 40 s on the runner, was 745 s; sim/difficulty/sim.py --quick is new, 36 s here), the site build, an internal link check of site/*.html (151 links, 0 broken) and a gh-free identity grep of the public export list after the generic scrub (tools/ci/identity-check.sh, tools/ci/forbidden-strings.txt: 157 files, 0 hits). First run green: https://github.com/igneum-network/igneum/actions/runs/37193811336, 54 s from trigger to completion. The node fork is gitignored and too big for the free runners today; the workflow says so.
Not done: igneum-harness-sim's per-block cost on the devnet-v4 line (about 70 ms here against 3 ms on the ordering-layer branch, the execution layer's follower) is what still bounds the harness, not the clocks; the fast-time presence window floors at one checkpoint; the GPU workers were not run on fast time (the CPU miner proved the swap).
4 October 2026, first finality lock on the live devnet: checkpoint 242 at 77.4% of all weight, two hours after genesis
-
Live devnet v4 (genesis 10:05 BST). The weight window and min_daa are 7,200 DAA seconds, so no checkpoint could lock before DAA 7,200. The first checkpoint past it, index 242 (block 59b4a314, blue score 7,261), locked at 12:03:44 BST with 77.4% of total weight and 77.4% of active weight signed, 12 aggregated votes from 17 vote keys (two RTX 5090 machines with 8 identities each, the Mac's Metal miner, the integrated AMD chip's identities), floor 2/3. The certificate (23 headers) was stored and carried in block 1e2439a1; observer.mjs logged checkpoint_locked 0.7 s after the miner's own LOCK line. The floor was raised to 2/3 this morning (O-3.15); this is its first live lock. Difficulty at the moment of the lock was mid-oscillation (93M to 99M, see the oscillation finding), which did not affect voting.
+
Live devnet v4 (genesis 10:05 BST). The weight window and min_daa are 7,200 DAA seconds, so no checkpoint could lock before DAA 7,200. The first checkpoint past it, index 242 (block 59b4a314, blue score 7,261), locked at 12:03:44 BST with 77.4% of total weight and 77.4% of active weight signed, 12 aggregated votes from 17 vote keys (two RTX 5090 machines with 8 identities each, the Mac's Metal miner, the integrated AMD chip's identities), floor 2/3. The certificate (23 headers) was stored and carried in block 1e2439a1; observer.mjs logged checkpoint_locked 0.7 s after the miner's own LOCK line. The floor was raised to 2/3 this morning (O-3.15); this is its first live lock. Difficulty at the moment of the lock was mid-oscillation (93M to 99M, see the oscillation finding), which did not affect voting.
+
4 October 2026, the gfx1036 worker fault and what the Mac could and could not reproduce
+
PC 2 (RTX 5090 plus the Ryzen's integrated gfx1036), package 0.3.0 prebuilt workers. The CUDA worker compiled the pack with NVRTC (after -default-device) and mined at 124.2 MH/s, equal to the nvcc-built worker, 0 rejected, CPU re-check clean. The OpenCL worker (igneum-worker-opencl.exe --pack, path prebuilt-generic) self-tested PASS and mined correctly at 3.3 MH/s for 577 s (8 accepted blocks), then from about 600 s every job "completed" in 0.5 ms with no hash: 906 jobs became 56,384 within 30 s, the miner reported 4.3 GH/s inside jobs and the dashboard over 1 GH/s, with no error line, no exit and no restart. PC 1's cl.exe-built worker on the same host.c serve loop ran over an hour without this.
+
Root cause, as far as it can be stated: the AMD runtime kept answering clEnqueueNDRangeKernel, clWaitForEvents and the blocking clEnqueueReadBuffer with CL_SUCCESS while running nothing, so the loop walked its chunks at memory speed and reported the stale output buffer as a finished job. What flipped the runtime into that state at 600 s is not visible in the logs and the job path itself leaks nothing (one event per chunk, created and released; verified below). The two plausible triggers are a device reset of the integrated GPU with the runtime swallowing it (the generic path is the only one that self-tests, which reads 256 MiB back and runs the three vector warps at start; an hourly prepare would do the same work again on a second queue while jobs run) and a runtime limit reached after about 900 jobs. Neither reproduces on Apple OpenCL:
+
Run on the M5 Max (Apple OpenCL 1.2, pack-a, 2^22 nonces per job)
Jobs
Job time ms (mean, min, max)
Faults
Live objects at the end
20-minute soak of the shipped generic worker
3,365
412 / 305 / 591
0
not counted (that build had no counters)
1,200-job soak of the hardened worker (events and buffers counted)
1,200
411 / 315 / 549
0
0 events, 4 buffers (cache, dataset, out, init words); 1,200 events created and released
the same worker with IGNEUM_FAULT_TEST=6 (the dispatch skipped from chunk 6 on, the runtime "succeeding")
6 real + 1
1: the output buffer is unchanged since the previous dispatch, exit 3
+
So the fix is defensive at three levels (commit 112acf6 and vendor devnet-v4 f9392600): the worker treats every OpenCL error in the job path as fatal, requires CL_COMPLETE on the dispatch event, refuses a chunk 20x faster per nonce than the running mean or an output buffer unchanged since the previous dispatch, prints live object counts every 200 jobs and exits 3 on any of these; the miner kills and restarts a worker whose job time per hash drops under 1/20 of the mean or whose interval rate exceeds 10x the mean before it, rolls its counters back to the last report and prints WORKER FAULT; the launcher shows worker fault and restarting for that card instead of a rate. The next gfx1036 run says which guard fires first; that line is the diagnosis the Mac cannot give.
+
4 October 2026, a node 60 s behind the clock is silently dead (PC 2's first app install)
+
PC 2 came back from a power cut with its clock 60 s slow. igneumd connected, then logged HandleRelayInvsFlow flow error: the block timestamp is too far into the future: block timestamp is ... but maximum timestamp allowed is ... for every relayed block, processed 0 blocks and the app sat on "waiting for a peer" with nothing to say. The consensus rule is right (a header may not be ahead of the node's clock by more than the tolerance, check_block_timestamp_in_isolation); the reporting was not. The node prints one WARN per relayed block with two millisecond numbers and never the one line a person needs.
+
What
Where
Now
The app reads that WARN, takes block timestamp - maximum allowed as a lower bound and shows "Your clock is at least N seconds behind the network; mining cannot start until it is fixed" on the node card with a Sync clock button (macOS sntp -sS time.apple.com under an administrator prompt, Windows w32tm /resync elevated, Linux chronyc makestep / timedatectl) and the manual steps
Independent of the node: once blocks arrive the engine samples the latest block's timestamp through the node's Ethereum JSON-RPC every 10 s and takes the median of local minus block time over the last 9 (behind only; a stalled chain reads as ahead); and an HTTPS Date header from dl.igneum.network at start and every 10 min (either direction, 1 s resolution). Over 5 s: a warning. Over 10 s (the consensus bound): the Start button is blocked and running miners are held
The node itself should log one clear line at WARN, once, not per block: clock skew: local time is N s behind the median peer block time (and the same for ahead, when its own templates are refused by peers). Filed for the devnet-v4 worktree owner; the app does not patch the node
docs/plans/node-changes.md
filed
+
Checked on the Mac with a fake 60 s skew (IGNEUM_APP_FAKE_SKEW=-60): the banner, the node card, the blocked Start button and the held miner all showed; with the real clock the HTTPS source read +0.4 s and the block source agreed.
+
4 October 2026, first machine on the Igneum Miner app: PC 2's RTX 5090 at 118 MH/s, via Setup.exe
+
the project lead's second PC (a clone of the first; the app's per-install machine id 1ccfe586 keeps its keys apart), installed from the runner-built Igneum-Miner-Setup-0.3.0.exe (unsigned, SmartScreen "run anyway"), the one-click package: prebuilt NVRTC worker, no toolchain on the machine. First attempt sat at "waiting for peer": the PC's clock was 62 s slow after a power cut and igneumd rejected every relayed block ("the block timestamp is too far into the future"; the 10-s skew bound from the hardened timestamp rule) and processed 0 blocks for 12 minutes with no visible reason. Clock set by hand; the node caught up (46 blocks in the next 10 s at 12:27:53 BST), the 5090 started inside the app and ran at 117 to 119 MH/s with 34 accepted blocks in the first minute, CPU re-check OK on every share, the integrated AMD chip at 3.3 MH/s beside it. Two defects from the run, both fixed in the app the same hour: no clock-skew warning (now detected from the node's warning, block timestamps and an HTTPS Date header; Start is blocked above 10 s), and the node card stayed on "syncing" after the late catch-up while the miner was already accepted (state now re-derived every poll).
diff --git a/site/build.mjs b/site/build.mjs
index b81346d5..9d7c0f91 100644
--- a/site/build.mjs
+++ b/site/build.mjs
@@ -173,6 +173,7 @@ if (existsSync(join(docs, 'bench-log.md'))) {
['Finality floor', 'Finality floor raised to two thirds of all weight'],
['First hourly program swap on the live devnet', 'First live hourly swap: no pause on Mac, NVIDIA or AMD'],
['First finality lock on the live devnet', 'First live finality lock: 77.4% of weight, 17 voters'],
+ ['First machine on the Igneum Miner app', 'First machine on the one-click app: a 5090 at 118 MH/s'],
['Devnet v4 cut-over', 'Devnet v4 live: generator v2, two-thirds floor, fresh chain'],
];
function shortTitle(t) {
diff --git a/site/journey.json b/site/journey.json
index 7aa6fabf..1fbf25c0 100644
--- a/site/journey.json
+++ b/site/journey.json
@@ -50,6 +50,21 @@
}
],
"log": [
+ {
+ "date": "2026-10-04",
+ "text": "The gfx1036 worker fault and what the Mac could and could not reproduce",
+ "short": "The gfx1036 worker fault and what the Mac could and could not reproduce"
+ },
+ {
+ "date": "2026-10-04",
+ "text": "A node 60 s behind the clock is silently dead",
+ "short": "A node 60 s behind the clock is silently dead"
+ },
+ {
+ "date": "2026-10-04",
+ "text": "First machine on the Igneum Miner app: PC 2's RTX 5090 at 118 MH/s, via Setup.exe",
+ "short": "First machine on the one-click app: a 5090 at 118 MH/s"
+ },
{
"date": "2026-10-04",
"text": "First finality lock on the live devnet: checkpoint 242 at 77.4% of all weight, two hours after genesis",