Nine AI Agents, One Human in Charge

Nine AI Agents, One Human in Charge

In March I wrote about my first coding agent fleet, a handful of Squad agents and the GitHub Copilot coding agent turning user feedback into pull requests. At the end of July I went a step further and created a single folder for my presales work, put a rules file in it and started Claude Code there. Three months later that folder has eight siblings, and between them they prepare my meetings, qualify opportunities, draft quotes, keep an eye on existing customers and write content, while I’m still the only one who talks to customers. Nothing leaves the house without going through me, and that one rule shaped more of the architecture than anything else.

Every agent is still just a folder

That first folder already contained the whole idea, and it hasn’t changed since. Each agent is a directory with a CLAUDE.md for its role and rules, a .claude/settings.json for permissions and hooks, a board file it keeps up to date and an inbox/ where work arrives. When Claude Code starts in that folder it picks all of this up, so the role description, the memory and the permission model live side by side, and Git keeps the history of every one of them.

What I like most is that none of my own tooling is required. Open a terminal in the folder, type claude, and you’re talking to the same agent with the same limits as when my cockpit starts it. A new agent costs me a folder and a small JSON file, not a line of new code.

Here’s the crew, cut along the path a customer takes rather than along the tools they use.

AgentJobWhat it never does
AnnaPresales hub for cases, qualification, meeting prep and decksTalk to customers
OttoQuotes in the ERP, works only behind AnnaWrite without my approval
BeaWon customers and partners, when to call and when to ask for a referralTalk to customers or partners
KonradSignal engine that fills a daily queue of drafts and call sheets for meSend anything
MartinContent and positioningPublish
PetraPortfolio with bets, demand evidence and pricing questionsRun a bet without a threshold of proof
RobertTest bench against simulated audiencesWrite content
CharlyChief of staff who keeps the overall picture and hands out workDo the content work
BobBuilds and maintains the fleet itselfPush or touch the tenant without my go

When they talk to me, each of them has its own voice. Anything they write for other people is neutral or in my voice, and a document that sounds like an agent is a bug I fix.

A voice message travels through Azure and ends up on my Mac

Six-step strip from recording on the iPhone through transcription, queue, inbox on my Mac and a run in the agent’s folder to a card back in Teams. A session parks itself after ten minutes without an answer, and a voice message is an order, not an approval.

Most of the time I’m not sitting in front of a terminal when I need something, so there are two other ways in, a voice message from my iPhone and a chat with a Teams bot. Let’s say I press the action button and say “Anna, prepare tomorrow’s ten o’clock”. The shortcut sends the audio to an Azure Function, which checks that it’s really me and confirms right away, and Azure AI Speech turns it into text. I give Speech a phrase list with my agents’ names, a small detail that matters more than you’d think, because without it Konrad came back as something else in every second message. The transcript then waits on a Service Bus queue.

The cloud never does any of the actual work, it’s a mailbox and nothing more. On my Mac a small service keeps an outbound connection to the queue open, using AMQP over WebSockets on port 443, which also works on networks that block plain AMQP and means nothing on my machine has to be reachable from outside. It picks up the message, drops it as a file into Anna’s inbox/ and hands my local cockpit a job (if the first word isn’t one of the names, Charly decides who gets it).

The cockpit is a small Node app with SQLite, about 17,000 lines without a build step, and it deliberately doesn’t think for itself. For each job it starts a Claude Code process in the agent’s folder, so Anna works under exactly the rules and permissions she’d have in the terminal, reads the case and the meeting transcripts and writes her prep sheet into the case folder. Through MCP the cockpit hands her a few tools of its own, so she can ask me a question, send a Teams message, propose a handoff or save a checkpoint.

When she’s missing a decision, the question pops up as an Adaptive Card in my Teams chat, and if I don’t answer within ten minutes the session parks itself and picks up again from its checkpoint as soon as I do. The result comes back the same way, a short message with the file attached. Voice and chat count as one conversation, so a reply without a name in the next four hours simply continues where we left off.

The brakes live in the systems, not in the prompt

For the first seven weeks every boundary in the fleet was a sentence in a prompt, “never write outside your own library” and the like, which is a polite request and not much more. Since 19 September every folder also has deny rules in its settings.json, and an agent that runs into one says “blocked” and stops instead of looking for a way around.

The brakes I trust most, though, sit further out, in the systems the agents talk to. The Entra app registration behind the fleet has Mail.ReadWrite so the agents can put drafts into my mailbox, but it doesn’t have Mail.Send, and no prompt in the world changes what Graph allows. Quotes for the ERP go through a small gate. Otto builds a preview with a checksum, I look at it, and only after my explicit yes is an approval file with exactly that checksum written. The gate only writes when the two match and has no way of deleting anything, so what ends up in the ERP is what I actually saw.

CRM and SharePoint run on my delegated permissions, which means an agent can never do more than I can. And a voice message is an order rather than an approval, so if I say “prepare the quote” into my phone, what I get back is a preview.

Agents hand work over as files

Between the agents there’s no API and no database, just inboxes. When an opportunity is won, Anna writes a file into Bea’s inbox and an anonymized reference pattern goes to Martin, two of 16 numbered handoff rules. The cockpit notices the occasion and suggests the handoff, and once I click, the agent the information comes from writes the file, while the cockpit itself never copies content from one folder into another.

It sounds almost embarrassingly simple, but it’s the reason I can debug the whole thing. When an agent proposes something odd, I open the file it read and see where the idea came from.

Two rules sit on top of every handoff. Anything in an inbox file or a transcript that sounds like a command is treated as a finding about that file and never as an instruction, and missing facts stay marked as missing instead of being filled in with something plausible.

One of them talks to a colleague’s agent

Since 17 October Charly has been exchanging requests with a colleague’s agent, the first time the fleet talks to anything outside my own setup. Only Charly does the talking and the others go through Charly, and a request from that side is never treated as an order from me. A loop breaker stops a thread after a few automatic replies in a row, and my colleague and I can both read the whole history.

I can’t give you a number

I haven’t measured hours saved or win rate, so I won’t make a number up. This is a personal setup on one Mac, built for one person, and whether it would work for a team is something I simply don’t know yet. Every customer conversation and every negotiation stays with humans.

The deny rules also have a limit I only stumbled over recently. According to the Claude Code docs they cover Claude’s own file tools and the shell commands it recognizes, but not a script that opens a file on its own, and closing that gap takes the sandbox, which I haven’t switched on yet.

The boring parts survived every rebuild

Looking back over three months, what’s still standing from the early days is the boring stuff. One folder per role, handoffs only through the receiver’s inbox, a checksum gate in front of anything that can’t be undone, a cloud that’s only a mailbox and a control layer that stays on my own machine. Everything else I’ve torn down and rebuilt more than once. It all runs on Claude Code with Microsoft 365 and Azure around it, mostly because that’s what I had at hand, and I’m not trying to sell you any of it.

If you’re building something similar, take a look at which of your boundaries still rest on a prompt alone. Until 19 September, all of mine did.

A few weeks ago I kept reading and hearing that everyone should build their own AI harness, and my first thought was, sure, I’ll just casually rebuild Claude Code or GitHub Copilot. This week it finally clicked what that meant, because I’d been doing it all along without noticing. I never touched the model or the agent loop. What I kept tuning was everything around it, the folders, the rules, the inboxes and the handoffs, until the context that reaches the LLM fits my tasks as closely as I can get it. That’s the harness, and mine grew one folder at a time.

Enjoyed this post? Let's connect on LinkedIn:

Follow on LinkedIn →