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)¶
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.
Gate 2 — the render (optional, strongly recommended)¶
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.