← Blog

Orchestrating a One-Person Software Factory

I've used Claude Code every day since it launched last year, and Codex every day since it came out. They've changed how I build software. But for most of that time, the bottleneck wasn't the agents. It was me.

On a normal day I'd have several threads going at once: one fixing a bug, one building a feature, one on the website, one helping with marketing. Each needed my attention, and each lost context over time. I was also the only connection between them. I'd read a bug report in my customer support thread, then copy and paste it into a new coding thread. I'd try to remember which agent was touching which part of the code, so two of them wouldn't end up doing overlapping work, because they had no way to see each other. It was very clunky. I think that's still the main bottleneck for most developers working with AI agents, and plenty of people are running into it:

AI was supposed to make us work less … most days I have up to 10 agents running at the same time … and I jump from conversation to conversation all day … compared to 5 years ago, I probably context switch 100x more … by the end of the day my brain is fried.

— Tibo (@tibo_maker)

Agents That Talk to Each Other

This summer, the Codex app gained the ability for one thread to start new threads and send messages to other threads. It didn't really get much notice at the time, but to me this seemed like a huge paradigm shift. I started thinking about how this could change the way we all work with agents, and automate away much of the manual work I was doing.

What if one agent acted as an orchestrator? It could create the agents it needed to get the work done, delegate to them, and be my main point of contact.

I started playing with this at the end of August. Soon I had orchestrators for Backdrop and another project, then for Sensei, marketing and customer support. Support mostly ran as a single thread. I wrote the workflow down as a skill that each project adopted, and its core was pretty simple:

  • One orchestrator per project, and it doesn't build. It creates a visible thread for each piece of work and coordinates them.
  • Every thread's title says what it is. A purpose emoji in front, like ✨ for a feature, 🐛 for a bug or 🔍 for research, so I could scan the sidebar.
  • Every thread's title also says if it needs me. 🟢 means a PR is ready for my decision, 🟡 means it needs input from me, and 🔴 means it's stuck. I've since dropped these, because the Claude app already shows each thread's state.
  • The orchestrator is my one point of contact. Threads report follow-up work and questions to the orchestrator, and it brings them back to me in its own thread, so I don't have to check a dozen threads. To keep track of it all, the orchestrator keeps a pinned "Current priorities" issue on GitHub.

All in all, I worked this way in Codex for about a month, and it worked fairly well. It made it much easier to keep separate tracks, like customer support, marketing and coding. But I still found myself going into the individual threads manually a lot, because the orchestration wasn't quite there.

Moving to Claude

When Opus 5.5 came out, I tried moving the workflow over to Claude Code. Within about a week, every Backdrop pull request was coming from a Claude Code branch.

Opus 5.5 turned out to be extremely competent at working like this. The setup was the same; the model made the difference. It delegates, follows up with the agents doing the work, keeps the priorities straight, and comes back to me with what actually needs me. It just works. I suspect that's not a coincidence: the week before Opus 5.5, Anthropic relaunched Projects in Claude Code, where a project thread coordinates a set of parallel agent threads. That runs in the cloud, though, and my agents need my Mac to build and run the apps. So I run the same pattern locally, with sessions in the Claude desktop app messaging each other.

Backdrop is the clearest example, because I'd been working on it with AI agents all year. From January to early September, that added up to only 363 commits on main, since I'd often work on something for a day or more before committing.

Backdrop commits per week in 2026
Commits on main, Jan 5 – Oct 11, 2026
One thread at a time Orchestrator in Codex, from Sep 9 Orchestrator in Claude, from Sep 30
Show data
Week ofCommits
Jan 5, 20260
Jan 12, 20260
Jan 19, 20260
Jan 26, 20261
Feb 2, 202610
Feb 9, 202610
Feb 16, 20260
Feb 23, 20260
Mar 2, 20260
Mar 9, 20263
Mar 16, 2026144
Mar 23, 202621
Mar 30, 202610
Apr 6, 202611
Apr 13, 202619
Apr 20, 202625
Apr 27, 20266
May 4, 20264
May 11, 202616
May 18, 202618
May 25, 202610
Jun 1, 202611
Jun 8, 20267
Jun 15, 20260
Jun 22, 20260
Jun 29, 20260
Jul 6, 20263
Jul 13, 20260
Jul 20, 20260
Jul 27, 20260
Aug 3, 20263
Aug 10, 20264
Aug 17, 20269
Aug 24, 20267
Aug 31, 202610
Sep 7, 202665
Sep 14, 202692
Sep 21, 202682
Sep 28, 2026225
Oct 5, 20261,516

