№ 01 Case files

Three changes, with the receipts.

Every hosting company claims agents ship changes fast. Here are three that actually shipped on this exact site — the plain-language brief, what the agent did, what human review caught, and the diff behind each one, read straight from this repo's own history.

№ 02 By the numbers

The whole ledger, not just three rows

Every figure below is read from this repo's own merge history at build time — see the FAQ for how.

Changes shipped
96
7 July 2026 → 27 August 2026, across 52 separate shipping days.
Pace
12.9/wk
Busiest day was 10 July 2026, with 22 changes shipped.
Diff size
+61700 / −5238
Across 1097 file changes, every merge counted.
Automated guards
15
Merges that added or tightened one of this site's own build-time checks.
№ 03 The case files

Three changes, followed end to end

Each one started as a plain-language brief and ended as a merged pull request. The spec row under each brief is read from that merge's own commits, not typed by hand.

CF-01

The site is blinding at night

“The site is blinding at night — support dark mode.”

19 files · +751 / −258 · shipped 31 July 2026

  1. 01

    Add the dark half of the palette

    Every colour on this site already lived in one tokens file, so the theme is a single :root[data-theme='dark'] block there — no second copy of the palette behind a media query to drift out of sync. A new --on-accent token was added for text sitting on an accent fill, which flips separately from --ink.

  2. 02

    Resolve the theme before first paint

    The layout's <head> got an inline script: read localStorage's stored side, else follow the OS's prefers-color-scheme, write data-theme on <html> before the body paints, and keep following the OS live until a visitor picks a side.

  3. 03

    Add the DAY/NIGHT toggle

    The header grew a labelled rocker, not a moon icon — on brand for a utility that already talks about shifts. It renders hidden until that same inline script un-hides it, so a JS-off visitor never sees a dead control.

  4. 04

    Keep the always-dark bars dark

    The contact and footer "switch room" bookends, plus a few permanently dark bars elsewhere, were repointed at theme-invariant tokens instead of the ones that flip — so they read as a darker, separate room in both themes rather than inverting.

  5. 05

    Teach the accessibility crawler to see both themes

    The automated a11y check had only ever scanned the one palette that existed. It now opens every route in a light-preference browser context and a dark-preference one and scans both.

What review changed

Review sent this branch back twice before it merged: two tokens behind the homepage's technical figure had no dark value at all, so its dashed construction lines, dimension rails, and vent strokes all composited to near-invisible on the new background — the figure lost its draughtsmanship and left two captions floating with no rail attached. And the DAY/NIGHT rocker itself picked up a display style that silently defeated its own [hidden] guard, so a JS-off visitor would have seen a control that looked live and did nothing. Both were fixed on the same branch.

A full day/night theme, auto by default and sticky once a visitor picks a side, everywhere on the site.

See it flip on the homepage →

Make sure someone on a screen reader can actually use this

“Make sure someone on a low-contrast display or a screen reader can actually use this.”

46 files · +957 / −80 · shipped 28 July 2026

  1. 01

    Crawl every route with an accessibility engine

    A new check-a11y script drives a real accessibility engine across every route in the sitemap and asserts the WCAG 2.1 A/AA rule set, plus one heading and one main landmark per page.

  2. 02

    Fix what the crawl found

    Contrast values in the token file and a dozen individual pages were adjusted to clear AA, and a handful of heading levels that skipped a step were corrected.

  3. 03

    Add the document-structure checks the crawl misses by default

    The engine files heading-order, one-h1, one-main, and landmark-region under its own 'best practice' tag rather than the WCAG tags the crawl otherwise runs — so the guard now runs those four rules explicitly instead of trusting the tag filter alone.

  4. 04

    Close the crawl's own blind spot

    The engine never simulates :hover, so a failing hover state can ship invisibly. The guard now rewrites every :hover colour rule into an unconditional one at scan time and re-runs the contrast check against that.

  5. 05

    Fix the regression the fix itself introduced

    A short follow-up branch caught a heading skip that the first pass had relocated rather than removed on /selector, and taught the guard to see that shape of mistake too.

What review changed

