minifleet

A small software factory you can run yourself.

Here's the idea. I wanted a handful of cheap AI agents to work on my codebase around the clock, including while I slept, without me babysitting them. That turned out to be two separate problems. Getting agents to do work is easy. Keeping a dozen of them from quietly wasting the night, stepping on each other, or landing something broken is the hard part, and it's mostly a plumbing problem rather than an AI problem.

minifleet is my answer to the plumbing. It isn't a program you install. It's a written description of how the plumbing should be shaped, detailed enough that your own coding agent can read it and build a version that fits your repo and your machines. Mine runs on a laptop and a spare computer. Yours might look different, and that's fine, as long as a few shared parts keep the same shape.

                                        ________
                                       /       /|   tick, every 30 min
                                      /_______/ |   read the numbers
                                      | watch | |   fix one root cause
                                      | o o o | |   write three lines
                                      |_______|/

   ________         ________                        ________    ________    ________
  /       /|       /       /|                      /       /|  /       /|  /       /|
 /_______/ |      /_______/ |                     /_______/ | /_______/ | /_______/ |
 | inbox | | -->  | board | |  claim --------->  |  lane | | |  lane | | |  lane | |
 | tasks | |      | sqlite| |                     | flash | | | gemini| | | claude| |
 |_______|/       |_______|/   <-- finish, reap   |_______|/  |_______|/  |_______|/
                  one writer                          |           |           |
                                                      v           v           v
    ==================================================================================
     [##]--[##]--[##]--[##]--[##]  >>  train: rebase . regen . guards . land
    ==================================================================================
                                                                      |
                                                    failed? --> back to author
                                                                      |
                                                                      v
                                                    next  ===>  main  (hourly gate)

How the pieces fit

Picture a small workshop. Work comes in through an inbox: a folder of task files, each saying what to do, which files it may touch, and how to check that it worked. A board keeps track of every task, who has it, and what happened to it. Workers, called lanes, pick tasks off the board, each in its own copy of the repo, so they never trip over each other's half-finished changes.

When a lane finishes, it doesn't push to your main branch. It hands the work to a train, which is the only way code lands. The train rebases the change, rebuilds anything generated, runs a few quick checks, and lands it on a staging branch. Once an hour a slower set of tests runs, and if everything passes, the staging branch is promoted to main. If a change fails on the train, it goes back to the lane that made it, along with the reason, so it gets fixed by whoever has the context.

Finally there's a watch loop. Every half hour a capable model reads the numbers (how many tasks finished, how many landed, what's waiting, what's stuck), fixes one real cause of trouble, and writes a few lines about what it saw. If it hits a question only a person can answer, it adds it to a short list for me.

Why one task board, with one program allowed to write to it

This sounds fussy until you've lived through the alternative. Early on, a tiny bug let a few empty rows into the task list, and that made every later write fail silently. Nothing complained. The watchdog saw tasks that looked frozen and killed 169 of them in eight minutes. A dozen agents were reading and writing one file, and when the file went bad, each of them made it worse.

So now exactly one small program can write to the board, and the database itself refuses writes from anyone else. Anything that wants to change a task goes through that program, and when a write fails, you hear about it. That one rule removed a whole family of problems.

Why a train instead of a pull request per agent

Most agent tools open a pull request for every piece of work and leave the merging to you. With a few agents that works. With a dozen running all night, you wake up to thirty pull requests that conflict with each other, each tested against a main branch that has since moved on.

The train lands one change at a time (or a small batch that doesn't overlap), each rebased onto the latest code and checked right before it lands. The per-landing checks take about a minute on purpose, because the heavy tests run hourly on the whole staging branch. When something fails, the train says why, and the task goes back to its author instead of sitting in a pile.

Starting with cheap models

Most tasks don't need the smartest model. A lane starts with the cheapest model that might do the job. If that model stalls on a task twice, the task moves up to the next model. If a provider runs out of quota, the fleet treats that as a plumbing hiccup rather than the task's fault, and pauses that lane for a while. Over a night this keeps costs low without me picking a model for every task.

Noticing when things get stuck

This one surprised me. The usual health checks ask whether each process is alive. Every process in my fleet was alive, and yet for days the train sat idle about 80% of the time, because of a five-minute wait hidden inside each pass.

So the alarms now watch the work itself: tasks waiting while nothing gets started, a train with work queued and no pass in ten minutes, a change marked as shipped with no result after twenty, or the same check failing on several branches at once, which usually means the environment broke rather than the branches. Each alarm has a clock, and each one goes off without me having to look.

What I learned the hard way

Every rule in the skill comes from something that actually went wrong. A few examples:

There are 26 of these so far, each with the fix that now prevents it. Here's the full list. I think it's the most useful part of the project.

How it compares to other tools

There are good tools for running several coding agents at once. Gas Town, Agent Orchestrator and Bernstein are the closest to minifleet, and I borrowed ideas from each. They're strongest at coordinating agents and giving you a dashboard to watch them. minifleet puts its effort elsewhere: getting work landed safely, using cheap models, and noticing when things stall.

That means minifleet is probably not for you if you want a visual dashboard, would rather someone else host and run it, want agents to respond to pull-request reviews, or work across many repos at once. Those tools do those things well, and the comparison says which one fits which need.

How I judge whether it's working

I try to judge the fleet by what it actually did over the past day, since a design can look great on paper while the real thing sits idle. A fleet is doing well when work still lands with the internet off. When I can kill any process and nothing is lost. When a small test task goes from picked up to landed in under five minutes. When one command shows me the whole history of any task. When every item on the "what went wrong" list has a fix that runs on its own. And when I find out something is stuck from an alarm rather than from a quiet morning.

Trying it

Open a coding agent inside your repo and give it this line:

Read minifleet.dev/skill and build me a minifleet for this repo.

It will ask you about five things (your repo, your machines, which models you want to pay for, what "landed" means to you, and when you're usually away), then build the pieces in order, checking each one before starting the next. The first thing it should show you is a test task going all the way through.