The pipeline lives in the repo it deploys
Self-mutating deploy pipelines: the pipeline that builds a product is defined inside that product's own repository, and it updates itself before it ships your code.
The pipeline lives in the repo it deploys
There's a moment on most projects where the deploy pipeline becomes a museum piece. Someone set it up at the start, by hand, in a CI tool's web UI. It works. Nobody remembers exactly how it's configured, and nobody wants to touch it, because touching it means clicking through settings pages and hoping. The pipeline drifts away from the application it serves until the two are strangers.
We don't build pipelines that way. Our deploy pipeline is defined as code, in the same repository as the application, and it has one unusual property: it updates itself.
Self-mutation, concretely
On AWS we use CDK Pipelines, where this pattern is first-class. The pipeline's own definition is a construct in the repo. The first thing the pipeline does on each run — before it builds anything, before it deploys a line of your code — is read its own definition from the latest commit and reconfigure itself to match. If you added a stage, the pipeline grows the stage on its next run. If you changed a deployment region, the pipeline rewires itself. You never click into a console to update the pipeline, because the pipeline updates the pipeline.
This is what "self-mutating" means. The pipeline is not a fixed machine that runs your code. It's a machine that first rebuilds itself from the repo, then runs your code through the version it just became.
Why it matters more than it sounds
Three things follow, and they're the difference between infrastructure you trust and infrastructure you fear.
The pipeline can't drift. There is no gap between "what the pipeline does" and "what the repo says the pipeline does," because the repo is the only source and the pipeline rebuilds from it every time. The museum-piece problem is structurally impossible.
Pipeline changes get reviewed like code, because they are code. A change to how you deploy goes through a pull request, gets read by a human, runs through the same checks as everything else. Compare that to the normal world, where someone with console access quietly changes a build setting at 5 p.m. on a Friday and nobody knows until it breaks.
Onboarding is reading, not archaeology. A new engineer — or an AI agent working in the IDE — learns how the system ships by reading a file, not by spelunking through a CI vendor's settings pages that may or may not reflect reality.
The same pattern, our products and yours
We run this on our own products. New Austrian Economics, our content property, deploys through a self-mutating pipeline defined in its own repo. That's not incidental — it's the point. The patterns we recommend to clients are the patterns we live with daily, which keeps the advice honest. We don't suggest a deployment approach we wouldn't run ourselves, and we don't run anything in production for a client that we haven't already broken and fixed on our own infrastructure first.
The cost, stated honestly
This isn't free. Pipeline-as-code has a steeper initial climb than clicking through a setup wizard. You have to define the pipeline in a real language, in a construct, and the first deploy of the pipeline itself has a chicken-and-egg bootstrap step. For a weekend script that will never change, it's overkill, and we'd tell you so.
But that's not the work we take. We take multi-year programs and production products, the kind where the pipeline will be touched dozens of times by people who weren't there at the start. For that work, a pipeline that drifts is a liability that compounds quietly for years. A pipeline that rebuilds itself from the repo, every run, simply doesn't have that failure mode.
The deploy pipeline is part of the system. So it belongs in the system's repo, in code, reviewed and versioned like everything else — updating itself before it ships your work.
Have a pipeline nobody wants to touch? Start a conversation.