How a Living Website Runs and Repairs Itself Every Day

Cloudflare Workers keep time, Claude routines write and check, and almost everything runs on free tiers and a subscription.

How a Living Website Runs and Repairs Itself Every Day

A travel site is never finished. Places close, opening hours change with the seasons, a guide gets a detail wrong, and every page that misses it starts telling its readers something false. StayByCity, a travel site I built and run on my own, has hundreds of pages to keep true and new ones to add every week: a job for an editorial staff, and the site has none.

So the site does that job itself. On a Wednesday at 21:00 UTC an AI agent starts on a schedule and writes eight food articles. Each article is read three times, checked against its sources and against its city’s guide, and given a photograph that a second agent looks at before anything ships. The batch arrives as a proposed change to the site, what developers call a pull request, and it is merged into the site automatically if the checks pass. By morning the pages are live and announced to search engines, without anyone having touched them.

I call that a living website: a published site plus the engine that keeps it alive, adding pages on a fixed cadence, maintaining the ones already there, and checking, repairing and measuring all of them. Each piece of the engine runs where it fails least and costs least, and almost all of it runs on free tiers and a subscription I already pay for.

The loop: data, choosing the work, production routines, checks, pull request, gate, publication and announcement, with the morning routines feeding the same pull requests

A Static Site With Everything Alive Around It

StayByCity had 666 published pages on November 3: city guides, itineraries, food articles, beaches and Christmas markets. The pages are static: a site generator, Astro, turns them into plain files when the site is built, and a small program on Cloudflare’s network, a Worker, serves them. There is no database behind them and no server to keep patched, the same reasoning that moved this blog off Ghost. Everything that changes the site lives instead around its repository, the versioned archive of all its files: routines that write and correct, Workers that keep time and merge, a dashboard that collects the numbers.

I built it with Claude Code, Anthropic’s AI agent for software work, and the routines that run it are Claude Code too: sessions that Anthropic’s cloud starts on a schedule. The repository is the single source of truth, and a routine never writes to its main branch, the copy the site is built from. Whatever it produces arrives as a pull request, with the exact list of what it changed, which is what makes the rest of this design possible.

Three Homes, Each With a Reason

The routines run in Anthropic’s cloud because the subscription covers that work: writing, the three readings of every article and the choice of photographs need no server of my own and no separate bill. A few steps also run outside any session, in jobs that call Anthropic’s API directly, so every step that uses a model exists in two versions, one for a Claude Code session and one for the API. Both read the same instructions and pass the same validation, so a step does the same thing whether I start it, a routine does or a job does.

Cloudflare holds the clock and the merge decision, because the clock has to be on time and the merge rule has to sit where no pull request can change it, and GitHub gave me neither. A Worker with a small database keeps time and collects the numbers, a second Worker merges and watches, Cloudflare’s build service builds the site and runs the checks, and its storage keeps the image cache and the map data.

Where each piece runs: routines and the Messages API at Anthropic, the repository and Actions runners on GitHub, Workers Builds, the site, bot and dashboard Workers and R2 on Cloudflare, with every build reading and writing its image cache in R2

GitHub hosts the repository and keeps only a few jobs, and the reason is most often the network. Some services judge a caller by its address, and a Worker or a cloud sandbox shares its addresses with everyone else’s: Bing’s API for site owners refuses calls from a Worker, and an anonymous image search on Wikimedia Commons from the routine’s cloud took between 50 and 75 minutes. A shared address is a reputation you inherit. So the few jobs that need a clean address run on GitHub’s own machines, and the Commons search now runs with my own credentials, which no tool ever sees, in 51 seconds.

One Subscription and Free Tiers

In mid-October the routines used about $7 every two weeks of the $250 monthly credit that comes with my Claude subscription, and the steps that call the API draw on credits it also includes. That subscription is the main running cost, and I would pay for it anyway, because I use it for everything else.

The rest sits on free plans: the Workers, the database, the access control and the analytics on Cloudflare’s, and the private repository on GitHub’s, whose 2,000 monthly minutes of automation it shares with my other private repositories. The metered costs are small: about three cents for each generated image (a dish’s cover when no freely licensed photograph shows it, or the background of a Pinterest card), a couple of dollars of GitHub minutes in a month that runs past the free ones, as October did, and the domain.

Two choices in the design come from free-plan limits: staying inside GitHub’s minutes is why the deploy and the checks run on Cloudflare, and the missing branch protection on GitHub’s free plan, the setting that blocks a merge until the checks pass, is why the merge rule lives inside a Worker. Nothing stops the site from moving to Cloudflare’s $5 paid plan the day a limit is worth more than five dollars.

No Scheduler Is Trusted Alone

