Deconstructing this website
If someone tells you how they work and cannot show you the workshop, be suspicious. This is ours.
The tour runs downwards, from the point of presence that answered your request to the commit that authorised these words. Every layer opens if you want the detail, and everything claimed here is in the repository.
The architecture
There are no servers to look after, and that is the least of it. What matters is where the response you are reading was made: at the edge, on Cloudflare Workers. Cache sits in front, and on a hit the code never runs.
Below that, the CMS is EmDash, which Cloudflare released under an MIT licence as a successor to WordPress, and not a service to call over the network: it is the same application, served by the same worker. And at the bottom of the descent there is no database, there is a text file in Git.
L5the edgeWorkers · cache in frontA hit returns the page without running any code.
The
Workerscache sits in front of theworker, so a hit answers without running anything. Nothing is cached by default: a page only gets in if it asks to. Once in it lasts an hour, and publishing purges it by tag.L4the doormiddlewareDecides what may be cached and adds the security headers.
One middleware for every response: it resolves the locale, loads the accessibility labels, decides the cache policy and stamps seven security headers. The editing panel is excluded, because it brings its own.
L3the renderAstro SSRBuilds the HTML in the same
workerthat took the request.26 public routes, 24 components and 12 stylesheets, on
Astroon-demand rendering — Astro has been part of Cloudflare since January 2026. Locales are not separated by prefix but by translated slug, so the alternate route is resolved against the CMS and never guessed: guessing it returns a 404.L2the CMSEmDashRuns inside the same
worker: no external service to call.EmDashis not a service you subscribe to: it is the CMS Cloudflare released in April 2026 under an MIT licence as a successor to WordPress, and has run its own blog since 12 August. Here it injects 183 routes under/_emdashinto this very application, with 7 collections and 43 entries: same script, same bindings, no network call. Third-party plugins are the deliberate exception, running in a separate isolate through Worker Loader, with no way out to the internet.
The panel, editing this page. It runs in the same worker that just served it to you. L0the originseed.json · markdownWhat a person writes. Everything above derives from it.
A text file in Git, plus the service bodies in
markdown. The whole site comes out of it in a rebuild from nothing, which is what continuous integration does before every merge.
Content as code
Almost every text lives in seed/seed.json, with the service bodies in markdown: the filename is the slug, the directory is the locale. A rebuild from nothing remakes the whole site, and continuous integration checks that before every merge.
Caching inherits the discipline: a page is cached only if it asks to be, and publishing purges it by tag. One gap is worth saying out loud: menus and site settings emit no event, so a one-hour TTL is what bounds their staleness.
➜ serverstartup.io rebuild --from-nothing
database created, empty
seeds applied: 43 entries, two locales
frozen copy: 26 routes
rendered copy: matches the frozen baseline
╰─ done. The rebuild is the proof, and it runs before every merge.
The agents
A model writing the first draft is neither impressive nor mysterious. What decides whether this is serious is who has authority over what.
The agent proposes and cannot merge. The checks refuse and cannot write: their credential is read-only. The human can do both, which is why the human is the only one who can be wrong by name. The small print: the agent not merging is a written rule, not a lock on the server.
Before a person is asked anything, the branch goes through sixteen steps that can fail. They refuse what a reading by eye does not catch:
A guard is only worth having if it can fail, and one that finds nothing looks like one that cannot. The most delicate ones carry a positive control that blows them up the moment they stop looking. The last door is not automatic either: production is deployed by hand.
publish without anyone reading it
Non-citable names: a client who must not appear in a public repository.
Copy outside the CMS: a label that exists in one locale only, or a sentence burnt into a template.
Colours outside the system: a literal or a new width, which is how seven different measures come back.
Caching in the wrong place: a call placed after the headers have gone, which caches nothing and looks like it does.
Copy that changes by itself: the rendered text of 26 routes is frozen.
Images that ask for themselves: an absolute URL to our own domain, which cannot work on Cloudflare and looks perfectly fine locally.
Accessibility and contrast: keyboard traversal, reflow at 320 pixels and W3C validation.
All checks have passed — quality-gates / gates
✓ gitleaks✓ citability✓ astro check✓ seed schema✓ CMS text✓ design tokens✓ cache hints✓ unit tests✓ build✓ boot the stack✓ html-validate✓ frozen copy✓ headers✓ image hrefs✓ accessibility✓ LighthouseThe numbers
An undated number is the worst possible place for drift, so there are two kinds here and they never mix. The threshold lives in a file: 95 or more for performance, 100 for accessibility, best practices and SEO, over the median of three runs under mobile emulation.
The measurement carries its date. On 24 August 2026, against the production build: 100 in all four categories across all five addresses, with the largest content painted in under 1.6 seconds. Each figure is a median, and the bound is the worst of the five.
The workshop, in plain sight
The repository is public and syncs on every change to the main branch, whole history, unfiltered. Publishing like that has a cost: that is why the non-citable-names guard exists.
Code, seeds, checks and deployments: it is all there. Look inside and tell us if you would do it differently.
PARTS INCLUDED
- the edge ×1the
workerthat answerssrc/worker.ts - the door ×7the security headerssrc/middleware.ts
- the render ×26the public routessrc/pages/
- the CMS ×5a plugin of ours on the
EmDashAPIsrc/plugins/cache-purge.ts - the data ×3
D1,R2andKVwrangler.jsonc - the origin ×43the whole corpusseed/seed.json
- the engineers ×3not included: already there
ASSEMBLY
- 01write the seeds
- 02the skill sets the voice
- 03the agent drafts
- 04human review ✋
- 05pull request and merge
- 06deploy to the edge
Do not assemble without step 04. The agent drafts, the human signs.
Step 03 never merges. Ever.
Assembly time: three weeks, in odd hours.
Hardware included: zero handoffs.
Let's talk, engineer to engineer.
Bring the problem as it is. You'll hear back from the person who'll write the code.
Tell us about your project