← Notes

Beyond vibe coding · Part 1

Beyond vibe coding: the pipeline

Part one of a series on what it actually takes to build software solo, with AI. This part: the pipeline.

Vibe coding gets you a demo. Shipping something you would put your name on takes a pipeline, and the willingness to understand it.

Vibe coding is the glossy magazine-cover version of the AI promise: describe an app, watch it appear, feel done. I love the speed of it, and the speed is real, yet all it ever gets me is a fast demo, a quick experiment. I bet you have been there too. The moment you want to ship something you would put your name on, the glamour ends and the engineering begins. It starts with the most underrated piece of the whole thing: the pipeline, and the willingness to understand it. Spoiler: setting your pipeline up like a pro is actually fascinating.

The mystery in the middle

For me, and I suspect for a lot of non-engineers, the pipeline was a black box that Platform or DevEx owned and that somehow worked, or somehow didn't. It came wrapped in enough complicated terminology to make the message clear: stay back, let the experts handle it. Problems were mysteries and solutions were never certain. Each deploy was a gamble, and God forbid you ever needed a rollback.

So tackling CI/CD was a deliberate step outside my comfort zone. I learned it the only way that sticks, hands on and step by step, with AI as my guide. Because here is the thing: CI/CD is a solved problem, it just travels with heaps of jargon. What finally cracked it open was asking Claude to break it into plain terms and walk me through it stepwise, creating the accounts, setting up the secrets, wiring it all together. Doing it by hand, with a guide, gave me a tangible feel for the whole construct.

Let me hand you the outline of what I learned. At a high level there is the idea, then there is the code, and then there is a working app, which might show up in several environments, dev, stage and prod, or across several tenants, like different markets. CI/CD is what floats in the gap between the code and the working app, and it comes in two halves: CI, continuous integration, and CD, continuous delivery.

The integration half takes a piece of code, a new feature or a bug fix, written in Java, C++, Ruby on Rails, .NET, whatever the language, and folds it into the existing code of the app. Tests run as part of this, to make sure the new code does not break what was already there. The result is a thing called an artifact, a single packaged-up version of the built app, and it is versioned, so if it turns out to be a bad idea after all, you can step back to an earlier one. For now, though, the artifact just sits there like a puppet on a shop shelf. Until someone picks it up, names it Mr Jones, and sits it down at the tea party with the toy bear and the plushy that looks like a design accident, it does nothing useful at all. So let us get the artifact to its tea party.

This is where the delivery half comes in, and where the rubber hits the road. Here the artifact becomes the working app, and to do that it has to be placed where the app actually runs, on a server or, more likely these days, in the cloud. That is the kid's room. It needs its specifications too, say the settings that make it fit one market or another, which is how the puppet gets the name Mr Jones. And it needs testing before the tea party starts, so in a dev or stage environment I check whether the app really does what I meant it to, and fix what it doesn't, before letting it out into the wild and into real hands. This half gets versioned as well, so if something goes wrong, rolling back to the last working version is easy.

The pipeline I run

My CI/CD pipeline for websites and web apps is three tools in a line: GitHub, Octopus Deploy, Cloudflare Workers. GitHub owns the CI half: it holds the code and, through GitHub Actions, builds it into a versioned package. For the CD half I use Octopus, a tool made specifically to turn deployments into boring events. GitHub pushes that finished package to Octopus, which preps it into an immutable release and moves it onto the Dev environment automatically so I can test. When I am happy, I move it to Prod with the click of a button. That click is the human gate, to make sure nothing escapes into the wild without me wanting it. Dev and Prod are both Cloudflare Workers, which run the site.

The principle behind it: the build half and the delivery half stay strangers to each other. Each does one job only, and does that one job well. Every release is a snapshot, this exact package with these exact settings, ringfenced so the wrong thing cannot slip out and two sets of changes cannot get crossed. If a release turns out to be a disaster, rolling back to the last good one is a single clean move, not a panicked dig through history.

This might sound like a lot of machinery for a small site. However, it makes tracing a failure mind-blowingly faster, cleaner, and far less frightening. Good tools and a properly set up workbench pay for themselves quickly. I have a playbook now, and standing the whole pipeline up for a new idea takes me about thirty minutes end to end. Done, and never worried about again. I proved the pattern on daily-intentions.app first, then ran the same playbook clean on neonpale.com. A steep climb the first time, easy every time after.

The human in the loop

Over the years I have picked up a fair bit about how software gets built: security principles like least privilege and gated access, robustness principles like clean code and leaving seams for where the thing might go next, and the plain human instinct to keep asking, is this really it, what are we missing?

Let me share a few examples where I pushed the AI. When I first wired up Cloudflare access, the default token carried a sweeping set of permissions, around two dozen. Even to me, a self-confessed platform imbecile, that sounded like rather a lot. So I stopped and asked what the pipeline actually needed. Three, it turned out, and I scoped a custom token to exactly those. Least privilege in action, so that a leaked key, if it ever happens, has a far smaller blast radius. Once the pipeline stood up, the pages were still wide open to anyone. A working pipeline is not the same as a finished one, so I gated access until each site was ready to be seen.

None of this is witchcraft, but it does take a human to hold the overview and think a step ahead. Asking the AI to critique its own work has become a habit after every major step, alongside the more useful interruptions: stop here, I am not sure I follow. Or, wait, I think you are missing something. Plenty of times everything was fine. Often enough it wasn't, and I caught the flaw. I am convinced this is no different from working with a good team, the pausing, the reflecting, the critiquing. It is the difference between something I would demo and something I would hand to a stranger.


Written 9 June 2026. Intentions is in closed beta on iOS at the time of writing. The pipeline described here runs the studio's web surfaces; the iOS release path is its own story, and perhaps its own note.

More to come

More to come, bit by bit:how I ideate, how I design, how I iterate, how I test.

If you want to know more, or you have an idea to share, reach out.