The problem
Everything an agent would need to write this site sits on the same server as things that must never be published. Telling a model "don't include anything private" is a request, not a guarantee. So the guarantee has to come from code.
What happens on every build
- The content is data. The résumé is a JSON file in the open JSON Resume format. Each project is a Markdown file with a fixed set of fields: a title, a one-line summary, the steps in its diagram, and up to three facts, each with the file it came from.
- A schema checks every file. A missing field, a date in the wrong form or a summary that runs too long stops the build. Bad output from an agent never reaches the page.
- A gate reads the finished pages. It refuses to publish if it finds anything on a private list (names, numbers, addresses, internal machine details), if a fact has no source file, or if a link is dead.
- I approve a preview. Changes go to a preview address first. Nothing replaces the live site until I've read it and said so.
- The output is plain files. No server runs code when you visit. The site is static HTML on a content delivery network, so it is fast and there is little to break.
Tools
Astro builds the pages. Playwright prints the PDF résumés from the same pages you can read here, so the two never disagree. The look comes from my own UI kit: white ink, the system's own font, controls pressed into the surface, and colour kept for data. The map at the top of the home page is a frame from Pulse.
Who wrote what
I decided what the site should say and how it should work, and I review every page. AI coding agents (Claude Code) wrote the code and drafted the project write-ups from my own documents. Drafts are labelled until I've rewritten them in my own words.