With the orchestrators in Codex, things picked up. After the move to Claude Code, they took off. In the two weeks from the end of September to mid-October, Cindori's repos (Backdrop, Sensei, the backend, the website and the admin tool) got 5,001 commits. Backdrop alone got 2,028, more than in the five years before all this.

Backdrop commits since 2021
Running total of commits on main, Jun 2021 – Oct 13, 2026
One thread at a time Orchestrator in Codex, from Sep 9 Orchestrator in Claude, from Sep 30

Pull requests tell the same story. Backdrop alone merged 478 in those two weeks, and Sensei merged 662 in five days. I'm the only person at Cindori.

Compared to before, this new workflow feels like running a small software factory.

How It Works

Today it looks like this:

How the work flows
One orchestrator per lane, owners per outcome, and GitHub as the shared record
Metaste, direction, money🧭 Cindorichases, daily digestquestionsdecisions🧭 Lane orchestratorsBackdrop · Sensei · Support · …Company boardNeeds Oskar listreadsdelegates · reports🐛 Ownerone outcome✨ Ownerone outcome🎨 Ownerone outcomeRoutineson a schedulee.g. marketing · analyticscrashes · submissionssummariesupdatescommitsGitHubIssuethe mandateBranchown worktreePull requestmainmergesafter reviewand clearance🔍 Reviewerfresh agentreviews

Lanes. Work is split into lanes: an area or product with its own priorities. Backdrop and Sensei each have one, and so do marketing and customer support. A lane isn't the same as a repo. The Platform lane covers the backend, the admin tool, the web store and hosting, which live in several repos, because they share the same priorities and the same deploy rules.

Orchestrators, one per lane. The orchestrator is the agent I talk to most: I dump ideas there and answer its questions in one place. It hands the work to owners, keeps track of them and brings me what needs a decision. Above the lanes sits one more, 🧭 Cindori, an orchestrator of orchestrators. It does no lane work at all. It routes new work to the right lane, keeps the company-wide list of what's open, chases anything that has stalled, and sends me one morning digest of what needs me.

Owners, one per outcome. An outcome is "a result worth independently prioritizing and accepting", like a bug or new feature that matters to users, a new marketing goal, or another distinct chunk of work, such as research or prototyping something. It isn't a file or a ticket. Each owner is a visible session with a title like 🐛 Fix Library sync, working in its own git worktree and branch, so several owners can work in the same repo at once without stepping on each other.

Routines handle the recurring work that just needs to happen, using Claude's scheduled tasks. That might be marketing, going through analytics and crash reports, reviewing new wallpaper submissions or something else. They're fully autonomous: I never have to go into those threads. Every run ends by posting a short summary to its orchestrator, so I read one thread instead of ten.

Put together, it runs itself. I can shovel in ideas, tech debt, bug reports, whatever comes up, and the orchestrators sort it into the right lanes, hand it to the right owner (or ask me to start one), and get it built and tested on their own. I don't need /loop or /goal to keep it going: every finished task, question or review result is a message that wakes an orchestrator up again, so the whole machine keeps rolling until everything is either done or blocked on me. An hourly check is just the safety net for anything that slips through.

GitHub Is How the Agents Coordinate

Before September, I barely used pull requests or issues. I was working alone, so I figured there was no point. Who would read them? My coding agent worked for me, and it could do a review at the end. From January to August this year, I opened three pull requests on Backdrop, and the repo had 27 issues in its entire history. Most of the planned work existed only in my head.

