app-ia-26 item 8: the audit-26 screens in docs/design/app-screens/0.3.26; the Settings page renders again; a render that throws says so

Item 8 (docs/design/app-audit-2026-10-08.md): tools/ui-mock/shots-audit-26.txt is the shot list (the four pages, dark
and light, the first minute, the table, the syncing node, a job holding the card, a still chain) and the fourteen
screens are in docs/design/app-screens/0.3.26, taken by tools/ui-mock/capture.sh on build-2 against the mock with
the engine's earned windows on every scenario.

Two faults found by the screens. (1) Since item 4 the Settings page had not rendered on the mock: renderProvingSection
called proveInsteadWords bare after the page-side alias left with the old card details, the poll's catch swallowed
the throw as an engine silence, and the Settings captures of items 4 and 6 showed the markup's defaults ("not set",
"Node starting"). It reads View.proveInsteadWords now; renderSettings also renders the Node card's line and facts
(they live on Settings since item 3). (2) The poll's catch now prints "render failed: <stack>" to the console, so a
throwing render is a visible bug and the capture scripts report it, never a silent default page. The not-answering
branch addresses the node line and the toggle by their present ids.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-08 14:33:55 +00:00
parent 86d4fd1fef
commit 0ab19a4ebc
15 changed files with 7 additions and 4 deletions

View file

@ -2696,7 +2696,7 @@ if (typeof document !== 'undefined') (function () {
setHidden('shard-card', !sh); setHidden('shard-card', !sh);
if (sh) { setText('sc-when', clock(sh.at)); setText('sc-title', 'Your card proved shard ' + sh.shard + ' of block ' + withCommas(sh.block) + '.'); setText('sc-line', View.fmtIgn(View.ign(sh.wei)) + ' paid for it \u00b7 ' + withCommas(pv.paid || 0) + ' shard' + (pv.paid === 1 ? '' : 's') + ' paid on this machine'); setText('sc-sub', '20 points of every block pay the provers, split by shard. A paid record is a chain fact: anyone can read it.'); $('sc-title').title = View.FIELDS.shards; $('sc-line').title = 'proving.paid_wei, proving.paid'; } if (sh) { setText('sc-when', clock(sh.at)); setText('sc-title', 'Your card proved shard ' + sh.shard + ' of block ' + withCommas(sh.block) + '.'); setText('sc-line', View.fmtIgn(View.ign(sh.wei)) + ' paid for it \u00b7 ' + withCommas(pv.paid || 0) + ' shard' + (pv.paid === 1 ? '' : 's') + ' paid on this machine'); setText('sc-sub', '20 points of every block pay the provers, split by shard. A paid record is a chain fact: anyone can read it.'); $('sc-title').title = View.FIELDS.shards; $('sc-line').title = 'proving.paid_wei, proving.paid'; }
if (document.activeElement !== $('s-prove')) $('s-prove').checked = enabled; if (document.activeElement !== $('s-prove')) $('s-prove').checked = enabled;
var pi = proveInsteadWords(pv, s.settings); var pi = View.proveInsteadWords(pv, s.settings);
$('pv-instead-row').hidden = !pi.show; $('pv-instead-row').hidden = !pi.show;
if (pi.show) { $('pv-instead-help').textContent = pi.help; if (document.activeElement !== $('s-prove-instead')) $('s-prove-instead').checked = pi.on; } if (pi.show) { $('pv-instead-help').textContent = pi.help; if (document.activeElement !== $('s-prove-instead')) $('s-prove-instead').checked = pi.on; }
var w = View.proveWords(pv, enabled, s.node.synced); var w = View.proveWords(pv, enabled, s.node.synced);
@ -2721,6 +2721,7 @@ if (typeof document !== 'undefined') (function () {
function renderSettings(s) { function renderSettings(s) {
renderProvingSection(s); renderProvingSection(s);
renderWallet(s); renderWallet(s);
renderNode(s); // the Node card's line and facts live here now (app-ia-26, 4.4 item 2)
var st = s.settings || {}, sw = function (id, on) { if (document.activeElement !== $(id)) $(id).checked = !!on; }; var st = s.settings || {}, sw = function (id, on) { if (document.activeElement !== $(id)) $(id).checked = !!on; };
sw('s-vote', st.vote); sw('s-login', st.start_at_login); sw('s-jobs-allow', s.jobs && s.jobs.allowed); sw('s-trust', st.proof_verify_trust); sw('s-power-control', st.power_control); sw('s-profile', st.profile_public); sw('s-vote', st.vote); sw('s-login', st.start_at_login); sw('s-jobs-allow', s.jobs && s.jobs.allowed); sw('s-trust', st.proof_verify_trust); sw('s-power-control', st.power_control); sw('s-profile', st.profile_public);
setText('s-profile-text', View.profileWords(!!st.profile_public)); setText('s-profile-text', View.profileWords(!!st.profile_public));
@ -3005,13 +3006,15 @@ if (typeof document !== 'undefined') (function () {
uiReloadIfChanged(s); uiReloadIfChanged(s);
perf.render += performance.now() - a; perf.polls++; perf.render += performance.now() - a; perf.polls++;
if (failures === 0 && $('pill').classList.contains('away')) { $('pill').classList.remove('away', 'warn'); } if (failures === 0 && $('pill').classList.contains('away')) { $('pill').classList.remove('away', 'warn'); }
}).catch(function () { }).catch(function (e) {
// a render that throws is a bug in this window, never the engine's silence: say so in the console (app-ia-26)
if (e && e.stack && typeof console !== 'undefined') console.error('render failed: ' + e.stack);
failures++; failures++;
if (failures >= 4) { if (failures >= 4) {
$('pill').classList.add('warn', 'away'); $('pill-text').textContent = state && state.quitting ? 'Stopped' : 'App not answering'; $('pill').classList.add('warn', 'away'); $('pill-text').textContent = state && state.quitting ? 'Stopped' : 'App not answering';
if (phase === 'dashboard') { if (phase === 'dashboard') {
setText('node-line-text', 'Node: no answer'); setText('node-sub', 'the app is not answering. The window reconnects by itself'); $('node-card').classList.add('bad'); setText('node-line-text', 'Node: no answer'); $('node-go').title = 'the app is not answering. The window reconnects by itself'; $('node-go').classList.add('bad');
setText('btn-toggle-sub', 'the app is not answering'); $('btn-toggle').disabled = true; $('btn-toggle').title = 'the app is not answering'; $('btn-toggle').disabled = true;
setText('t-hash-sub', 'no answer from the app'); setText('t-hash-sub', 'no answer from the app');
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB