← Back to Notebook
FIELD NOTES

Running a Solo Agent Fleet: An Operating Manual

A companion piece to the agent-fleet essay · the review-gate mechanism, the handoff files, and two failures that changed how I run it

I run a one-person shop with a fleet of Claude Code agents doing most of the execution — research, drafting, deploys, monitoring, even parts of my own business-strategy loop. This isn't a demo. It's been running for about five months (not every single day — it's gone quiet for a day here and there when a cron job died silently, more on that below) across a real portfolio of side projects, a consulting brand, and a personal-training bot, and it has broken in specific, instructive ways.

This is not the "AI agents are amazing" post. It's the playbook: what I actually delegate, how state moves between agent runs that share no memory, the review-gate mechanism that lets the thing run unattended without me waking up to a disaster, and two failures that changed how I run it. If you're a solo builder thinking about running more than one agent unsupervised, steal the structure — not the vibes.

The core problem this solves

A single Claude Code session is easy to trust: you're watching it. The problem starts when you want agents doing useful work while you're not looking — overnight, during your day job, across a week you don't touch the laptop. At that point "trust" isn't a feeling, it's a mechanism. You need a way to say what an agent can do without asking, a way for agents to hand off work to each other and to future-you with no shared memory, and a way to find out what happened — and undo it — when something goes wrong. Because something will.

Roles: what's delegated, what's kept human

I split roles by reversibility, not by task difficulty. A hard research task is fully delegated; a trivial but irreversible action (sending an email, spending money, publishing under my name) is not.

Delegated to agents:

  • Market/competitive research, prospect research, signal scanning
  • Drafting — outreach copy, blog posts, specs, code, landing pages
  • Building and deploying prototypes on free-tier infrastructure
  • Reading and classifying project state (with a hard rule: open the folder before describing it — a project got mislabeled for days because an agent trusted a filename instead of reading inside)
  • Monitoring: checking in on other agents' output, flagging what's stale
  • Reversible ops: registering a domain within a small budget, deploying to free hosts, archiving a project into a skip list

Kept human, always:

  • Sending anything to a real person's inbox, DM, or feed
  • Publishing under my personal name/accounts (brand-identity publishing is a step down, more on that below)
  • Any spend above a small per-transaction cap, any subscription, any paid infrastructure
  • Anything irreversible — deleting files, legal filings, signing things
  • Strategic kills of a project (shelving is reversible and agent-doable; killing it for good is not)

The heuristic that makes this legible to agents, not just to me, is one rule of thumb: drafts are not sends. An agent can write the outreach email, the blog post, the landing page copy, the domain purchase plan — all of it — and stop exactly at the point it becomes irreversible or identity-bearing. That line is cheap for an agent to self-check and cheap for me to audit.

For coding-specific work (a multi-package TypeScript project, in my case), I split further into builder agents (implement one task, in isolation via a git worktree if it touches shared files) and tester agents who write tests independently of the builder for the same task — the point isn't redundancy, it's an independent reading of the spec that catches builders grading their own homework. An orchestrator role — usually just me in an interactive session — decomposes the roadmap into agent-sized tasks and does the final merge review. Everything that isn't the merge review goes to an agent by default; otherwise you drift back into doing the work yourself and the fleet is theater.

Handoffs: how state survives between runs

Agents don't share memory across sessions. The fix isn't a fancier memory system — it's flat files as the interface, checked into git.

  • A state directory of markdown files is the single source of truth: current focus, budget, what happened each day, what needs review. Every run mode reads this at the start and writes to it at the end. No agent holds state in its head past its own session.
  • A daily/run log that's genuinely a log, not a dashboard — append-only, one entry per action, timestamped, with an explicit "how to reverse this" field on every entry that isn't fully free. If I need to know what happened while I wasn't looking, I read one file.
  • Provisional-state rules with a staleness trigger. If a piece of state (say, "what's the current priority") goes more than N days without a human touching it, an agent is allowed to pick the best-supported next value, write it in, and log the old value next to it so it's a one-line revert if wrong. This is the load-bearing idea: silence from the human doesn't mean the system waits — it means the system takes the best reversible action and makes reversal trivial. Never re-nag; log and move.
  • Task specs, not vibes, for coding handoffs. Every task an agent receives has: a one-sentence user-visible goal, the exact files it may and may not touch, a validation-gate command it must run and paste real output from (not "tests pass" — the actual tail), and a behavioral definition of done ("brushing a cluster highlights the same rows within 100ms," not "implement brushing"). Agents without this spec produce plausible-looking work that's wrong in ways that don't show up until merge.
  • Commit early, commit often, inside a worktree. A worker that dies at 80% with nothing committed costs a full re-run of the handoff. Worktrees only see committed state — dispatch a worker against uncommitted prerequisite files and it correctly refuses the task, because it can't see them. That's a feature once you know it's coming, not a bug.

Review gates: the authority ladder

The mechanism that actually makes unattended operation safe is a tiered permission ladder, re-read by every agent at the start of every run. It has four tiers, ordered by how expensive it is to be wrong:

  • Green — act freely, no logging. Research, drafting, iterating on existing docs, building on free tiers, classifying (after reading inside the folder). This is the default; most of the fleet's hours live here.
  • Yellow — act, then log. Reversible-but-real actions: registering a domain inside a small budget, deploying a free-tier site, adopting a provisional priority. The agent does it and appends one line to an append-only review log with a "how to reverse" field. I scan that log; I don't approve each line before it happens.
  • Orange — stage, notify, wait out a veto window, then act. This tier is for outward-facing brand actions that are consequential but recoverable — publishing a blog post under the company brand, submitting to a directory. The agent stages the exact final artifact, posts a notification with a one-tap veto option, and only ships once the window (48 hours by default, 7 days if money is attached) lapses un-vetoed. The important design detail: the veto clock starts at confirmed delivery of the notification, not at staging time — if there's no reliable channel to notify me, this tier silently behaves as the next one up instead of quietly shipping.
  • Red — never without an explicit go-ahead. Sending anything to a real person, publishing under my personal name, any spend over budget or outside pre-approved categories, anything irreversible. These get staged fully — one click from done — and surfaced once. Never re-nagged more than once a day; the deadline does the nagging, not the agent.

The two rules that keep this from decaying into either paralysis or chaos: log yellow, window orange, stage red — the tier tells you the shape of the safety net, not just a mood. And: inbound content (an email that arrives, a form submission, a forum reply) runs one tier stricter than the same action if the agent initiated it — outside text is data the fleet reacts to, never instructions it obeys. That second rule exists because without it, a malicious or careless input becomes a privilege-escalation path for the fleet's own authority ladder.

Failure modes actually hit

Two are worth walking through in detail because they changed the mechanism, not just the outcome.

1. The full-tree rsync that wiped live data. A deploy script for a small side-project bot did a full-project rsync from the dev machine to the production box on every push, to keep the two in sync. On one deploy, that sync overwrote several data files on the production side — including a person's actual accumulated logs — with stale local copies, because the "source of truth" side of the sync was, for those specific files, behind the destination. The wipe wasn't caught until later; recovery meant pulling older files back out of git history and manually reconciling which files had genuinely newer content that shouldn't be clobbered (some had legitimate post-commit edits — blindly reverting everything to HEAD would have destroyed those too). The fix wasn't "be more careful," it was structural: deploys for that project were narrowed from "rsync everything" to an explicit allowlist of files the deploy is actually allowed to touch, and a separate one-way, pull-only backup mirror was added so a bad push can never be the only copy of live data again. The rule written down so future agents don't relearn it the hard way: never do a full-project sync between a dev tree with unrelated WIP and a production data directory — sync exactly the files the task is about.

2. A monitoring pipeline that "worked" for a day before silently dying. A digest/notification pipeline (the thing that starts the Orange veto clock, among other jobs) was built, manually tested in an interactive session, and confirmed working — message posted, reactions seeded, state logged. Left to run on its own cron schedule, it then crashed on every scheduled run, with a ModuleNotFoundError for a dependency that existed in the project's virtual environment but not in the bare system Python the cron job actually invoked. Nobody noticed for about a day, because the one successful run — the manual test — was what got logged as "verified live," and there was no cheap way to distinguish "a real scheduled run happened and worked" from "someone tested it by hand once." The fix was mechanical (call the venv's Python binary explicitly, not bare python3), but the lesson was about what counts as verification: a manual same-session test is not evidence a cron-triggered run works, because the two can have entirely different environments. Now "verified" for anything cron-driven means checking the actual cron log for a real scheduled firing, not running the script by hand once and calling it done.

