I’m not one to usually write about product launches (insofar as I’m one to “usually” write about anything.) I’m making an exception to an unwritten policy I don’t follow because I already run most of my business and my homelab on the thing that launched.

Swamp went public today. The framing in the launch is “behavior-centric” AI design, positioned against the “agent-centric” approach that most of the industry has been building on since late 2022. If that sounds like another framework trying to name a category, I understand your skepticism. I’d like to walk through what the distinction actually means once you are the person who has to keep the result running.

The agent-centric version

The default way to build with a model right now is to hand it a pile of tools, give it some context, and let it decide what to do next. The model is the center of the program: it reads the situation, it picks a tool, and it reads the result. Then, it decides whether it is done. When the task gets bigger, you add more tools, more context, sub-agents, memory schemes, a gateway in front for security, a router to pick the model. The shape never changes: the model is driving the control flow.

That works fine in a demo. It works fine when the person who built it is the person using it, because they know why it sometimes skips a step, and they just run it again. It’s a papercut, not a problem… to them. The issue is that despite giving heaps and heaps of context, you still run up against a fundamental limitation with the pattern itself: garbage in, garbage out. You can dress up the garbage, make it smell nicer, pile on retries until it works 100% of the time (at an 80% duty cycle.) All of that papers over the problems, and exactly none of it addresses the underlying root causes.

It stops being fine the moment someone else depends on it, or the moment it runs without anyone watching. A trip planner that occasionally forgets the hotel is a funny story until it’s a booking system and someone lands in another city without a room. To make it reliable enough to trust, you add validation layers, retries, and more agents whose only job is to check the first agents. Every one of those costs tokens on gathering its own context and reasoning about its own output. The bill grows faster than the capability does. That’s the part that doesn’t survive contact with scale.

Last year, at a conference, I overheard a group of elder DevOps folks (30- and 40-somethings, which apparently makes us elders now) telling a fresh college grad that he should be managing a team of AI agents to do his work for him. Not learning how the systems work, or how to troubleshoot them. Managing agents. Apparently the natural progression from graduating college is becoming a middle manager for a bunch of stochastic interns.

It rubbed me the wrong way, but I couldn’t quite articulate why. I’m obviously not opposed to using AI to do work. I use it constantly. But telling someone who’s just starting out to delegate decisions they haven’t yet learned how to evaluate seems completely backwards. And the people giving that advice should have known better.

I didn’t have a particularly good name for what bothered me about that advice at the time. I do now.

The behavior-centric version

The alternative is to stop letting the model drive.

You decompose the intent into small, typed behaviors. Each one does a single thing, takes validated inputs, produces structured data against a versioned schema, and has its own scoped access to credentials. You compose those behaviors into a workflow that calls them in order. A model gets called only where the job genuinely needs intelligence, perhaps to turn a messy human request into structured parameters at the very start. After that, it’s ordinary deterministic code.

The important move is that the model is no longer responsible for control flow. It’s a step, not the conductor. You use frontier intelligence at build time to encode your intent into behaviors you can rely on, instead of paying for it at runtime to re-derive what to do on every single call.

There’s a catch, of course: you still have to give a shit about what you’re building. You–the human, not a meat puppet clicking “approve”–have to read the inputs, understand the assumptions, and check that the result actually does what you intended. Garbage in, garbage out still applies here, if not moreso when the result is code that will faithfully repeat your mistake every time it runs.

The difference is that those decisions are made while you’re building the behavior, where you can inspect, test, and change them. You have control over what gets built, and more importantly, how it works. That’s quite a different proposition from handing a model a goal and hoping it makes all the right decisions between here and there.

And, circling back to that conference anecdote, this is the distinction I wish I’d had the words to make at the time. There’s nothing wrong with using a model to help you build something you don’t yet know how to build. That’s a fantastic way to learn, provided you’re actually paying attention. But there’s a world of difference between using intelligence to develop your own understanding and outsourcing the understanding altogether. One leaves you with something you can reason about. The other leaves you managing something you may not even know is wrong.

What that buys me in practice

I didn’t start using Swamp because somebody launched it. I’ve been running it in my shop well before today, and at this point it’s responsible for quite a lot of what goes on around here.

For example, I built a Swamp extension to inventory a Heroku estate: apps, dyno formations, add-ons, custom domains, config var names, pipelines, all of it. Well, almost all of it. I deliberately excluded the secret values that the Heroku API would quite happily hand over, because I didn’t need them and had no intention of collecting them just because I could.

The result is a versioned inventory that I can query and compare over time. I can see what changed between this week and last week without having to ask six different people whether someone touched production. I wrote about that separately.

And it’s hardly the only place I use this approach. Patching servers on a schedule, provisioning and configuring build boards, inventorying cloud resources–all things that have enough moving parts to get interesting, and all things I’d rather not have to babysit.

Where a model is useful, I use one. But I don’t need a model waking up every Tuesday to figure out what “patch the servers” means. I need to define that once, verify that it does what I want, and then let it run. If something needs to change, I change the behavior. The same inputs should follow the same path, and if something fails, I should be able to tell you where and why without reconstructing an agent’s conversation history.

To put some numbers on it, over the last quarter Swamp executed north of 900,000 traced operations across my homelab, my business, and open source work. Looking back over the last year or so of tracked work, roughly half of it has passed through Swamp in one form or another.

That’s a lot of work I didn’t have to sit there and manually execute, and importantly, it’s not 900,000 opportunities for a model to improvise what happens next. It’s code executing behaviors I’ve already defined and tested.

Now, none of this means the code is magically correct. I write bugs, APIs change, assumptions turn out to be wrong, and computers remain stubbornly committed to doing exactly what you told them to do instead of what you meant.

But those are problems I know how to deal with. I can inspect the inputs, look at a trace, reproduce a failure, and fix the behavior. I’m not trying to figure out why a model decided that today was a good day to skip step four.

That’s why I’m comfortable leaving this stuff running unattended. Not because it can’t break, but because when it does, I’m dealing with a system whose behavior I can understand and control. Runtime contracts won’t save me from writing bad code, but they’ll give me a much better chance of catching it than hoping a model remembers all the rules I put in its system prompt.

The reusable point

I don’t think any of this is especially revolutionary to someone who’s spent enough time operating production systems. Explicit inputs, defined interfaces, limited privileges, predictable execution, and failures you can actually investigate are not new ideas. We’ve been building software around those principles for decades, or at least trying to.

What is new is having models capable of helping us build that software, and then deciding whether we want to use that capability to produce something we can operate, or to put the model in charge of operating it.

Swamp calls the former “behavior-centric,” and I’m happy enough with that name. Whatever we call it, I’d much rather spend the intelligence figuring out how something should work once than pay to have the same question answered every time it runs.

The end result is infrastructure that’s a lot less exciting to operate.

Which, as usual, is exactly what I want from it.