The clock is a Cloudflare Worker that ticks every fifteen minutes and starts whatever is due, because GitHub’s own scheduler can start a job hours late: one nightly data collection meant for 05:30 UTC once began at 13:20. GitHub keeps a single safety net that catches anything the clock missed during the day and calls me when it has to step in. The last layer is the one I trust most: every job that collects numbers re-reads the last few days, so a night missed by any scheduler fills itself on the next run.

The Gate Lives Where No Pull Request Reaches

A routine’s pull request merges itself only when two things hold: the automatic checks pass, and every file it changes sits inside the routine’s perimeter, the part of the site it is allowed to touch. Content routines may touch guides and data; the repair routine may touch tools, never the files that guard the rest. The rule lives in a deployed Worker that no routine’s pull request can change. The checks that run the pull request’s code hold no passwords or keys, and the Worker that decides the merge never runs that code at all: it reads the result of the checks and the list of changed files.

The merge gate: a routine's pull request, the label, the check on Workers Builds, the perimeter, the merge by the bot Worker, the deploy and the announcement

Every gate is tested where it will be relied on, with an input it must refuse. A deliberately broken draft once passed a build that read an old cached copy instead of the pull request’s files, and merged itself; it was a draft, so nothing was served, and since then a gate counts only once it has been seen saying no.

Whoever Writes Never Judges

The night in the opening is the food routine, which runs four nights a week and takes the most-read cities first. The three readings are as a reader, as a local and as a fact-checker, and a correction needs a source, otherwise the claim is softened or dropped. A verification pass looks for contradictions and for consistency with the city’s guide, and the photograph is checked by a fresh agent that did not choose it. Fresh, because the chooser writes the captions, and three of the first four refusals were captions.

The life of a food article: dish row, queue, writing, validation, cover, three readings, corrections, verification, photo check, publication

The checks earn their cost on the details nobody would think to doubt. An adversarial pass, a research agent plus a skeptic told to default to “refuted” when uncertain, removed a claim about a low-tide passage to Ondarreta in San Sebastián that the municipal police sealed in March 2026. The routine’s own verification found a published guide placing tram line 2 at Place Masséna in Nice, a stop that belongs to line 1, and the fix shipped with a source the next day. The checks are checked too: Chengdu’s fact-check proposed correcting the article’s winter opening hour from the panda base’s homepage, and the step that decides which corrections to keep turned it down, because the same site’s ticket-rules page publishes the seasonal times the article used. Acting on it would have introduced the error it meant to remove.

Not every step is an agent, on purpose. An agent re-reading one article once used 1,202,491 tokens, the units a model’s work is counted in, and exhausted the session limit, while a purpose-built tool reads the same article with 3,693. Photographs went the same way: the model now picks each photo in a single call, which costs 27 times less than the agent it replaced, with the same model looking at the same pixels. The model stays because without it six of nine picks were unusable, among them a cemetery under “Where to stay”.

How the Site Learns

Every defect becomes a row in a ledger, with what broke, how to verify it and when it closed: 156 rows between July 27 and November 2, 155 of them closed, and 47 files of regression tests, the automatic checks that keep a fixed defect from coming back, each born from a real one. Reporting a defect is not fixing it, so every open row is work for something that can act on it.

Three mornings a week that is a repair routine. It takes one open row, writes first a test that catches the defect and then the fix, and its pull request merges itself only inside a narrow perimeter that excludes every guard and alarm. The project’s notes give the reason in one sentence that I would sign today: a model pressed to turn a check green can do it by loosening the check, so the checks are what it may not reach.

My Part Is Traffic

The site runs itself, and what I do with it is decide where traffic can grow. The search data from Google and Bing, the visits measured by Google Analytics and Cloudflare’s numbers sit in one place, built to be read by a program as well as by me, so I open a session with Claude and we work out together why a number moved. Over the last three months the food pages brought most of the site’s Google clicks, so since November four nights a week go to food.

Pinterest is the other lever. Every Saturday the clock proposes eighteen pages, cards are made, a model checks each one, and the pins that pass enter a queue that posts three a day. I see every queued pin before it goes out, I can swap its image or postpone it, and each decision is recorded.

A short list stays mine too: the site’s identity, money, deletions, accounts and any code outside a routine’s perimeter. When a routine, a merge or a deploy fails, an alarm reaches my phone. Everything else is the system’s job, and each of the 156 rows in the ledger is a place where it learned part of it.

My Next Crazy Experiment

What I still do, deciding where the traffic can grow, is the part I want to hand over next, or almost. I want to define agents that read the same numbers and decide how the site should change course, whether that means a different kind of page, a different use of the nights or something I have not thought of yet: an engine with a brain of its own, while the keys stay mine.