Skip to content

Verification

Two gates. The first proves the file is self-contained by reading it; the second proves it is correct by rendering it.

Gate 1 — the build (always runs)

python3 tools/build_standalone.py page.src.html -o "../dist/Page Name.html"

Standard library only, so it runs anywhere Python does. It inlines every stylesheet, follows @import chains, drops non-Latin font subsets, converts fonts and images to data: URIs, and inlines <script src>.

Then it re-reads its own output and refuses to report success if anything survives that a reader's browser would still have to fetch: an external subresource, a relative path, an external url() in CSS. An <a href> to the open web is fine — that is a link, not a dependency.

Downloads are cached under .cache/, so a build that has run once runs offline. --no-network makes that explicit: it fails loudly rather than silently producing a page that needs the internet.

Read the summary line. Source 58 KB → standalone 295 KB with 11 cached assets is healthy. 580 KB means discrete font weights or undropped subsets.

node tools/verify_page.mjs "../dist/Page Name.html" --shots /tmp/shots

Needs Playwright and a Chromium build. Neither is a dependency of the repos this runs in, so both are located at run time; PLAYWRIGHT_MODULE and PLAYWRIGHT_CHROMIUM override discovery. It exits 69 and explains itself if Playwright is absent — the build gate still stands on its own.

It loads the built file at six theme and width combinations and fails on:

Check Catches
Zero network requests An asset the build gate's static scan missed
data-theme and aria-pressed resolve as expected A broken toggle, a token defined only in a media query
Every webfont reports loaded A dropped subset, a corrupt data URI, a family name typo
No dead in-page anchor A rail link to a section id that does not exist
No horizontal page overflow A table or diagram that escapes at 380px
No SVG text outside its viewBox A label pushed off the canvas
No SVG text wider than the box containing it A label overflowing its box

The six cases are: system light, system dark, explicit dark over a light system, explicit light over a dark system, 760px, 380px. The two override cases matter — they are the only ones that exercise the :root[data-theme] block, and a page can pass every other check with that block missing entirely.

Look at the screenshots

Both gates are mechanical. Neither will tell you a diagram is confusing, a figure caption asserts something the figure does not show, or a status colour reads as alarming when it should read as routine.

--shots DIR writes one image per case. Open them. On the page this skill came from, reading the screenshots caught a caption overflowing its box and a connector line running through an arrow label — after both gates passed.

What is not checked

  • Contrast. Compute it when you add or change a colour; do not assume a DS value passes at your font size. Two DS badge pairings do not.
  • Accuracy. No tool knows whether 34% is still 34%. That is source-handling.md.
  • Whether the regeneration prompt still describes the page. Update it in the same edit as the change it describes.