site/site.css: the tokens of the miner app's third redesign in light and dark (a darker light-mode ember and molten for text so every pair passes 4.5:1, checked by tools/ci/site-contrast-check.mjs), the type scale on Unbounded, Plex Sans and Plex Mono, the nav with one primary, the footer with a System/Light/Dark control, cards, tiles, tables that scroll on a phone, buttons, pills, notes, callouts, the state words, focus rings, reduced motion, print. Partials rebuilt; the head loads the stylesheet and applies the stored theme before paint. Every page's own style block is reduced to its page rules. site/live-dag.js: the shared DAG view for / and /live (docs/plans/site-ui-3.md section 6): blocks by header time and miner lane, parent edges with the selected chain as one heavier path, blue lit, red dim, pending grey, proven filled, checkpoint bands with their lock weight (locked solid, pending dashed), new blocks arriving with a glow, hover and tap details in the ledger's words, wheel and pinch zoom of the window (30 to 300 s), a pause button, device-pixel sharpness, a still frame under reduced motion; opts.mine marks the user's own blocks (the miner app embeds the same file), opts.poll:false with dag.push(reply) lets a host feed it. Every pixel is a block the observer stored. site/index.html: the one-screen story (what it is, the live scene with chain block, shards proven, last lock, vote keys and hash rate as state words, three things a sceptic checks, the download, how it works, the wallet, the journey, economics), every tick-list row kept, the chip model's numbers moved to the sceptic card, the testnet terms behind a chevron, the scroll-reveal gone, the Open Graph set on the 1200 by 630 image, no horizontal overflow at 390. site/litepaper.html: dark like the site with light on request, whole paper by default (the section mode kept, deep links intact, print prints the paper), repository paths off the surface, the cover dated 6 October, the wallet at 0.1.4, the roadmap's verifier figure aligned with the Mining section, the proof lag stated as measured (about 380 s against the 60 s gate), the 0.3.6 plan dated with 0.3.14 stated, the two "tonight" placeholders said as not yet measured. Every ledger sentence verbatim (tools/ci/ledger-text-check.mjs, 43 sentences). site/live.html: the lane chart replaced by the module; "proven A/B in 10 min", "finality paused, last #N", "pending" for "n/a"; the fee sentence true on both sides of DAA 210,000. site/metamask.html: its own canonical, the explorer linked, the wallet's state said true. site/404.html: the page count and section count said true. site/build.mjs: the generated pages on the system, each with its own eyebrow, the miners page's source notes as sentences. downloads.json refreshed from the host (0.3.14). tools/ci/site-orphan-check.mjs: no site heading leaves one word alone at 390 px (log titles reported). Checks: identity grep 0 hits, link check 854 links 0 broken, ledger text 43 of 43, contrast 32 pairs 0 under 4.5:1, no horizontal overflow at 390 on 14 pages (the wallet page's timed table overflows by 5 px, for the wallet-ui-3 owner), orphan check 0 site headings (the miner h1 at 96 characters is the site-miner agent's copy). After captures beside the audit's: docs/plans/site-ui-3-shots/after/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
65 lines
4.4 KiB
JavaScript
65 lines
4.4 KiB
JavaScript
// Ledger text check: every sentence docs/fud-ledger.md requires on a public page must appear on that page verbatim
|
||
// (docs/plans/site-ui-3.md step 6). The list below is the ledger's stated-sentence set as audited on 6 October 2026
|
||
// (docs/plans/site-ui-3-ticklist.md); a new ledger row that states a sentence adds a line here in the same commit.
|
||
// node tools/ci/ledger-text-check.mjs exit 1 listing every missing sentence
|
||
import { readFileSync } from 'node:fs';
|
||
import { join, dirname } from 'node:path';
|
||
import { fileURLToPath } from 'node:url';
|
||
const site = join(dirname(fileURLToPath(import.meta.url)), '..', '..', 'site');
|
||
const REQUIRED = {
|
||
'index.html': [
|
||
['E5', 'The one payment to the project is the Ember software’s optional 1% dev fee', 'The one payment to the project is the Ember software\'s optional 1% dev fee'],
|
||
['G4', 'admin keys in consensus'],
|
||
['C2', 'since 2019 (approximate)'],
|
||
['X2', 'Public testnet: not yet open; the devnet build is here for people who want to look'],
|
||
['X3', 'Live rows arrive with the public testnet, August 2027'],
|
||
['X7', 'hello@igneum.network'],
|
||
['X8', 'No listing is arranged, promised or sought by the project'],
|
||
],
|
||
'litepaper.html': [
|
||
['M2', 'computing items on the fly runs 4.8x slower than loading them'],
|
||
['M4', 'ProgPoW, as KAWPOW on Ravencoin since 2020'],
|
||
['M7', 'The hash is a lottery, not a general-purpose cryptographic hash'],
|
||
['M7', 'no analysis of the lottery properties exists yet'],
|
||
['M10', 'an RTX 5090 hashes at 95 GB/s of useful 4-byte loads against 1,638 GB/s of sequential writes'],
|
||
['M13', 'Macs mine too, at about a fifth of a flagship card'],
|
||
['F1', 'In the chain’s first 30 days no checkpoint locks at all', 'In the chain\'s first 30 days no checkpoint locks at all'],
|
||
['F5', 'An attacker matching the honest network needs twenty days for a third and never reaches two thirds'],
|
||
['F10', 'Pools carry their hashers’ votes, so vote concentration equals pool concentration, and it is public', 'Pools carry their hashers\' votes, so vote concentration equals pool concentration, and it is public'],
|
||
['P3', 'the wrapping cost is a phase two measurement'],
|
||
['P4', 'The consensus proof that makes the checkpoint self-verifying is phase two'],
|
||
['P6', 'a supplier whose marginal cost is close to power'],
|
||
['P7', 'Writing new code, including an emergency fix to the proof system, is the one thing that takes a person'],
|
||
['P10', 'settlement in IGN with a 10% burn follows'],
|
||
['P14', 'pays about 7,300 IGN a year'],
|
||
['E5', 'No fund, no foundation, no fee to the team'],
|
||
['E5', '1 block in 100 pays the project'],
|
||
['E6', 'The schedule is a bet, not a measurement'],
|
||
['G1', 'reviewers will be named and paid before gate 3'],
|
||
['G2', 'one founder with AI systems'],
|
||
['G3', 'there is no team page'],
|
||
['G4', 'no admin keys in consensus'],
|
||
['G6', 'Pools can be bypassed on transaction choice'],
|
||
['C2', 'precedent, not proof'],
|
||
['C3', 'Chips arrived, as on Kaspa, whose hash was designed to welcome them'],
|
||
['C3', 'Kaspa has run in production since 2021 (approximate)'],
|
||
['C5', 'Inclusion is not confirmation on either chain'],
|
||
['C6', 'the combination is the risk the gates price'],
|
||
['C6', 'Dates slip. Gates do not.'],
|
||
['C8', 'Ergo, Ravencoin and Conflux still mine on GPUs at a fraction of the 2022 fleet (approximate)'],
|
||
['C10', 'Boundless provers post ZKC and Succinct provers stake PROVE (approximate'],
|
||
['C11', 'We know of no chain that combines them'],
|
||
['L2', 'Nearly a quarter of all supply is mined in the first year and half in the first two'],
|
||
['X1', 'The node, the miner and the wallet are in a private repository until the public testnet'],
|
||
['X7', 'hello@igneum.network'],
|
||
['X8', 'No listing is arranged, promised or sought by the project'],
|
||
],
|
||
};
|
||
const norm = s => s.replace(/\s+/g, ' ').replace(/'|'/g, '\'').replace(/"/g, '"').replace(/&/g, '&');
|
||
let missing = 0, n = 0;
|
||
for (const [page, rows] of Object.entries(REQUIRED)) {
|
||
const html = norm(readFileSync(join(site, page), 'utf8'));
|
||
for (const [row, ...variants] of rows) { n++; if (!variants.some(v => html.includes(norm(v)))) { missing++; console.error(`ledger text: ${page} lacks ${row}: "${variants[0]}"`); } }
|
||
}
|
||
console.log(`ledger text check: ${n} sentences, ${missing} missing`);
|
||
process.exit(missing ? 1 : 0);
|