Changing posture
For years, my pleasure was eating code. But with the agents, a big chunk of the work moved.
In late April, then mostly in early May with Claude Code, I start writing far less code by hand. I’m still a developer, but my days change shape: framing the task, breaking the problem down, reviewing the code, testing the result, taking back control when the agent invents, generalizes, or breaks something. The agent can ship the code. If the diff is bad, it’s still my problem.
The AI accelerates me, but it also accelerates my bad reflexes. From watching hundreds of correct lines pour out, I sometimes ended up reviewing too fast. Later I’d come back to a diff thinking “what the fuck?” Hidden bug, code smell, shaky architectural choice. The agent had produced code; I had stopped treating it as code that needs review.
I start treating my prompts like tickets I’m still responsible for: understand the need, validate a plan, isolate the work in a branch or worktree, run the checks, review the diff. I call this orchestration, for lack of a better word.
When sub-agents arrive
Before sub-agents, I was already orchestrating by hand: re-pastable Markdown, ticket scenarios, custom slash commands. I’d hand the agent a procedure: read this, produce that, check this, stop there.
When Claude Code adds custom sub-agents through /agents, what changes is mostly the isolation: each sub-agent works in its own context. It runs a task, returns a report, then disappears. I see the move: frame a task, send it into a throwaway context, get a report back, verify.
The day after the release, I push it too far: instead of writing an agent, I write a meta-agent that reads the official docs, then spits out specialized agents on demand.
In one evening, I end up with about thirty specialized agents: generalist front-end, “UI state” front-end, “accessibility” front-end, back-end, database, “test diagnostic”, “Playwright tester”, “lint/format”, “CI triage”, “doc writer”, and so on.
On paper, it looks like a small team. Inside Claude Code, it quickly becomes something else: a chain of relays.
Me, I hand intent to the parent agent. The parent agent summarizes, picks a sub-agent, passes part of the context. The sub-agent works in its bubble, returns a report, then vanishes. At every step, something can go missing: a forgotten constraint, a flattened nuance, a too-partial result. You see where this is going? Yes, context again. Here, the input shapes the output.
I’m rebuilding in miniature a ceremony I already know far too well: client, PO, architect, dev, tester, reviewer, tech lead, then back to the human.
The problem isn’t the agents themselves. It’s the number of relays. Each added role demands framing, a handoff, a verification. As soon as you multiply relays, you pay in coordination; here, that cost runs through summaries and context windows.
I wanted to build an ideal team. I built a bureaucracy.
I trim the fat.
I keep fewer specialized agents and move back toward more generalist roles. Context stays the real lever: a generalist agent with a good prompt often does better than a specialist agent with a poor brief.
Some sub-agents stay useful, especially to explore a path, test a hypothesis, or isolate a task. But the main agent becomes the mandatory pass-through: it frames, delegates, picks up the reports, then hands me back a readable state.
On my side, I set the limits: scope, exit criteria, validations, order of execution. At this stage, I’m not chasing the perfect workflow yet. I’m mostly trying to cut the noise so I can keep experimenting.
My orchestration workflow
Once the noise is down, another problem remains: working with the agents without rebuilding an overcomplicated machine around them.
I keep two commands at the center:
/issueto talk to GitHub (create, update, or comment on issues),/worktreeto spin up parallel working copies, one per sub-task.
I tested a heavier approach with lots of scripts, logs, and end-to-end tests. I kept it long enough to see where it broke: too fragile, too complicated for what it brought.
At this stage I don’t have a perfect workflow. I have a smaller surface: a reusable prompt that describes the expected flow, the steps, the possible actions, and the moments to call /issue or /worktree.
This wasn’t my workflow for every task. For a simple fix, it was way too heavy. I mostly used it when the request was fuzzy enough to deserve a framing detour: understand, scope, slice, verify.
In my head, it always started before the code. I’d give the objective, the scope, the constraints, and what “done” meant. The agent would then read the project, spot the important files, look at the tests, and tell me what it had understood. I wanted to see its understanding before letting it write.
When the topic stayed fuzzy, we’d break the ambiguities. I’d ask for an approach, sometimes one or two explorations from sub-agents, then a consolidated version I could review. Only at that point would I kick off the implementation.
For a simple task, an agent worked in a dedicated worktree. For a wider task, I cut more aggressively: several worktrees, bounded chunks, less mixing in the diffs.
Then came the checks: tests, lint, types, sometimes architecture. Errors went back into a short loop. At the end, the agent presented me with the diff. I reviewed, I tested, I asked for fixes. The PR didn’t tell the whole story: just the objective, the changes, the checks, the linked issues.
Open question, not just AI: past how many relays does the signal degrade faster than it transmits?
The rule that starts to emerge is simple: few agents, bounded chunks, readable handoffs, and checks that quickly say whether the work holds. /issue and /worktree stay useful because they make the work observable without adding too much glue code: a request, an isolated space, a diff, a PR.
Crash-test of over-orchestration
Then I fall into the opposite excess: channel everything.
Very quickly, I swing the other way: I want to channel everything. Branches, worktrees, issues, PRs, hooks, guards, “secured” workflows: every action ends up with its sub-command, its planned path, its little wrapper around Git.
At first, it’s reassuring. Everything looks framed. Then I spend days iterating on the rig itself: a path works on one machine and breaks on another, a script becomes painful to debug, a rule fixes one case but opens others, the docs grow because the system isn’t readable without them anymore.
A typical case: I describe the plan in a kind of YAML, with the branches to create, the worktrees to prep, then the expected merge order. The tool can do the scaffolding. The problem hits when the orchestrator has to follow that plan over time. It reads the command but interprets it too fast, skips a step, or treats a rule as a suggestion. I end up correcting the agent instead of correcting the code.
On top of /worktree, I add /orc, my orchestration command. It would classify the task, pick the isolation level, prepare branches or worktrees, then try to run the steps through to PR.
After enough iterations, I see a problem: the commands exist, but the agents don’t always follow them as planned. /orc, /worktree, the PR rules, the hooks, the guards: it’s all written somewhere, and yet I often have to step in behind. The agent skips a step, reads a rule too quickly, or forgets why the command exists. The friction isn’t just in the tool. It’s in the gap between the written command and what the model does with it.
In early November, I start cutting. Specialized commands disappear. So does the glue code wrapped around Git. I also reduce the documentation, because part of it isn’t really transmitting an idea anymore: it’s there to make a too-heavy system bearable. A few days later, I do another pass on the skills and documents. Fewer examples, fewer “just in case” scenarios, less strategy frozen into files the agent rereads without always needing them.
What I keep from this cut is simpler: if orchestration doesn’t reduce ambiguity or coordination cost, it’s just adding a layer. It doesn’t replace Git, the tests, the PR, or CI. It’s there to help the agent know where to act, what to check, when to stop, and how to hand me back a readable state.
From here on, I’m wary of stacking. By piling on commands, docs, guards, and reminders to keep the agents inside the frame, I sometimes end up loading the very context I’m trying to protect. It’s not a problem on every task. It mostly breaks when the orchestrator has to hold too much at once: planning, dispatching, tracking the worktrees, reviewing the returns, prepping the PR. The frame is supposed to help; at that level of complexity, it becomes one more weight. The way out, I find less in some magic command and more in smaller tasks and shorter relays.
What survives isn’t the grand workflow. It’s the discipline. A smaller task. An isolated workspace when it’s worth it. A short relay. A report I can review. A diff that still tells the original intent. Orchestration stays useful when it reduces ambiguity; the moment it becomes a system maintained for its own sake, it starts polluting context again.
Update (April 2026)
A few months after writing this chapter, I barely use the orchestration plugin as a daily workflow anymore. The repo still exists: claude-code-plugins/orchestration, and I pushed it a long way during that period, but part of what I was building by hand has moved: sometimes into the tools, sometimes into lighter practices.
Looking back, the plugin matters less than the reflex it left me: keep orchestration light, observable, and simple enough that it doesn’t become the problem itself.