Dispatches from the trail · deep dive

How a Fleet of AI Agents Runs Real Projects

Not one agent in a chat window. A team of isolated agents — coordinating over a live message protocol, governed by a versioned repo of policies. Here's the machinery.

Three problems appear the moment you have more than one agent:
1 — keep them from leaking into each other (isolation)
2 — let them talk without a human relay (coordination)
3 — agree on the rules, with an audit trail (governance)
Solve those and one person runs a team.

I ship commercial products solo — the most recent, a regulated SaaS, went from a client's requirements to production in eleven days. People reasonably ask how that's possible without cutting corners. The honest answer isn't "a faster model." It's the substrate underneath: I don't run one agent, I run a fleet of them — and most of the engineering went into how they coordinate.

A single agent, left alone on a week-long build, drifts: it does the easy thing, quietly forgets the goal, and sounds confident about it. The fix isn't a bigger context window — it's structure. So the fleet stands on three pillars: isolation (agents can't bleed into each other), coordination (a live protocol to talk), and governance (one versioned source of rules, with automatic audit). Let me show you each — with the actual protocol, not a diagram of a dream.

The fleet at a glance — isolated cells on two shared planes

PLANE 1 · MESSENGER — live coordination (m; protocol) ephemeral · retention-bounded · event-driven wakes PLANE 2 · agent-common — durable governance policies · standards · protocol pv:v1 · git history = audit PORTFOLIO owner · sole writer TENANT · analog-pro isolated org TENANT · N isolated org agent memory volt sealed own board · own runners agent memory volt sealed own board · own runners agent memory volt sealed own board · own runners commits read · reconcile (write = propose via Plane 1)

Pillar 1 — Isolation through memory

The first mistake is one big shared brain. If every agent reads and writes one memory, one knowledge base, one board, they contaminate each other: a fact from project A surfaces in project B, a half-finished thought leaks across a boundary that should never have been crossed. Worse, if one of them is doing a client's confidential work, that client's data is now one prompt away from everyone else.

So each project is a genuinely isolated cell — its own organization, with its own task board, its own runners, and, critically, its own memory volt: a separate vector/graph knowledge store the other cells cannot read. A tenant agent working on a commercial build sees its project and nothing else; a cross-boundary read simply returns not-found. Isolation verified, not promised.

Separate memory isn't a nicety. It's what lets one operator run a client's confidential project next to their own platform without the two ever touching.

Pillar 2 — Coordination through a live protocol

Isolated cells still have to talk — "I'm about to restart the shared build box," "here's how auth is supposed to work," "the fix is deployed, re-run and report." That's the messenger: a live, cheap, ephemeral plane. But the messages aren't freeform chat. Each one is a structured UFN record — a  m; line — with a stable routing core the server understands and a rich semantic vocabulary the agents interpret.

The envelope

The three fields that make it a protocol rather than a group chat are three orthogonal axes — and conflating them is the classic mistake:

fieldquestion it answersvalues
rxwhen to act (time-urgency)now (interrupt) · soon · bg
rqwhat is owed back0 · ak (confirm) · rp (answer) · rpt (report after acting)
prhow important1..4 (1 = critical)
tymessage typeq · rq · rp · rpt · hs (handoff) · dc (decision) · bl (blocker) · st

A message can be pr:1 (critical) yet rx:bg (act whenever), or rx:now (interrupt me) yet rq:0 (nothing owed back). A rq:rpt opens a trackable obligation: it stays outstanding until a matching report answers it — the router literally surfaces "reports I owe / am owed." Here's a real exchange between my platform agent and an isolated tenant agent, coordinating a rollout:

# tenant asks; wants an answer (rq:rp)
m;fr:analog-pro;to:portfolio;ty:rq;rq:rp;sc:checkout-auth;tx:how is checkout-auth meant to work for the remote runner?
# portfolio answers, references the task
m;fr:portfolio;to:analog-pro;ty:rp;re:9c1d;rf:t=KX-382;tx:keyless FetchRepo over PSK, no key on the box
# portfolio ships it — INTERRUPT now, report back within 2h (rx:now rq:rpt)
m;fr:portfolio;to:analog-pro;ty:st;rx:now;rq:rpt;pr:1;dl:2h;rf:t=KX-382;tx:keyless checkout rolled out — update runner and report
# tenant closes the obligation with a report
m;fr:analog-pro;to:portfolio;ty:rpt;re:c7f2;rf:r=ap-c-app;tx:runner updated, checkout green

Nobody polls

The expensive way to do this is to have each agent poll for messages — burning tokens on a loop that mostly finds nothing, and still adding latency to anything urgent. Instead the driver is event-driven: a thin, non-model listener holds a streaming subscription open at essentially zero cost and wakes the agent model only when something is actually addressed to it. rx:now jumps the queue as an interrupt. An idle agent costs nothing; an urgent message reaches it immediately. And because the channel is a retention-bounded ring — a window, not an archive — anything that needs to be remembered doesn't live here. It lives on Plane 2.

Pillar 3 — Governance through a versioned repo

The durable plane is a single git repository — agent-common — that holds the shared truth: the coordination protocol, the coding and security standards, the build templates, and a registry of who owns what. Its git history is the audit log, for free.

The rule that makes a fleet safe is one line: agents never push it. The write path is the messenger. An agent proposes a change as a message; the owning (portfolio) agent validates it and commits it, with a trailer recording who proposed it. That gives you two-layer audit by construction — the signed message says who asked, the commit says what was applied:

Interaction — the propose → commit → reconcile loop (Model A)

agent messenger portfolio agent-common 1 · PROPOSE m;ty:rq · desired change 2 · wake (to:portfolio) 3 · VALIDATE (gate) 4 · cp-apply: commit + push trailer: ref · proposed-by 5 · m;ty:rpt · rf:c=<sha> 6 · wake (reply) 7 · RECONCILE Two-layer audit — message = WHO asked · commit = WHAT applied

Then every agent reconciles — GitOps for a fleet. Each one periodically compares its local actual state against the repo's declared state and corrects the drift. The repo is the desired state; the agent is the reconciler. And because the protocol vocabulary itself lives in that repo, versioned by a pv: tag, the message language can evolve by pushing a file — no platform redeploy, agents just load the new version at session start:

# agent-common/manifest.ufn — the registry, single-writer = portfolio
acm;pv:v1;board:…;model:A;writer:portfolio;read:all;/
ag;id:portfolio;org:kovanex;role:owner-writer;/
ag;id:analog-pro;org:analog-pro;role:tenant;ch:project:ba61ea…;/
rp;id:…;name:agent-common;kind:control-plane;pv:v1;/

# the commit trailer that closes the audit loop
ref: <msg_id>  proposed-by: analog-pro

Many agents on one project

Coordination isn't only across projects — the sharpest version happens within one. On a single codebase, more than one agent works the task, under a hard separation of duties:

  • The implementer writes the code and its tests, and opens the pull request.
  • The reviewer is a separate agent, forked with its own fresh context. It never shares the implementer's assumptions — so it can't inherit the same blind spots or the same rationalizations. It reads the diff adversarially.
  • The merge gate fails if the closer is the implementer. Separation isn't a policy memo you hope people follow — it's enforced by construction.

An agent reviewing its own code inherits its own blind spots. A second, independent agent re-derives the problem — and catches what the author talked itself past.

What review actually catches

This isn't ceremony. On the last commercial build, the reviewer pass is where real defects died before they shipped. Two examples from the pre-launch security round, lightly paraphrased from the actual review:

review · billing/webhook — reviewer agent

✗ BLOCKER · security: the access grant is issued straight from the webhook request body. A caller can forge the payment id and amount and grant themselves access. The grant must come from the payment re-fetched from the provider, not from what the caller sent.

✗ security: region startup logs the database DSN with the password in cleartext — redact credentials before logging.

✓ after fix: Grant now re-reads the payment from the provider and verifies status + amount; DSN password redacted. Approved, merged.

Neither was a subtle bug — both were invisible to the author at the moment of writing, and obvious to a reviewer whose only job was to attack the diff. That's the whole point of a second independent agent.

Tests are the tripwire, not decoration

Every change is verified against a live PostgreSQL — not mocks — before it can merge. On that build: 451 tests across 123 files, roughly 0.62 lines of test per line of production code. And the tests earn their keep. One catch, from a data pipeline that has to be exactly right because a wrong answer is a fire hazard:

test · catalog · canon-vs-extractor cross-check

✗ FAIL: the extractor read a product's series digit as its pole count — producing 6- and 8-pole breakers that don't physically exist. 90 discrepancies flagged: canon disagreed with the extractor.

✓ resolved: extractor rule corrected; the cross-check test now guards the invariant so the same class of error can't come back.

Multiply that by 44 bugs caught in development and a test suite that runs on every pull request, and you get the thing vibe-coding can't give you: speed and a result you can defend. For genuinely wide work several agents fan out on independent slices and a final pass asks what's missing — but never, ever, does an agent mark its own homework.

What it solved in practice

This isn't a whiteboard architecture — it's the working setup behind real shipping. A few concrete payoffs:

  • A confidential client build ran beside my own platform, cleanly. The commercial SaaS was a fully isolated tenant — own board, own memory, own runners — coordinated with the platform only through the messenger. No shared credentials, no shared mailbox, no data bleed.
  • The second worker caught what the first couldn't. The isolated tenant, on a properly hardened build box with no credential, hit a continuous-integration failure the platform's own builds never showed — because the platform box happened to sit next to a credential that masked the bug. One report over the messenger, root-caused and fixed on the platform side, verified against live state. A blind spot only a second, isolated worker could expose.
  • Rollouts became a protocol, not a nag. "Keyless checkout is live — update your runner and report by a deadline" is a single rx:now; rq:rpt; dl:2h message that stays an open obligation until the tenant reports green. No polling, no chasing.
  • Nobody cut a running job. Before touching shared infrastructure, an agent posts intent and waits for the other's safe point — mutual exclusion by message, so one agent's maintenance never rips up another's in-flight work.

The eleven-day build wasn't one heroic agent. It was a governed fleet — isolated, coordinated, and audited — doing ordinary work without stepping on itself.

The takeaway

“AI agents build software” demos stop at one agent, one repo, one happy path. The real leverage — and the real engineering — starts at more than one: give them hard isolation so they can't contaminate each other, a cheap live protocol so they can coordinate without a human in the loop, and one versioned, audited source of rules so they stay honest. That substrate is what turns “a solo developer with AI” into something that behaves like a small, disciplined team — and it's exactly why a one-person shop can take on work that used to need one.

isolation · coordination · governance — one operator, a whole fleet.

Want this running on your project?

This is the working setup behind my client builds — a fleet of AI agents doing the dev and infrastructure work under an architecture that stays isolated, coordinated, and auditable. If you want an AI-CTO who runs it like that on your product — requirements to production, then support — that's the work I take on.

See how an engagement works →  ·  Read the 11-day build →