My last post ended with agents I can leave working and trust the result, one task at a time. Nothing in that setup picks the next task, notices when an agent stalls, or remembers what I decided a week ago. That was still me.
So I asked a Claude Code session to try running my outer loop, to see whether I could be more hands off. The outer loop it runs today has six parts:
- a worktree and branch per task
- a coordinator that runs every task as a subagent
- a ledger repo that holds the coordinator’s state
- gates on that repo
- a daily workflow review and experiments that judge every change
- one coordinator per area of work
The coordinator only held together once its state lived in a repo instead of a session. The sections below follow the order I built the parts in.
A worktree per task
The oldest part started this summer as wt.sh, a small shell script that gives each task its own git worktree, because two agents in one checkout overwrite each other’s files. The script only helped when something called it. Claude Code makes its own worktrees for subagents, without the project’s setup, so this month the script became agent-worktree. It owns the whole lifecycle, and its plugin sends Claude Code’s own worktrees through it, so every worker gets a checkout on its own branch that comes up ready and goes away clean.
Before a branch lands, a reviewer looks at it as a whole. How a finished branch lands, by fast-forward to main or through a pull request, is up to each project, and the skills follow it.
One coordinator, many workers
When I started, I had about seven idle sessions spread across four repos. Each had stopped somewhere, some waiting on me and some at a usage limit, and none knew the others existed. Relaying work between them failed: a push ordered by another session does not count as my approval, so auto mode refused it.
So the coordinator runs every task as a subagent of itself, with one place to approve and one place where the plan lives. Each worker starts with the routing skill from my skills plugin preloaded, and the reviewer from my last post, Loops I Can Trust, accepts each commit before it is made.
Once that held for a few rounds, I decided the coordinator could always push, as long as the work and its commits had been checked. An agent cannot widen its own permissions, so I left auto mode once and approved the allow rules myself, such as pushing reviewed commits. Auto mode is back on, because the same session also has connectors to production systems.
Taking over the outer loop also split the skill from my last post. What I called coordinate there is now task, the inner loop each worker runs from request to landed work, and coordinate is the outer loop: delegate each task, keep the ledger, batch my questions and check on agents that go quiet.
State in a repo
The coordinator session ran long, around 390,000 tokens. The usual answer is a handoff to a fresh session, but I have to write each one and start the next session, which keeps me in the loop. Work also sat where only one session could reach it, in a cloud container or a chat message.
So the state moved into a ledger in a private repo, agent-ops. It holds:
- my decisions and standing rules
- questions waiting on me, batched so I answer once
- each project’s open obstacles and plans
- the briefs agents work from
The ledger says only what is true now: git keeps the history, and a decision leaves once a repo’s own docs or skills hold it. Claude Code’s auto memory kept notes that went out of date, so I turned it off.
The tasks started out in the ledger too, and a few days later moved into agent-task, which records each task from when it is queued until its work is over, with its repo and its brief. Now agent-task holds every queued, waiting and running task, and the ledger holds what surrounds them.
With the state in a file, the coordinator needs no handoff. I set Claude Code to compact automatically at 300,000 tokens, and hooks then reload the ledger, so the coordinator works from the file rather than from a compacted summary. The same file let me move the coordinator from the cloud to my Mac, where it runs under Remote Control and agent-record, the session record from my last post, keeps every subagent session.
Gates on the ledger
Because the ledger is in git, agent-ops can be gated like code. Every coordinator rereads its ledger after each compaction, so a wrong line there misleads every session that follows. The commit check refuses:
- a line that records landed work, since
git logalready holds it - a ledger past its size limits, since it is read in full every time
- a line citing a commit the remote does not have, which no other session can reach
- a plan that no ledger links
- a malformed experiment line
The rule from my last post holds here too: gate the outcome, never whether a skill was loaded.
A daily workflow review and experiments
Measuring started with cost. In one week this month, the coordinator read about 7.5 million input tokens for each accepted commit, and the biggest share was the output of its own record queries. Since then every step of every loop gets measured.
A routine runs the daily workflow review: each morning it reads the last day of work across every project and proposes the top three workflow fixes. Each hook, gate or rule a coordinator adds opens an experiment with a signal to judge it by, such as how often I had to step in. Once its check date passes, the daily workflow review proposes an outcome, and a change stays only if its signal moved the right way.
That replaced a habit of dry-running every skill change against a few unrelated repos before it landed. When the coordinator queued yet another round, I called it off, because I had better machinery for that by then. Evals, skill usage counts and the experiments now judge a change in real use.
A coordinator per area
A session loads the project skills and rules of the folder it starts in, and every subagent it starts works in that same project. When my first coordinator filed an issue in a product repo of mine, it did so without that project’s rules.
So I now run three coordinators: one for my agent tooling, one for that product and one for another product of mine. Each session points AGENT_LEDGER at its own ledger in agent-ops, and all of them read one shared file of my rules and decisions, linked from the first line of every ledger, so a decision made in one area holds in every other area.
One of those rules says where a change belongs: a tool holds only what applies to most projects, and what is one project’s own stays in that project. When I asked that product’s coordinator for a change to the shared design-review skill, I decided the product’s specifics did not belong in it. The skill got a generic widening, and the product’s own rule stayed in the product.
The coordinators also keep to their own repos and talk to each other. Each applies the daily workflow review’s proposals only to the repos its ledger holds. When a tooling change that a product coordinator waits on lands, the tooling coordinator sends it the commit.
Where it stands
Worktrees keep agents out of each other’s way. The coordinator decides what runs next and who is waiting on me. The ledger holds the state across compaction and machines, the gates keep it accurate, the daily workflow review proposes workflow fixes, and the experiments decide which changes stay.
My part is smaller now. I answer batched questions, decide when a plan should stop, and correct a coordinator when it invents a rule. For the first time, the loop above my loops lives in a file I can read instead of in my head.
Try it
The task and coordinate skills ship in the same Claude Code plugin as the reviewer:
claude plugin marketplace add cniska/agent-skills
claude plugin install cniska-skills@cniska
The two tools, agent-worktree and agent-task, install with Homebrew, and each comes with a Claude Code plugin of its own from the same marketplace:
brew install cniska/tap/agent-worktree cniska/tap/agent-task
claude plugin install cniska-worktree@cniska
claude plugin install cniska-task@cniska
Both also install through npm, Bun or a release script, and their READMEs have the steps.
The ledger needs nothing installed. Set AGENT_LEDGER in a project’s local settings to a file in any repo, and the coordinator keeps its ledger there.