publish-jobs.sh --deploy POSTs the new stamp (published_at plus 8 hex of the file's sha256) and the added id to the
relay's /wake once the live file verifies. The relay token goes in a 600-mode header file, never on the command line
or the screen. Prints "woke the apps (stamp ...)" or a one-line warning; the apps' 2-minute poll still catches it.
tools/jobs.mjs status reads relay_wake (one row per publish with the ids it added) and prints "woken +N s after the
publish" for a machine's latest job that a publish added; nothing when the table does not exist yet.
docs/plans/release-0.3.6.md: "Instant jobs" section with the design, the expected latency and a TODO row per machine
for the measured number once 0.3.6 is live. packaging/ota/README.md: the 10-minute poll is history.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
s8-steady.mjs: two nodes, one honest vmine miner at 1 block/s, no flood,
RSS and cache-build count every 60 s, vmmap -summary at 0, 500, 1,000 and
1,500 blocks. Both builds ran 1,500 blocks on the 60x profile: before
41 to 1,342 MB by 514 blocks (9 cache builds, five 256 MiB chunks resident:
KEEP 4 plus one evicted chunk the allocator keeps) then flat, 27 builds in
1,529 blocks; after 319 MB at 510 blocks (1 build), 589 at 1,029 (the second
day's cache, by design), 603 at 1,526, 2 builds. Residual 30 MB per 1,000
blocks on both builds, read as the consensus database and caches filling,
not the PoW cache. JSON and vmmap files under
docs/benchmarks/memory-floods-2026-10-04/.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Report docs/review/redteam-2026-10-04.md: finality attacks s1-s8 plus 34% withholding, 50/50 long partition, F23 and
F24 custom runs, ordering harness, execution suite and EVM smoke, proving hostile tests and a proof flood, difficulty v2
timestamp forging in the simulator. New fails: the fast-time harnesses corrupt the u64::MAX sentinels of the override
(F25), a block or transaction flood grows the node by hundreds of MB in a minute (M30), the coinbase does not fit the
204-byte limit on mainnet, testnet and simnet parameters (M31). F23 and F24 reproduced on this build; F21's bound
measured at one window of the side's own DAA. Scenario scripts under tools/finality-attacks/redteam/.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
tools/harness: IGNEUM_HARNESS_BASE_PORT and IGNEUM_HARNESS_TMP move the test
network's ports and data directory so two agents can run it at once; the u64
sentinel round-trip in overrideParams is fixed with the BigInt reviver from
tools/finality-attacks (ledger F25); s6 records rss_start, rss_delta and
cache_builds per load and reports per-load growth (the old row subtracted one
baseline taken before all three loads, which is how the mempool flood was
read as +270 MB); s7 counts "PoW cache built" lines beside every RSS sample;
--live-only skips the s7 simulator part.
docs/bench-log.md: the 4 October 2026 (night) entry: the floods' growth was
one 256 MiB PoW cache per epoch roll (the engine kept a cache per (epoch,
day) pair, KEEP 4), measured before and after the fork fix (fork branch
fud-memory, 796f758d): submit load +263/+257 MB with 1/1 builds before,
+9/+2 MB with 0/0 after; block flood 302 to 1,085 MB with 3/3 builds before,
300 to 315 MB with 0/0 after. Result JSON under
docs/benchmarks/memory-floods-2026-10-04/.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
9 fee blocks in the 785 blocks of the two fee-paying miners (1.15%, expected 1 in 100 templates), the miners' fee
counters equal the chain's count on both nodes, the control miner at --dev-fee 0 paid nothing.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Conflicts resolved keeping both: engine.rs carries the sweep state (miner-eff) and the node watchdog (reliability);
the STATUS line goes through watchdog::parse_status and still feeds the sweep's rate sample; main.rs declares both
modules; bench-log.md keeps both entries. site/build.mjs keeps master's partial-injected pages and adds the /miners
bench table through the same page() with active: 'miners'; the Miners link is in site/partials/nav.html; sitemap
gains /miners; every generated page rebuilt with node site/build.mjs.
docs/bench-log.md: the fake-worker measurements (slow start one trip and 2.0 s restart, fake-fast guard in under
0.1 s, exit 43 at 8.8 s, CPU re-check stop at 0.5 s, stall guard at 60.1 s with STATUS lines through the silence,
one prepare per epoch with refused retries held; app: zero-rate restart at 79.6 s and faulted at 75.4 s on the
repeat, no-status restart at 90.4 s, silent node restarted at 150.7 s and synced 7.2 s later; no double restart on
the miner's own worker restart). Two defects the harness found are named with their fork commits.
docs/fud-ledger.md and the round-4 review table: M26, M27, X21 Fixed with the commits.
engine.rs: the miner's restart note no longer hides the fault reason on the card.
tools/reliability: the harness matches the miner's stderr lines where they are printed there.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Conflicts resolved keeping both: Settings and SettingsState carry the sweep fields (miner-eff) and dev_fee /
fee_total (dev-fee); the engine's settings snapshot sets both and the DevFeeState line stays.
Decision of 4 October 2026 (evening): the Igneum Miner software takes a visible, switchable 1% dev fee, the norm
for GPU miners; the protocol stays fee-free. The miner side (--dev-fee, the 1-in-100 template counter, the audit
command) is on branch dev-fee of the node fork.
- app: settings.dev_fee (default on) passes --dev-fee 0 to igneum-miner when off; Settings shows the miner's own
"dev fee 1% (1 block in 100) to 0x..." line next to the rewards address with a switch; the engine parses the
miner's start line and its dev-fee block lines (fee_session, lifetime fee_total, an event per fee block)
- packaging/hive: h-manifest.conf, h-config.sh, h-run.sh, h-stats.sh, make-hive-package.sh (igneum-hive-<v>.tar.gz
with the Linux igneumd, igneum-miner and both GPU workers), README with the Flight Sheet, selftest.sh (bash -n,
stub binaries, the three hooks the way Hive runs them, the stats JSON parsed). Hive itself is untested
- infra/cross/build-workers-linux.sh: the NVRTC and OpenCL workers cross-compiled for Linux with zig;
proto-opencl/cl_dynamic.h gains the Linux dlopen branch (libOpenCL.so.1)
- tools/dev-fee/run.mjs: the fee-block test network (two nodes on 29900+, three CPU miners, payouts audit)
- docs/design/miner-dev-fee.md (mechanism, flag, lines, the DEV_FEE_ADDRESS placeholder and the devnet address),
docs/fud-ledger.md E18 and the E5/L9 status line, litepaper "What a miner's hour looks like" paragraph, homepage
miner section note
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Conflict resolved: publish-jobs.sh keeps master's verify command and --tries (the retrying live check) alongside the
build kind's arguments; the usage range covers the merged header.
Conflicts resolved: state.rs keeps both the sweep fields (miner-eff) and the race fields (miner-perf); bench-log.md
keeps both appended entries; publish-manifest.sh keeps master's --override implementation (8082576, the "every
height switch" rule, --verify-only, --tries, the retrying live check) and adds miner-perf's --tuning / --no-tuning
with the carry-over of consensus.override and tuning from the current manifest. One --override case, one parser.
New job kind `build` (jobs.rs, jobbuild.rs, jobrun.rs run_build): free-space check on both sides (20 GB), the
build-inputs zip by sha256, setup inside the distro as root (mingw-w64 posix, clang for bindgen, protoc, zstd, the
Windows rust target; idempotent), sources extracted with the target dir persisting under /root/igneum-build,
cargo build --release native and for x86_64-pc-windows-gnu, cargo test for the manifest's packages, binaries
zstd-compressed and sent to the relay (fn=upload, Blob PUT, fn=drop; 50 MB each) with sha256 in RESULT lines,
STAGE lines with UTC times, a 40-minute default budget and per-stage caps, the Linux side killed on a cap. The
app's runner stays serial (one Active at a time), so a build never overlaps a shard job; nothing stops the miners.
From this version an unknown job kind is skipped by the app (parse_lenient) instead of rejecting the whole file;
the signer stays strict.
Mac side: packaging/windows/push-build-inputs.sh packs a fork worktree, app/igneum-app, brand/icons and
proto-cuda with a manifest (branch, commit, dirty, builds, tests) and the sha256; publish-jobs.sh add --kind build;
tools/build-job.mjs packs, publishes, watches, fetches, checks both sha256 per file and the PE header of every exe
(plus verify-exe.py on igneum-app.exe), and places the binaries where push-inputs.sh, make-payload.sh and the
cloud-devnet scripts look. relay.mjs drop <file> --body carries the body.
Tested on the Mac: 33 app tests (6 new) and the signer's 21; cargo check for x86_64-pc-windows-gnu; the packer
(7.9 MB zip, no target dirs); the publisher against a scratch folder with the rebuilt signer, the old signer
refusing the kind, a bad job refused at signing; the fetch path against the live relay with a real exe (sha256
and PE pass, a wrong sha256 refused; test items deleted). Not run on a PC: the job itself. docs/plans/build-job.md
has the first job for PC 1 and the rollout order (0.3.4 must be on the PCs before a build job is published).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Log drawer: the Logs button shows its open state (Close logs, chevron); a Newest button appears when the user scrolls
up and follow re-engages at the end; a time ruler with error and swap marks, an HH:MM:SS jump box, last error and last
swap buttons; substring search with a match count and highlights; copy the lines in view; the height drags from a grip
(140 px to 70% of the window, remembered); a window under 700 px tall opens a 180 px drawer. The list is virtualised
(19 px rows, only the rows in view in the DOM; up to 20,000 lines kept; wrap mode under 5,000 lines). Polling runs only
while the drawer is open and the window is visible.
Screens: one type scale and spacing scale in app.css, tabular figures everywhere, the bottom bar in pieces (machine name
truncates first, address always short, uptime dropped under 1100 px), tile captions carry their full text as a title,
syncing shows an ETA from the measured block rate, the engine-away state names itself on the node tile, short-window
rules, the key sheet scrolls on a short window, compact settings card rows on two lines, only a block that just arrived
flashes (not the whole strip on first paint).
Performance: the minute grid is drawn once into an offscreen layer; the strip redraws twice a second and at the display
rate only during a flash; nothing draws and the state poll drops to every 5 s while document.hidden. ?debug=1 prints a
budget line every 5 s and exposes window.__igneumBench.
tools/ui-mock: a stand-in engine (node tools/ui-mock/server.mjs) replaying recorded, scrubbed API responses with
scenarios (syncing, nodedown, nocards, integrated, clock, paused, biglog, fresh, job, nvidia), so UI work never
touches a running miner.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Review round 4 X21 and the project lead's levers 5 and 6 (4 October 2026 evening):
- src/watchdog.rs: CardWatch (no status line for 90 s, or hash rate 0 for 60 s while the node is synced: one
restart, then the card is marked faulted with the reason in the UI and the log; the miner's own worker restarts
suspend both rules until ready, so there are no double restarts; exit 43 counts as a watchdog restart) and
NodeWatch (our node silent for 120 s is restarted in-process through the restart kind the remote jobs use, with a
growing delay). State machines with no clock; 11 unit tests replay recorded STATUS and WORKER FAULT lines.
- engine.rs reads STATUS mismatched=, faults= and the WORKER FAULT lines onto the card (faults, mismatched, message);
a faulted card is not restarted until the user changes its settings or resumes mining; other cards keep mining.
- site/miners.html (build.mjs, scrubbed like /bench, rows from site/miner-bench.json): card, generator version, best
MH/s, MH per watt where measured, miner version, date, source, measured by the team or reported by the fleet. In the
navigation beside the engineering log on every page and in the sitemap. One line says there is no other miner to
compare with.
- tools/reliability: fake-worker.mjs (the serve protocol, misbehaving on command), run.mjs (miner guards on a private
test network, ports 29950+) and app-run.mjs (the app watchdog end to end, ports 29960+).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The engine turns a worker's race line into one TUNING {json} line in the app log (card model as the worker names it,
driver, arch, program class loads and wide loads, every variant's MH/s, winner, gain, the card's power cap and
draw, MH per watt), which the existing intake receives; the card state carries the variant for the dashboard and
one event per race. tools/tuning.mjs aggregates the records from miner_logs per card model (median MH/s or MH per
watt, at least 3 samples, de-duplicated per race) and writes tuning.json; publish-manifest.sh --tuning puts it in
the signed manifest (and now takes --override for consensus.override; both are carried over from the current
manifest when not given, --no-tuning drops it); manifest.rs parses it; ota.rs writes <app data>/tuning.json and
removes it when the manifest drops it; procs::spawn takes an environment and every miner starts with
IGNEUM_TUNING_FILE, which its worker reads at every prepare. Dry run of the publisher against a scratch folder:
tuning and override written, carried over, dropped, signature verified.
docs/plans/miner-perf.md: the signed jobs for PC 1 (fetch the race build of the NVRTC worker, then
relay/playbooks/race-5090.ps1 with the miners stopped: 17 variants, 3 rounds, twice) with the exact publish
commands for the main session; not published by the agent.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Three watchers never saw a job finish because the closing upload starts with the app header, not the SUMMARY line,
and a shard run whose stages failed still exited 0.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
the project lead, 4 Oct 2026: 0.3.1, 0.3.2 and 0.3.3 each took eight hand steps and an hour. The tool runs them in order, each
step idempotent and resumable (--from): preflight, bump (six version files, one function, read back), push-inputs,
commit and push, the windows.yml run polled with gh (auth switch before every call), fetch, DMG under the build lock,
copy, signed manifest, one deploy, HEAD/GET verification with sizes and sha256, one console item. --dry-run prints
the plan, --check compares the version files, --self-test bumps a scratch copy. Secrets never printed.
Found by --check: Igneum-Miner.iss and Info.plist were left at 0.3.2 when 0.3.3 was cut (CI passed -Version from
Cargo.toml, so the installer was right; the Mac bundle said 0.3.2 because build-dmg.sh's sed only matched 0.3.0).
Both aligned to 0.3.3; build-dmg.sh now stamps the version with plutil. fetch-ci-artifacts.sh: CONSOLE_SKIP=1.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Observer (tools/observer/observer.mjs): reads the execution layer's JSON-RPC of a node on the proving build
(IGNEUM_EVM_RPC, default the Mac app's node 26800): every chain block's shard plan as it joins the chain
(igneum_getShardPlan by blockHash, one live_proofs row per shard, planned), the proof records of the chain
blocks of the last 10 minutes polled in rotation (igneum_getProofRecords, four in flight, 40 blocks per tick
while active, 10 before activation): proving (in the pool), verified (SP1 proof verified, or carried and checked
by consensus), paid (a carrying segment paid it), with the prover's id8, the carrier, lag in DAA and the payout.
live_state.proving = {supported, active, activation_daa, tip_daa, verifier, pool, blocks_10m,
blocks_fully_proven_10m, shards_proven_10m, shards_paid_10m, median_proof_lag_s, provers_10m}. A node without
the RPCs gives supported false (rechecked every 5 min); an unreachable endpoint is retried every 20 s. Events:
proving (activation, first paid shard), prover_seen. Additive schema (live_proofs, live_state.proving).
API (site/api/live.mjs): proving, and per block shards: [{i, n, state, prover, lag, payout (IGN), pgas}] and
proven; ?window=N (30 to 300 s) for the page's diagnostic long view; LIVE_TABLE_PREFIX reads a test observer's
tables.
Live page (site/live.html), the design change of 4 Oct 2026: three thin strips sharing one time axis, newest at
the right. BLOCKS keeps the per-miner lanes, chain path, blue/red/pending colouring, arrival glow and tooltips;
the lock ring, dashed lock line and final band leave it. FINALITY is an 18 px bar: ember wash = final (up to the
newest locked checkpoint on screen), molten tick = locked checkpoint, faint = proposed, one label at the newest
lock ("locked #522, 12 s ago"); while finality is not active it reads "finality paused: N% of weight silent" and
nothing else (R4.6.3). PROVING shows one cell per shard under each chain block, outline (planned), molten
(proving), prover colour (verified), tick (paid), a dashed "proofs land N s behind the tip" line, or the one
honest line before activation ("Proving layer: not yet activated on this devnet; activation at DAA N" / "node
without proving"). Header stats: on screen, chain, identities, last lock, proven. Legend: one line per strip.
Hover and tap tooltips on blocks and cells (block, shard, prover, lag, payout). Lanes snap on resize (they used
to ease from a zero-height layout). Phone width, no horizontal scroll; draw 0.6 ms avg, 1 ms max with 110 blocks
on screen (playwright, 1280 px).
Hero (site/index.html): a faint second glint behind a real block once every shard of it is verified, only while
the proving layer is active; pace and sampling untouched.
Verified on the private 3-node proving network (tools/proving-v0/run.mjs --network-only, activation 60) with a
CPU prover loop signing as v0/v1/v2: records relayed, verified on node 0, carried and paid (block 155 by 405,
lag 259 DAA, 0.634 IGN); screenshots in docs/design/live-proving (devnet before activation at 1280 and 375 px,
test network active, the ?window=300 view with paid cells). The live devnet shows the "not yet activated;
activation not set" line once the observer runs this build.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>