It turns out that orchestration doesn't work without them. The orchestrator could read every agent's conversation, but that's slow, costly, and out of date the moment it's done. It needed an external source of truth that many agents can update in parallel. A reviewer needs an actual diff to review. And several agents working in the same repo need to stay out of each other's way. So today:

  • Every agent works in its own git worktree and branch, so several can work on the same app at once.
  • Every piece of work has a GitHub issue with the mandate, the owner, the PRs and the next action.
  • Every change goes through a pull request, which is where the review, the evidence and the merge decision live.
  • One company board ties it together. Bigger goals are parent issues, and the pieces are sub-issues in whichever repos the work happens in. Each item has a lane and a status: Now, Next, Blocked, Needs Oskar or Done. "Needs Oskar" is the only list of decisions waiting on me.

I don't sit and read these pull requests, though. When one needs me, it reaches me as a short summary and a single question. Here's the one that changed Backdrop's merge rule:

🧭 Backdroporchestrator thread

PR #463, 📝 Merge clearance is ready for your decision.

What changes: owners no longer ask you to approve every PR. They merge into main after merge clearance from the orchestrator. Clearance checks that the PR stays inside an approved outcome, that review and checks are done, and that it doesn't conflict with other owners' work.

You still decide:
  1. Direction changes: new features you haven't approved, removing features, or reversing your decisions.
  2. Protected things: release, signing, backend, secrets, spend, user-data deletion, privacy and licensing.
  3. Rule changes, like this PR.
  4. Disagreements the owner, reviewer and orchestrator can't settle.

Review: an independent agent reviewed the first version and found 2 blockers, 7 should-fix items and 3 nits. All are addressed in the second commit.

This PR changes the rules, so it needs your yes. Merge it?
●Yes, approve and merge
○No, keep it unmerged
○Something else…

Merged at fc686ba0, and logged your approval on the pull request.

How a pull request that needs me reaches me: a summary and one question in the Claude app. The same summary sits at the top of the pull request on GitHub, but I don't need to open it. A real example from Backdrop, trimmed for length.

The Rules That Made It Work

I didn't sit down and design this system up front. I just told Claude what hurt, like being the message bus or getting asked about things I didn't need to decide, and we worked the rules out over time. Most of them came from something going wrong.

I asked my Backdrop orchestrator to describe its job. It put it better than I would have:

Keep many parallel agents moving toward what you actually want, without you having to manage each one. I turn your decisions into owned work, keep the work from colliding, and bring back only the decisions that are truly yours. In short, I'm a router and a gatekeeper, not a builder.

The rules below are what make that work. They live in the repos themselves, in AGENTS.md files and a few shared docs that the agents read.

1. The Orchestrator Doesn't Build

If the orchestrator writes code, it becomes a hidden extra builder that nobody reviews or owns. It can read code and look into a problem, but all real work goes to a visible owner with a clear outcome and a name I can find in the sidebar.

This is the hardest rule to keep. The orchestrator has the most context, so it's always tempted to just fix the thing itself.

2. One Owner, One Mandate

Every piece of work has exactly one owner, from building and testing through the PR, the merge and any follow-up. When I approve something, that approval is the mandate: it covers whatever engineering it takes, from investigation and architecture to tests and fixing what breaks afterwards. The owner doesn't come back to ask permission for each step.

Owners also stick around after their work ships. If a bug comes back, or we later want to change a feature or something that touches it, the orchestrator usually goes back to the owner that built it instead of starting a fresh agent.

I asked my Backdrop orchestrator how it decides:

I reuse the owner whose existing context the new work depends on most, so the outcome stays in one place. I start a fresh one when the work is clearly separate: it would be accepted or prioritised on its own, it touches different code or skills, or it would make the current owner's scope hard to describe in one sentence. "Who's idle right now" is never my reason.

An owner that just built something holds hard-won knowledge that isn't in any document yet: which test flags are safe, which shared machine state it must restore, which edge cases bit it.

It can go wrong. I've carried old instructions forward as if they were permanent: a one-off "stop by midnight tonight" ended up in my briefs for days. A long-running owner may be on an older model than the task deserves, so for substantial new work I start a fresh one with the right settings. And when an owner's queue starts mixing unrelated outcomes, I split them.

