v1 — free and open source
Astro Production Starter
An Astro starter opinionated about what happens after the site looks right — the operational work that keeps it correct six months later, when nobody is looking at it.
The engine that runs the gates is live, and the template in the starter repo is a working Astro site with all six wired into its build and CI. Green out of the box, and every failure it documents was verified to fail.
✓ build-id matches deployed content
✓ no third-party assets
✓ freshness OK
✓ discovery OK
✓ links OK
✓ budgets OK (a11y blocking)
astro-ops check OK — 6 gates passed
Why this exists
Astro themes sell design. Design is the part a competent developer already has. What almost nobody ships is the layer above it — the checks that notice when a correct-looking site has quietly stopped being correct.
Every gate here answers a failure that a normal test suite cannot see, because in each case the code is fine, the build passes, the page renders, and only the edge, the crawler, or the calendar is wrong.
It was extracted from four sites that had been running the same twenty-odd build scripts, copy-pasted into every repo. Measured before extraction: 7 of 12 core scripts were still byte-identical across three repos, and the five that had drifted differed by one to four lines — a site name, a path, a threshold. The logic never diverged. Only the config did, and the copies drifted anyway because a fix landed in whichever repo hit the bug first.
The six gates
Content-hashed build id
A build id keys your edge cache. Most projects grow two ways to deploy — CI plus a manual command — and a random or timestamped id cannot survive that: a git-integration build has no build step and ships whatever id is committed, while a local deploy rotates the file on disk. Ship a content change with the rotated id uncommitted and new HTML goes out under the previous key. Every colo keeps serving the old page. The origin is correct, the deploy "succeeded", and nothing in CI can see it.
Hashing the deployed output fixes it at the root, and the check that recompares on every build is the half that matters — it turns "someone forgot to regenerate" into a failed build a year later.
Freshness watchdogs
Some pages state a fact that belongs to somebody else: a fee, a size limit, a tax rate. You verified it once; the authority changed it later and did not tell you. Two tripwires, failing differently because each covers the other's blind spot — a calendar that works offline and covers every claim, and a drift feed that catches a source changing no matter how recently you checked.
A 5xx from your own drift feed is a hard failure, deliberately distinct from being offline. That distinction was paid for: a malformed record once made a feed throw, it returned 500 for days, and the check warned and exited zero the whole time. The gate was completely off and every run looked green. A safety net that reports OK while disabled is worse than none, because you stop checking by hand.
Performance budgets that block a merge
Everyone measures performance; almost nobody enforces it, and the two are not the same thing. A score you read after shipping tells you what you already regret. Accessibility blocks by default because it is close to deterministic. Performance is advisory by default, because Lighthouse moves several points between runs on identical code — blocking on it produces a coin-flip gate, and a gate understood as a coin flip protects nothing.
Discovery wiring
The part a per-page SEO plugin cannot do, because it needs the whole site at once: a noindex
page listed in your sitemap, a sitemap URL with no page behind it, a canonical pointing somewhere the page
is not. Each half looks correct on its own, which is why these survive review and surface months later in
a coverage report.
Link integrity
Every internal href in the built site has to resolve to a file that still exists, and URLs
have to agree with your trailing-slash setting. This is the gate that catches you after deleting a page
whose siblings still link to it — a 200 on the origin with a hole in the graph.
Privacy-first defaults, with a tripwire
"We don't use third-party CDNs" is a claim that decays silently. A dependency adds a font import three minor versions later; someone pastes an embed into a post. Nothing breaks. But if your site claims to be private, or you have a published privacy policy, an unannounced third-party request is a factual error in a legal document — and the only way to notice is to open the network tab on a page nobody thought to check. This reads what you actually ship and fails on anything you have not explicitly allowed.
What you can use today, for free
All six gates live in @acsaven/astro-ops — MIT, zero runtime dependencies, installed as a git dependency so there is no registry account involved.
- Six gates, 51 tests, no dependencies to inherit
- Running in production on three live sites, not a demo
- One config file per project — the logic stays in one place
npm i @acsaven/astro-ops
What v1 includes
A working Astro site — layout, pages, a sitemap generated from those pages, claim data for the freshness watchdog, a Cloudflare Worker that keys its edge cache on the build id, and a CI workflow that runs build, then gates, then deploy in that order.
It builds green, scores 100 / 100 / 96 / 100 on Lighthouse, and carries no npm vulnerabilities. Its README lists five ways to deliberately break it — and each one was actually broken and observed to fail before it was written down. A starter whose own failure examples do not fail would be worse than one that made no claims at all.
It is free, and it stays free. There is no paid tier holding anything back and no licence to buy. If that ever changes it will be stated here as a number and a date, not as "soon".
Save an address if you want
Optional. We store the address. Nothing is emailed yet — there is no mailer. No drip sequence, no countdown.