From eeb70e04ffb2072e62c790d600b2299518b58121 Mon Sep 17 00:00:00 2001 From: igneum-labs <337424239+igneum-labs@users.noreply.github.com> Date: Tue, 6 Oct 2026 18:59:59 +0000 Subject: [PATCH] miner-ui-4: the chain's own words come back (shard, segment, checkpoint, aggregator, verifying), each explained once in grey; the rest of the sweep stands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Main's correction: the app uses the same words as the site, the litepaper and the ledger for the chain's own objects, or users cannot match the app to the docs. Shard (not piece), segment (not run of blocks, 'runs of 8 blocks' as the explanation), checkpoint and 'locked checkpoint' (not lock point), aggregator (not combiner), verifying (not checking proofs). Card, app, Default · Balanced, the Ember Tune strip, the state words and the one-sentence rule stay. 37 UI tests pass. Co-Authored-By: Claude Fable 5.1 --- app/igneum-app/ui/app.js | 28 ++++++++++++++-------------- app/igneum-app/ui/index.html | 20 ++++++++++---------- app/igneum-app/ui/view.test.mjs | 6 +++--- docs/plans/miner-ui-4-copy.md | 15 +++++++++------ 4 files changed, 36 insertions(+), 33 deletions(-) diff --git a/app/igneum-app/ui/app.js b/app/igneum-app/ui/app.js index 61fe15973..8cf86896a 100644 --- a/app/igneum-app/ui/app.js +++ b/app/igneum-app/ui/app.js @@ -499,17 +499,17 @@ var View = (function () { // the Prove page: pv = state.proving, enabled = state.settings.prove, synced = state.node.synced function proveWords(pv, enabled, synced) { pv = pv || {}; - if (!enabled) return { word: 'off', sub: 'not proving', tone: 'off', note: 'Off. Switch it on and this machine proves the pieces it is given.' }; + if (!enabled) return { word: 'off', sub: 'not proving', tone: 'off', note: 'Off. Switch it on and this machine proves the shards it is given.' }; if (pv.status === 'setup' || (pv.enabled && !pv.available && pv.setup_hint)) return { word: 'needs setup', sub: 'one-time install', tone: 'bad', note: pv.setup_hint || pv.message || 'The prover is not installed yet.' }; if (!synced || pv.status === 'waiting') return { word: 'waiting', sub: 'for the node to sync', tone: '', note: pv.message || 'Proving starts once the node has every block.' }; - if (pv.status === 'proving') return { word: 'proving', sub: pv.current || 'a piece', tone: 'on', note: pv.message || 'A proof takes minutes on a CPU and seconds on an NVIDIA card.' }; + if (pv.status === 'proving') return { word: 'proving', sub: pv.current || 'a shard', tone: 'on', note: pv.message || 'A proof takes minutes on a CPU and seconds on an NVIDIA card.' }; if (pv.status === 'submitted') return { word: 'submitted', sub: 'waiting to be paid', tone: 'on', note: pv.message || 'The node checks the proof, then the chain pays it.' }; - if (pv.status === 'idle') return { word: 'idle', sub: 'nothing assigned', tone: 'ok', note: pv.message || 'On. Nothing to prove right now. The next piece arrives within a minute.' }; + if (pv.status === 'idle') return { word: 'idle', sub: 'nothing assigned', tone: 'ok', note: pv.message || 'On. Nothing to prove right now. The next shard arrives within a minute.' }; return { word: pv.status || 'on', sub: pv.backend ? pv.backend.toUpperCase() : '', tone: '', note: pv.message || '' }; } function verifierWords(pv) { var vm = (pv && pv.verifier_mode) || 'unknown'; - var word = { command: 'checking proofs', trust: 'trusting without checking (devnet only)', off: 'off, passing proofs along', unknown: 'not read yet' }[vm] || vm; + var word = { command: 'verifying', trust: 'trusting without verifying (devnet only)', off: 'off, passing proofs along', unknown: 'not read yet' }[vm] || vm; if (vm === 'command' && pv.pool_entries) word += ' · pool ' + pv.pool_verified + '/' + pv.pool_entries + (pv.pool_failed ? ', ' + pv.pool_failed + ' rejected' : ''); return { word: word, tone: vm === 'command' ? 'ok' : (vm === 'off' || vm === 'trust') ? 'warn' : 'dim', needsSetup: vm === 'off' && /WSL2 prover is not installed/.test((pv && pv.verifier_reason) || '') }; } @@ -518,7 +518,7 @@ var View = (function () { function proveTier(cd) { var gb = cd.vram_mb ? Math.round(cd.vram_mb / 1024) : 0; if (cd.vendor === 'apple') return cd.name + ': proves on the CPU, slowly.'; - if (cd.vendor === 'nvidia') return gb >= PROVE_GB ? cd.name + ': proves while it mines (' + gb + ' GB; a full piece needs ' + SHARD_GB + ' GB).' : cd.name + ': cannot prove a full piece (' + gb + ' GB; a full piece needs ' + SHARD_GB + ' GB).'; + if (cd.vendor === 'nvidia') return gb >= PROVE_GB ? cd.name + ': proves while it mines (' + gb + ' GB; a full shard needs ' + SHARD_GB + ' GB).' : cd.name + ': cannot prove a full shard (' + gb + ' GB; a full shard needs ' + SHARD_GB + ' GB).'; return cd.name + ': cannot prove yet (proving needs an NVIDIA card).'; } // the counts in one sentence: "idle · nothing assigned · 0 assigned · 0 proven · 0 paid · 0.0000 IGN" @@ -619,11 +619,11 @@ var View = (function () { [/^GPU worker built from source/, function () { return 'Mining program built'; }], [/^block (\d+) shard (\d+) paid (.+) IGN/, function (m) { return 'Proof paid: ' + m[3] + ' IGN'; }], [/^block (\d+) shard (\d+) proven and submitted in (\d+) s/, function (m) { return 'Proof sent in ' + m[3] + ' s'; }], - [/^segment .+ paid (.+) IGN to the aggregator/, function (m) { return 'Run of blocks paid: ' + m[1] + ' IGN'; }], - [/^segment (\S+)\.\.(\S+) aggregated and submitted in (\d+) s/, function (m) { return 'Run of blocks proven in ' + m[3] + ' s'; }], - [/^segment (\S+)\.\.(\S+): (\d+) shards proven, aggregated and submitted in (\d+) s/, function (m) { return 'Run of blocks proven: ' + m[3] + ' pieces in ' + m[4] + ' s'; }], - [/^segment (\S+)\.\.(\S+): (\d+) shards proven and submitted in (\d+) s; the segment record is held/, function (m) { return 'Run of blocks proven: ' + m[3] + ' pieces in ' + m[4] + ' s. Its record waits for the chain'; }], - [/^segment (\S+)\.\.(\S+) record accepted on retry/, function () { return 'Run of blocks accepted'; }], + [/^segment .+ paid (.+) IGN to the aggregator/, function (m) { return 'Segment paid: ' + m[1] + ' IGN'; }], + [/^segment (\S+)\.\.(\S+) aggregated and submitted in (\d+) s/, function (m) { return 'Segment proven in ' + m[3] + ' s'; }], + [/^segment (\S+)\.\.(\S+): (\d+) shards proven, aggregated and submitted in (\d+) s/, function (m) { return 'Segment proven: ' + m[3] + ' shards in ' + m[4] + ' s'; }], + [/^segment (\S+)\.\.(\S+): (\d+) shards proven and submitted in (\d+) s; the segment record is held/, function (m) { return 'Segment proven: ' + m[3] + ' shards in ' + m[4] + ' s. Its record waits for the chain'; }], + [/^segment (\S+)\.\.(\S+) record accepted on retry/, function () { return 'Segment record accepted'; }], [/^WSL2 prover setup started/, function () { return 'Prover setup started in its own window'; }], [/^Card removed: (.+); its worker stopped/, function (m) { return 'Card removed: ' + m[1]; }], [/^(.+): not usable \((.+?)\); its worker stopped/, function (m) { return m[1] + ': not usable (' + m[2] + ')'; }], @@ -995,7 +995,7 @@ if (typeof document !== 'undefined') (function () { $('r-wallet').addEventListener('click', function () { api('api/open', { url: 'https://igneum.network/wallet' }); }); // ---------- Prove ---------- - $('s-prove').addEventListener('change', function () { var on = this.checked; api('api/prove', { on: on }).then(function (r) { if (r.ok) toast(on ? 'Proving on. The first piece arrives within a minute' : 'Proving off'); else { toast(r.error || 'could not change'); $('s-prove').checked = !on; } }); }); + $('s-prove').addEventListener('change', function () { var on = this.checked; api('api/prove', { on: on }).then(function (r) { if (r.ok) toast(on ? 'Proving on. The first shard arrives within a minute' : 'Proving off'); else { toast(r.error || 'could not change'); $('s-prove').checked = !on; } }); }); $('pv-setup').addEventListener('click', function () { api('api/prove/setup', {}).then(function (r) { toast(r.ok ? 'Setup started in its own window' : (r.error || 'could not start')); }); }); // ---------- Settings ---------- @@ -1570,7 +1570,7 @@ if (typeof document !== 'undefined') (function () { $('n-switches').innerHTML = (n.consensus_switches || []).map(function (x) { return '' + esc(x.name) + (x.daa <= n.daa ? ' (applied)' : '') + '' + withCommas(x.daa) + ''; }).join(''); } if (f.last_lock > 0) { setText('f-lock', '#' + withCommas(f.last_lock) + ' · ' + rel(f.age_s)); setText('f-note', 'a point the miners agreed can never be undone. It locks at two thirds of the last 30 days of mining'); } - else { setText('f-lock', 'none yet'); setText('f-note', f.message || 'locks appear once this machine votes'); } + else { setText('f-lock', 'none yet'); setText('f-note', f.message || 'checkpoints lock once this machine and the others vote'); } setText('f-votes', withCommas(f.votes)); } @@ -1610,10 +1610,10 @@ if (typeof document !== 'undefined') (function () { setText('pv-note', (!enabled && pv.default_note) ? pv.default_note + '.' : w.note); var v = View.verifierWords(pv); setText('pv-verifier', v.word); $('pv-verifier').className = 'v ' + v.tone; - setText('pv-verifier-help', pv.verifier_note || 'the node checks a proof before it counts'); + setText('pv-verifier-help', pv.verifier_note || 'the verifier: the node checks a proof before it counts'); $('pv-setup-row').hidden = !((pv.enabled && !pv.available && pv.setup_hint) || v.needsSetup); var seg = pv.segments_submitted ? pv.segments_submitted + ' proven whole, ' + (pv.segments_paid || 0) + ' paid' + (pv.segment_paid_wei && Number(pv.segment_paid_wei) ? ' (' + (Number(pv.segment_paid_wei) / 1e18).toFixed(4) + ' IGN)' : '') + (pv.segment_last_s ? ', the last took ' + Math.round(pv.segment_last_s) + ' s' : '') + (pv.segments_held ? ', ' + pv.segments_held + ' waiting for the chain' : '') : 'none yet'; - setText('pv-seg', seg); setText('pv-seg-note', pv.segment_note && enabled ? pv.segment_note : 'whole runs of blocks this machine proved'); + setText('pv-seg', seg); setText('pv-seg-note', pv.segment_note && enabled ? pv.segment_note : 'whole segments (runs of 8 blocks) this machine proved'); setText('pv-program', pv.program_id || 'not read yet'); setText('pv-aggregator', pv.aggregator_id || 'not read yet'); } diff --git a/app/igneum-app/ui/index.html b/app/igneum-app/ui/index.html index 971b79b0b..c0c1e80ad 100644 --- a/app/igneum-app/ui/index.html +++ b/app/igneum-app/ui/index.html @@ -188,11 +188,11 @@

The chain, live

connecting
- +
-
yourspendingincludedexcludedprovenlocked
+
yourspendingincludedexcludedprovenlocked checkpoint
@@ -212,8 +212,8 @@
tips0open ends of the chain right now
blue score0blocks on the agreed main chain (the blue score)
next program--:--the hourly mining program
-
last locknone yeta point the miners agreed can never be undone
-
votes sent0this machine signs a lock point every 30 s
+
last checkpointnone yeta point the miners agreed can never be undone
+
votes sent0this machine signs a checkpoint every 30 s (a point the miners agree can never be undone)
rules fingerprint
@@ -314,7 +314,7 @@

Prove on this machine

-

Every block is turned into a short proof. Your cards prove pieces of it and earn IGN for each one.

+

Every block is turned into a short proof, in pieces called shards. Your cards prove shards and earn IGN for each one.

@@ -326,16 +326,16 @@
@@ -418,7 +418,7 @@

Advanced

devnet
- +