Swamp Club: Deterministic Automation for AI Agents

Last week I wrote about Google’s Open Knowledge Format and mentioned in passing that I run a background orchestrator that keeps a fleet of coding agents busy across my repos around the clock. A few people asked what actually runs that thing. The answer is Swamp, and it’s interesting enough on its own that it deserves its own post. So this one is about Swamp itself, with my autopilot as the worked example.

The problem Swamp is built for

If you’ve handed a real task to an AI agent, you know the failure mode. You ask it to do something involved, it does it, and it works. Then you ask again next week and it does something subtly different, or reaches for a slightly different command, or forgets a step it did last time. The capability was real, but it lived in a chat transcript, and now it’s gone.

Swamp’s tagline is “deterministic automation for AI agents,” and that’s the whole thesis. Agents are great at figuring out how to do a thing. They’re bad at doing the same thing the same way every time, keeping the credentials straight, and leaving behind a record you can search later. Swamp’s bet is that you let the agent decide what to do, but you make the doing repeatable, typed, and logged. It calls itself an adaptive automation framework designed to be operated by AI agents, which is a mouthful, but the emphasis matters: it’s built to be driven by an agent, not by a human writing YAML by hand.

The primitives

Swamp is deliberately small. It gives you a handful of building blocks and gets out of the way. Each one does a single job, and the interesting part is how they compose.

Models are the unit of work. A model is a typed interaction with some external system: a shell command, a cloud resource, an API. Each model has a type (something like command/shell), a set of methods (create, sync, delete), and typed schemas for its inputs and outputs. The clever bit is the split between the type and the definition. The model type is reusable logic written in TypeScript. The model definition is just configuration written in YAML. That separation is what makes the whole thing agent-friendly, because an agent can author a YAML definition without writing any code, and the typing keeps it honest.

Workflows orchestrate those methods. A workflow is a DAG of jobs, where each job contains steps that run model methods. Jobs execute in dependency order, and steps within a single job run in parallel. Steps can chain data, so a downstream step can reference an upstream step’s output through a CEL expression. Workflows can nest, they can pause for a human with a manual_approval step that suspends the run until someone signs off, and they can trigger themselves on a schedule.

Data is the part people underrate. Every model execution, every workflow run, every step produces a versioned, immutable artifact, stored with rich metadata: which model made it, which spec it belongs to, its tags, a version number, a timestamp. And it’s all queryable with CEL. You can ask for every failed step, or everything a given workflow produced, after the fact. Your automation stops being a stream of ephemeral logs and becomes a searchable history.

Vaults hold secrets. Definitions reference secrets by name, and Swamp resolves them at runtime, so credentials never freeze into your YAML and never persist into the data layer. The providers are swappable, from local encryption up to something like a cloud secrets manager.

Extensions let you package reusable model types in TypeScript, version them, and publish them. And skills, in the Claude Code sense, are how an agent learns to operate all of this. They’re markdown documents, not code, and a unified swamp skill acts as a gateway that routes the agent to the right guidance for whatever it’s trying to do.

One more thing worth calling out: steps run locally by default, but a step with a target or labels field gets dispatched to a connected worker instead. The worker dials home, receives the step, runs it, and streams the results back. So the same workflow can fan work out across machines without you rewriting it.

How autopilot uses it

My autopilot is a loop that keeps my Claude Code and Codex subscription windows full around the clock, moving all of my repos forward: it proposes work, opens PRs, reads the feedback on those PRs, and drives them toward green. Swamp is the entire backbone, and the thing I keep appreciating is how little of it there is.

There’s exactly one daemon: swamp serve. On launch it reads the workflow’s cron schedule and fires the workflow on its own every few hours. I don’t have a supervisor process babysitting a queue. The scheduler is just a field on the workflow definition, and serve honors it.

The workflow itself is a handful of jobs with dependency ordering: ideate, implement, converse, a checks pass, a rollup, and a skill-distillation pass, each one depending on the ones it needs to run after. Every job is a typed model method. I wrote a couple of small extension models in TypeScript that shell out to my actual scripts, and because each run captures a typed result and a log file, I get the searchable data layer for free. My analytics dashboard doesn’t scrape stdout, it queries the artifacts Swamp already stored, filtered by tag and status.

Here’s a decision that shows off the design. Autopilot has two human gates: I approve proposed work, and I merge the PRs. Swamp has a manual_approval step that seems tailor-made for exactly that. I don’t use it. A manual_approval step suspends the run until I click approve, and I don’t want a long-lived suspended run sitting around waiting on me for hours. So I put my gates on GitHub labels instead, and let every workflow run complete cleanly whether or not I’ve weighed in. That’s the nice thing about a framework made of small primitives: when one of them isn’t the right fit, you can just not use it, and nothing breaks.

Worth a look

Swamp scratches a specific itch: you want agents to do real, repeatable operational work, and you want the record of what they did to be typed, versioned, and searchable instead of scattered across chat logs and one-off scripts. The source is on GitHub and the manual is thorough if you want to go deeper.

In the next post I’ll put the two pieces together and write up how I use Swamp and the Open Knowledge Format in tandem: building and maintaining a knowledge base across every project as the agents work, and distilling reusable skills out of it that get proposed back into a shared skills repo. That combination is where this has gotten genuinely useful.