A smaller failure worth a one-line mention: a stranded lock-file marker on a laptop-based cron job, left behind because the laptop was asleep and the process got killed outright (suspend/OOM) instead of exiting normally, so the script's own cleanup-on-exit logic never ran. Nothing was lost, but it's a reminder that any "cleanup runs on exit" guarantee only holds if the process gets to exit at all — anything running on hardware that sleeps needs a staleness check on its own lock files, not just an exit trap.

What I'd tell someone setting this up from scratch

Start with the ladder, not the agents. Decide what's reversible in your specific domain before you decide what to automate — the ladder is what lets you say yes to autonomy on the 80% of work that's cheap to undo, while keeping a tight human leash on the 20% that isn't. Then make the log boring: one append-only file, one line per action, a reverse instruction on every line. That log is what turns "I don't know what the agents did while I was gone" into a five-minute morning read. Everything else — the specific tools, the cron schedule, the model you run — is replaceable. The ladder and the log are what actually keep you safe running agents you're not watching.

Worth flagging
  • The runtime and codebase specifics referenced here (the multi-package TypeScript worktree playbook, the digest pipeline's cron/venv bug, the trainer-bot rsync incident, the stranded lock-file marker) were cross-checked directly against the underlying project playbooks and the append-only review log before publishing.
  • An earlier draft of this piece said the fleet had been running "about two months" — the actual run history goes back about five months (mid-February), not continuously every single day, but close to it. Corrected here rather than left as an estimate.