3. Own It to Done

Orchestrators had a habit of handing work to an owner and then quietly forgetting about it. So now every open item is in exactly one of three states: someone is working on it right now, it's waiting on a decision from me, or it's done, checked against the PR, the deploy or the running app. "Waiting" and "handed off" don't count.

🧭 Cindori checks this every hour during the day. Anything that has stalled gets one nudge to the orchestrator that owns it. If it's still stuck an hour later, I'm told which orchestrator dropped it. A small watchdog outside the app tells me if that hourly check itself stops running.

4. Review Is Built In

Every substantive PR gets a review from at least one agent that didn't write it. The reviewer gets the actual diff, the requirements and the evidence, and room to challenge the claim that it's done. A green CI run or the builder's own summary doesn't count as review. Findings get fixed, or rejected with evidence. It's the same job a service like CodeRabbit does, just as an internal step with no extra tool. Some changes are also tested on VMs running older macOS versions before they merge. A VM owner keeps those machines ready, and each feature's owner runs its own checks there.

The same idea applies to recommendations. Before one reaches me, a fresh agent or Codex gets the data but not the conclusion, and tries to reach its own. Any disagreement gets reconciled before I see it. No more manually asking for adversarial reviews.

5. One Gate for Shared Things

Anything shared goes through the orchestrator: merging to main, deploys, the test machine, the VMs. Before a merge, it checks that the PR stays inside what I approved, that it merges cleanly and that nothing collides with another owner's work. Then it clears one exact commit, in a message to the owner that's also recorded on the PR, and the owner merges that commit and nothing else.

Clearance isn't a second review. The independent reviewer has already checked the code, so the orchestrator only checks scope, conflicts and order. Shared things also come with time limits: whoever holds a deploy slot or the test machine posts progress every half hour, and after an hour of silence the slot gets released.

6. Only Ask Me What's Mine

Most work never reaches me. The lanes decide everything else themselves and tell me afterwards. They only ask about:

  1. Money: prices, offers and any new recurring cost.
  2. Customers: anything a customer sees, receives or can do.
  3. Production: deploys and releases of something new.
  4. Credentials: keys and secrets, which I run myself.
  5. Irreversible changes: deleting data, or anything that can't be undone.
  6. Direction: a feature or design I haven't approved, or reversing one of my decisions.
  7. The rules: changes to who decides what, this list included.
  8. Genuine uncertainty: two reasonable options remain after checking the code and data and getting a blind review, and the wrong pick is costly to undo.

How they ask matters as much. All of a lane's questions come in one numbered message, each one a yes-or-no with the lane's pick and at most three plain sentences of why. One yes covers a whole plan, so nobody comes back for each step. Every message to me ends with "Needs you: …", even if it's "Needs you: nothing". And my words are passed on verbatim and logged in one place, so nobody asks me twice for the same yes.

7. Say What Really Happened

When something breaks, or an agent got something wrong, it says so plainly. A green test or a merged PR doesn't mean a feature is done; observed behavior does. Updates lead with what changed for the user and what was actually seen: "Created two wallpapers consecutively and found both in Library" tells me more than a test count.

When I asked my orchestrator which rule matters most, it said:

One owner per outcome, and one gate for anything shared. Most of the chaos with many agents comes from two agents touching the same thing at once, or nobody clearly owning a result.

Here's what all of that looks like for one feature, from my request to the merge. Try it:

One feature, start to finish
A made-up example. Send the request, and answer when you get a question.
GitHubMe🧭 Cindoriroutes cross-lane work🧭 Backdroporchestrator🧭 Platformorchestrator✨ Ownershare links🔍 Reviewerfresh agent🗄️ Ownercatalog backendIssuethe mandateBranchown worktreePull requestmain
Me → 🧭 Backdrop: Let people share a wallpaper with a link.

Working From Anywhere

All of this runs on a Mac Studio. The agents build, test and run the apps there, so I don't need to sit in front of it.

