In Search of an Easy Way to Arm Your Agent Fleet: YAML, CLI, and In-Repo Allocation<br>← Facundo<br>June 22, 2026<br>In Search of an Easy Way to Arm Your Agent Fleet: YAML, CLI, and In-Repo Allocation
This is the second in a series of documents where I work through the architecture of an agent-orchestration library I'm building. The previous one was about the environment in which the agent runs. This is about how to actually declare and use the library.
I wanted to build something that allowed me for declaring agents easily. The way most libraries achieve this is usually by making it a thread, with a fixed configuration. Then spawning one is trivial because there's almost nothing to configure.
I wanted each agent to be its own independent entity, with its own runtime, workspace, harness, and toolchain. This certainly has a cost: If every agent can differ on every axis, then declaring and operating a fleet would be very tedious, because every agent would have to spell out everything about itself.
Note that each agent still has its own isolated workspace, artifacts, and secrets, for the reasons I went through in the previous post. This one is about how to declare and drive them.
Here is the solution that I came up with
Where It Lives
Everything lives under .agents in the repo root. The config sits there too, in agents.yaml, next to the artifacts, secrets, and workspaces from before.
code]:bg-transparent [&>code]:px-0 [&>code]:py-0 [&>code]:rounded-none">/<br>.agents/<br>.artifacts/<br>agents/<br>common/<br>.secrets/<br>agents/<br>common/<br>.workspaces/<br>agents.yaml
The thing I care about here is that the whole fleet is a directory I can open and read. The config and the state are in the repo, possibly in git.
Declaring Agents
The config has two parts: defaults that every agent inherits, and per-agent entries that override only the axes that differ.
code]:bg-transparent [&>code]:px-0 [&>code]:py-0 [&>code]:rounded-none">defaults:<br>harness: claude<br>workspace:<br>environment: filesystem<br>mode: worktree
agents:<br>atlas:<br>harness: codex<br>runtime: docker<br>toolchain: nodepy<br>workspace:<br>mode: clone<br>agent2:<br>harness: kimi<br>agent3:<br>harness: codex<br>agent4: null<br>agent5: null<br>agent6: null
Each agent inherits everything from defaults and changes only what it needs. atlas runs a different harness, runtime, and workspace. agent2 only swaps its harness. agent4 through agent6 are null, so they take the defaults whole.
Any agent can override any axis by writing down the parts that actually differ.
I chose yaml over JSON because this is a file I hand-edit constantly while running the fleet, so I want it optimized for reading and editing, not for being a serialization format.
Driving Them
To start an agent you would do:
code]:bg-transparent [&>code]:px-0 [&>code]:py-0 [&>code]:rounded-none">agents init # automatically creates the directories for each agent<br>agents provision atlas # creates the workspace<br>agents start atlas # starts the actual environment (like the docker container)
init sets things up, provision builds an agent's environment, start runs it.
Once an environment is started, then you can attach to it by doing:
code]:bg-transparent [&>code]:px-0 [&>code]:py-0 [&>code]:rounded-none">agents attach atlas --via tmux
# to open a single tmux session with one window per agent<br>agents attach atlas,agent2,agent3 --via tmux
Attaching to the environment is one of the ways to communicate with an agent. What this command does is teletransporting the user to the environment. There is another method of communication.
The important part is that each agent can have a different, personalized environment, without this impacting into conveniency: the environment itself knows how to attach / talk to it.
init and doctor Commands
The library provides two commands that make it easy to set everything up, and ensure the tools are set up correctly.
agents init is the bootstrap command. It creates .agents, copies a built-in template into it, and lays down the directory structure that the rest of the library assumes exists.
Secrets have one slightly non-obvious implementation detail: in Windows, the directories are created with mode 755, and most copied credential files are expected to be 644. That looks loose if you only think about a single-user host process, but it is intentional for Docker-based agents. A lot of agentic tools require to run as a non-root user. Mounted secrets need to be readable inside the container. For the Kimi credential file the expected mode is stricter, 600, because that tool expects it.
There is also an optional --copy-credentials flag. When used, init copies known AI-tool credentials from the user's home directory into .agents/.secrets/common, including Claude, Codex, Gemini, GitHub CLI/Copilot, Kimi, and MiniMax config files. This gives all agents a common fallback credential set without forcing each agent to have its own copy.
agents doctor is the corresponding preflight command.
It checks the directory tree first, verifying that the...