I never took the kind of pleasure in writing code that some engineers do. Solving problems - simple or complex - yes, always. But the code itself was only ever a means to an end. For years my LinkedIn has carried two words that say it plainly: “tech agnostic”.

Most of my career ran on Python. Not out of love - out of range. Automating the provisioning of network services, building a data platform chewing through hundreds of gigabytes a day, scraping every data format that exists, writing a bespoke framework to monitor hundreds of systems running on virtual infrastructure of several thousand VMs - Python did the job every time. It was the Leatherman on a shooter’s belt: you reach for it, it works, you move on. But this never stopped me reaching for Rust, PHP, Hack, JavaScript, TypeScript, Bash or even Ruby when one of them got to the result faster. Each is a tool. A means to an end, nothing more.

I start here because it’s the lens I bring to what’s happening now.

A proper evolution

We’re watching a real evolution - the kind that upends what we took for granted and redefines the discipline it came from: computer science. I’ll admit the pace caught me off guard, even though I could feel under my skin that the next few years would move a lot. The models and tools are sprinting - the processes are limping behind, still forming. How software gets made - and how it lands in everyday life - is changing underneath us.

And the thing gaining weight in all this is exactly the stance I started with: technology as a means, not the point. Pair that with a systems mindset and you get back to what always mattered - solving the problem, not admiring the tool that solved it.

This is the same thread I’ve been pulling for a while: in Idea as a Code, the source of truth moving from code up to intent. In The Day Your AI Forgets How to Think, a blunter version of the same point:

What reduces risk isn’t a better model. It’s better tooling, clearer processes, and an environment built to absorb the imperfections rather than pretend they don’t exist.

The word I keep landing on is environment. The agent is not the system. It’s one component in a system that, honestly, barely exists yet.

What its absence looks like

Here’s the felt version, at my desk right now: Warp open with a dozen-odd tabs, each running an agent. A few projects going at once across a dozen or so repositories - and me in the middle, context-switching like an air-traffic controller who also has to fly the planes.

Each agent is capable. Any one of them can take a task and produce a working change. That stopped being the problem. The problem is everything around the agent. Which one is waiting on my approval? Which quietly rebased onto a branch that moved twenty minutes ago? Which of these three changes touch the same file? What did that run cost? If I close the laptop, can I safely let one keep going from my phone?

Point two agents at the same directory and you get races and clobbered edits. A change across three repos is three pull requests held together with string. Agents get broad, long-lived credentials because scoping them by hand is friction. The dashboards show “now”, never “how long did this wait for me”. Tokens on a billing page map to nothing you care about. And you can generate far faster than you can review, govern, and safely publish - which is where the real risk lives.

None of that is a model problem. It’s coordination and control. A better model makes each agent better AND the gap between them wider - and it leaves you in the middle, carrying a cognitive load that eventually makes your head explode. Keeping it from doing that is the actual job.

You can’t buy your way out of this

“AI Software Factory” has been a loud phrase for a while now, and plenty of companies will sell you one off the shelf. Here’s the catch a shelf product struggles with: every organisation runs different processes, every person has different workflows, every team works under different constraints. A software factory isn’t a generic appliance you plug in. It’s your own daily workflows, mapped honestly and adapted to working with agents. Nobody can hand you that ready-made, because nobody else runs your process.

So I’m building my own - for myself first. Not because the market lacks products, but because the useful version of this is inseparable from how I actually work. And that leads to the uncomfortable part:

You cannot work effectively with GenAI without turning your existing approach to work upside down.

Not tuning it. Turning it over. The factory is the shape that new approach takes once you make it explicit.

A launcher is not a factory

Stripped down, “mapping your workflow to agents” means separating two things that are tangled together today:

  • A control plane - intent, state, history, policies, approvals, cost, audit. The part that must never run untrusted code.
  • An execution plane - where agents actually run, each in an isolated, disposable sandbox on a private workspace carved from an immutable snapshot of the repo. The part that assumes everything it runs might be hostile.

Between them: normalized events instead of raw terminal output, durable workflows that can pause for a day and resume without losing the thread, quality gates, and a publication step that opens a reviewable diff - not a silent merge.

The factory metaphor is deliberate. A factory isn’t autonomous. It’s instrumented. You can watch the line, stop it, inspect what came off it, and account for what it cost.

Human judgment, not a human bottleneck

This is the easiest place to say the wrong thing, so let me be exact. Human-in-the-loop does not mean a person sits at the end of the line reading every diff. Reviewing thousands of generated lines a day isn’t judgment - it’s a bottleneck wearing judgment’s clothes. I argued that already, and it doesn’t change here.

The mechanical part of review is exactly what should be automated and built into the process: tests, type checks, linters, security and dependency audits, policy checks, code-review assistants. Those are properties you validate with tooling, not properties a tired human reads into being line by line. The factory’s job is to run them and hand back a compact verdict - what changed, what was tested, what failed, what it cost, where the risk sits - instead of a wall of code.

What stays human is the part that was always the actual work: choosing which problem is worth solving, owning the architecture and the intent, judging whether the output truly solves it, and keeping authority over the consequential calls - which sensitive actions run, when work crosses a cost threshold, and what gets published, and when.

The control boundary follows from that. Agents never hold the keys to source control. A separate publication service takes an approved change, gets short-lived credentials, replays it in a clean environment, runs the gates, and opens a draft pull request. The agent produces a contribution, a human - reading evidence, not scrolling code - decides whether it becomes a publication. That line doesn’t move. The stack of code a human has to read to stand behind it should shrink toward zero.

What I’m deliberately not building

An honest scope is as much the “no” list as the “yes.” This is not a replacement for engineers, code review, Git providers, or CI - it sits around them. Not a new agent or model - I’m orchestrating the good ones that exist. Not a shared writable folder for agents to collaborate in - the opposite, by design. Not something that needs Kubernetes to run - it has to be useful on one machine first. And not an “autonomous software team” that removes the human from anything that matters. If a future post drifts toward autonomy theatre, treat it as a bug in the writing.

Starting local first

Version one runs on a Mac mini, driven from a browser and an iPhone. The constraint is a feature. Local first, not local only: small enough to force real decisions about what one node can do, structured so the control plane can later move to an always-on server while the Mac stays a private execution node. Start with the smallest system that keeps the boundaries correct. Add infrastructure only when a measurement - not a trend - demands it.

Why write this before I’ve built it

Because the plan for this series says build first, claim second and I intend to hold to it. This post makes no measurements and proves nothing - it’s a statement of intent, on the record, so the next posts have to be honest. Each will take one real question - how to isolate agent execution, how several agents share a project without corrupting it, how a run pauses for approval on a phone and resumes safely, what a verified change actually costs - and answer it with evidence, including the inconvenient kind. Where an assumption here turns out wrong, I’d rather show the correction than quietly edit the past.

If the mechanical translation from intent to code is moving to agents, the interesting work moves with it: describing intent precisely, and building the environment that turns intent into software you can trust. That environment is the real product. The agents are just the part that already works.

Next in the series: why the control plane and the execution plane have to be separated - and what breaks when a coding harness runs inside your backend.

— Adrian