The orchestrators have Claude Code's Remote Control turned on, so I can follow along and answer them from my phone or my MacBook. On top of that, the Studio keeps a Remote Control service running for each project. A small launch agent starts it at login and restarts it if it ever exits. From my phone, I can start a new session in any of the repos, and it gets its own git worktree, just like the owners do.

So when I'm away from the desk, the work keeps going, and anything that needs me still reaches me.

What's Still Rough

Plenty, and most of it is plumbing:

  • Messages between sessions are capped. The app pauses a session after about ten messages in a row from other sessions. It's a sensible guard, but it means orchestrators have to batch everything into one message per owner, and a pause can still leave cleared work sitting overnight.
  • Finished work doesn't always announce itself. An orchestrator is supposed to hear when an owner finishes, but that doesn't work reliably for desktop sessions yet, so the hourly check catches what slips through.
  • Agents can't start new sessions. An orchestrator or a scheduled run can message an existing thread, but it can't start a new owner. That still needs a person, which is usually me.

The Bottleneck Is Still Me

I started this post saying the bottleneck was me, as the message bus between agents. I'm not the messenger anymore: the agents talk to each other, and the orchestrators carry the context. But I'm still the bottleneck, just in a different way. Now it's my approval, my taste and my direction.

The agents aren't the slow part. A dozen of them can design, build, review, test and merge in parallel, through the night if I let them. What they wait on is me: a yes on a changelog, a look at a screen, a click on a permission prompt, five minutes to say which of three designs feels right. One feature sat ready for most of a day because I had to be at a specific machine to approve a single dialog.

I had an agent go through my own messages from two busy days to see where my time went. There were 488 of them, and only about one in eight was a real sign-off. About two thirds were things the system should have handled: explaining what an ask even meant, approving things a standing rule could have covered, correcting wrong assumptions, chasing stalled work, and untangling crossed messages. That review is where the rules in "Only Ask Me What's Mine" came from.

So the question shifts from "how do I get agents to do the work" to "how do the agents and I work together well". That turns out to be its own craft: getting across taste that's hard to put into words, asking questions of the right size, and remembering what I meant rather than just what I said. The agents that do it best show me something concrete early, like a rough still or a side-by-side, and let me react.

We Need a Better Interface

A big part of why I'm the bottleneck is the interface. We're getting close to a point where I can hand off a task and be pretty sure it comes back 98% right. The tools we use to work with agents weren't built for that. They're built for supervising: a long list of threads that I step through one by one, clicking into each to read what happened and push it along. That made sense when every agent needed watching, and each thread was a task of its own. Now most of them don't need watching, and one task can span many agent threads.

Most of the friction left is in how the agents and I talk to each other. A typical example: an owner has worked on something for a few hours and solved nine out of ten problems along the way. Then it asks me about the tenth. The question is perfectly reasonable, but I don't have the context it built up, so I can't tell what the options actually mean or what each one would change. Most of the time I just reply "explain", and we go back and forth until I understand enough to decide.

I think this way of working needs new affordances, not just faster versions of the old ones:

  • Organized around decisions and outcomes, not threads. I don't need to see every conversation. I need to see what's moving, what's done, and the handful of things that are waiting on me.
  • Questions that carry their own context. When an agent asks me something, it should bring what it already decided, what this choice changes, and ideally a quick preview of each option, so I can answer in seconds without catching up first.
  • Steering with a glance or a keystroke. Not a paragraph. The first signs are already here, like tab-to-complete suggested actions in the input box of tools such as Claude and Codex.
  • Quieter, with room to think. A calmer, more streamlined interface that shows just the context a decision needs, and leaves space to actually think it through.

Today I'm still clicking around in little bitmap interfaces, hopping between tabs and windows, pressing buttons to approve things and reading walls of status to piece together what's going on. It already feels like science fiction, but much of the workflow is still archaic.

The agents are already extremely capable at the work itself. The open frontier is the interface between them and us: how we share our ideas with them quickly, how they show us what they're doing without drowning us, and how we come to trust them with more.


If you want to try this yourself, I've put a generalized version of the rules, plus templates for the issues and pull requests, on GitHub: OskarGroth/orchestrating-agents. Take whatever is useful.