the artifact — /colophon
The smallest honest thing I could ship.
Zero bytes of JavaScript in the build, one dependency, no third-party requests, no cookies — and a Lighthouse 99/100/100 that carries the date it was measured, because the build doesn’t enforce that one. Every number below says how it’s known, and the rule is the site’s own: measured, or it reads unknown.
the stack
- framework Astro 5. Content, rendered to static HTML at build time. It ships zero JavaScript by default, and this site adds none — so the default is also the whole story.
- dependencies One.
astro, and nothing else — no UI library, no integrations, no build plugins. Fewer moving parts is fewer things that can quietly start lying. - client js None. No framework runtime, no router, no analytics bundle. A blinking caret or a status stamp is CSS. If a byte of script ever reaches the output, the build stops before it publishes.
- styles
Hand-written CSS on a single token layer, kept external so the
same-origin style policy needs no
unsafe-inlineescape hatch.
the ledger — what it costs to load this page
These are read straight from the build’s own measurement of the artifact, re-derived on every deploy and failed on drift. Named here so you can see how each one is known — and where nothing is.
- JavaScript in the build output
- 0 B enforced
- the build fails if a single byte of JS reaches the output
- Third-party requests at runtime
- 0 enforced
- CSP default-src 'self', plus a scan of the built HTML and CSS
- npm dependencies
- 1 — astro counted
- dependencies + devDependencies in package.json
- Self-hosted font files
- 5 latin .woff2 counted
- counted in the built output; nothing loaded from a font CDN
- Cookies, trackers, analytics
- none enforced
- there is no client code that could set or read one
- Lighthouse — perf / a11y / best-practices
- 99 / 100 / 100 counted
- measured headless against the build, 2026-07-24 — a dated snapshot, not build-enforced
- Lighthouse — SEO
- 92 counted
- the −8 is my own CSP: connect-src none blocks Lighthouse’s robots.txt probe (robots is 200 and valid). Harness truth, not wire truth.
The Lighthouse rows are a dated snapshot, not a build-enforced number — so they carry a date, and they’ll drift. The SEO score is the honest part: it loses eight points because the same connect-src 'none' that makes this site safe also blocks Lighthouse’s own in-page fetch of robots.txt — which is served, 200, and valid. A real crawler reads it fine. The audit is measuring my CSP, not my SEO.
type
- Fraunces Display — the big serif headings, set with a tight negative tracking.
- Newsreader Body — a face drawn for long reading, which is what prose is for.
- Courier Prime Mono — labels, data, and the terminal texture. The typewriter, used as a typewriter.
All three are self-hosted, subset to latin only, and
served from this origin — five .woff2 files, no request to a
font CDN, ever. That’s a font-src 'self' line in the policy
below, not a promise.
the discipline
The one rule is that a status is measured — with a value — or it reads UNKNOWN. Green is reserved for measured-and-alive, and nothing else gets to wear it.
This isn’t a note to self on a wall; it’s a build step. A script re-reads the built output, re-derives every fact this artifact claims about itself, and compares them against what the pages print. If any of them has drifted, the build fails rather than publish the stale one. The rule can be argued with; the build can’t.
That is deliberately the site refusing to trust me. A portfolio wants to flatter its author; wiring the honesty into the build is how it stays honest even when rounding up would flatter me.
the words
One honest disclosure, because it belongs on the page that describes how this site is made. The copy here wasn’t just typed and shipped — it was steered, with the same model-wrangling I do everywhere else. The home-page headline is the clearest case: seven drafts wrote twenty-eight candidates, four independent judges scored each on honesty, voice, typography, and stickiness, and one line survived the panel.
The judgment and the final words are mine; the panel is a tool I point at my own writing so a first draft doesn’t get to be the last one. It’s the same distrust that runs through the rest of this page — wire the check into the process, then don’t let the author talk his way past it. If that reads as odd on a personal site, good: the alternative was to hide it, and hiding it would break the one rule the whole site is about.
hosting
Static files on Cloudflare Pages — a dist/
of HTML, CSS, and fonts, and no server-side code, no bindings, no
functions. There is nothing running here to have an outage.
Everything is served under a strict, same-origin Content-Security-Policy.
default-src 'self' is the floor; the browser refuses any
third-party request even if one somehow slipped into the source. Verbatim:
script-src 'none' and connect-src 'none': nothing on this page runs a script or opens a connection, and the policy refuses anything that tries. The day that has to change, this line changes with it — not the other way around.
No trackers, no cookie banner, no third parties, and a date on every number the build can’t enforce. That’s the whole site.