Review's own read of the first pass is what surfaced the hover blind spot: a primary call-to-action's hover state was failing contrast and no automated run had ever caught it, because the crawl never triggers :hover. The fix is the guard, not just the one button. The follow-up branch then caught a heading-order regression the original fix had introduced on /selector — the loop catching its own mistake, not just the site's.

Site-wide WCAG 2.1 AA contrast and heading-structure fixes, plus an automated crawl that runs against every future change in both themes.

Read the accessibility page →

Answer engines should be able to read the whole site

“Answer engines should be able to read the whole site, not just the pages we remembered to list.”

11 files · +651 / −146 · shipped 2 August 2026

  1. 01

    Build one manifest for every route

    A single module composes the site's navigation data plus the guide, stack, audience, and legal content modules into one grouped list of every route and its description — throwing at build time if a route is missing one.

  2. 02

    Render it for people

    A new /directory page renders that manifest as an on-brand, grouped index — the back-of-manual reference for a human visitor.

  3. 03

    Render it for machines

    A generator writes public/llms.txt in the shape the llms.txt convention defines, from the exact same manifest — one data source, two renderings.

  4. 04

    Chain the generator into the build

    bun run build now regenerates llms.txt before astro build runs, so what ships is always current with the manifest at the commit being deployed, not a file someone regenerated by hand last month.

  5. 05

    Guard the drift after the build

    A post-build check reads the built llms.txt and sitemap and fails if any sitemap route is missing from llms.txt, listed twice, or points at a link that doesn't resolve to a real file.

What the audit caught

An automated audit of the site is what surfaced this, not a human reading the diff: the machine-readable index was the one failing check on an otherwise clean homepage, because it listed its URLs as plain text rather than links — so a link-following crawler saw no index at all — and it had already drifted behind the pages that existed. Patching that file would have left it a hand-maintained second copy of the site's structure, so the change deleted the copy instead: the human directory and the machine index are now both rendered from one manifest, and the build fails loudly rather than letting the two drift apart again.

A human directory page and a generated llms.txt, both read from one manifest that cannot fall out of sync with the site.

Browse the directory →
№ 04 Where the work went

Not just the marketing copy

File changes across every merge in this repo's history, grouped by what kind of file they touched.

Site components & copy
658
Generated assets
308
Docs & config
61
Infrastructure as code
37
Build & check scripts
26
Deploy pipeline
7
№ 05 What this means for your project

The same loop, on your codebase

  • Already hosted somewhere, or about to be?

    Host with us and CodeHerder can iterate on your codebase the exact way it iterates on this one — brief a change, review the pull request, ship the merge.

    How the loop works →
  • Want the full ledger, not three examples?

    Every one of these three case files is a single row pulled out of a much longer public record of merges to this site.

    Read the full ledger →
  • Want to know what it costs?

    Hosting and the CodeHerder iteration line are both flat monthly rates. A net-new CustomLabs build, like the one behind each case file here, is quoted separately.

    See how a month is billed →
  • Have a change in mind already?

    Describe it in plain language, the way every brief on this page started. One fixed monthly rate, in writing, within a business day.

    Get a quote →
№ 06 FAQ

Case file questions

What this page is proof of, and what it deliberately doesn't claim.

  1. 01Are these real pull requests, or a demo built to look like one?

    Real. Every branch named on this page is an actual merge in this repo's own history — check:ledger fails the build if one isn't.

  2. 02Why only three case files, when built-in-the-open lists dozens more rows?

    Built in the open is the full ledger, one line per merge. This page is that ledger's slow lane: pull a handful of rows and show the paperwork behind each one — the brief, the steps, what review caught, the outcome.

  3. 03Where do the numbers on this page come from?

    A small script reads this repo's own git history at build time — the same merge commits the ledger counts — and writes the file counts, line counts, and dates this page interpolates. Nothing here is hand-typed.

  4. 04Why doesn't this page say how fast a change went from brief to live?

    Because agents in this repo commit once at the end of a session, a measured first-commit-to-merge time would describe that bookkeeping, not how long the work actually took — so we don't publish a number we already know is misleading.

Want this loop running on your project?

Host with us and CodeHerder's agents can iterate on your codebase the same way — brief a change, review the pull request, ship the merge.

Get a quote