Why one agent is no longer enough: orchestrating Claude Code, Codex, and Kiro without tmux chaos
I’m Denis Shokhirev, an Agentic AI Systems Architect based in Freiburg im Breisgau, Germany, and at DennisCraft AI Studio I ship production AI systems for DACH B2B clients on Claude, Supabase, n8n, Doppler, and self-hosted Postgres. The failure mode I see most often is not “the model wrote bad code.” It’s 3 agents editing the same repo from different panes, each looking useful in isolation, while nobody can explain which branch, prompt, or terminal actually produced the code now heading toward p
I’m Denis Shokhirev, an Agentic AI Systems Architect based in Freiburg im Breisgau, Germany, and at DennisCraft AI Studio I ship production AI systems for DACH B2B clients on Claude, Supabase, n8n, Doppler, and self-hosted Postgres. The failure mode I see most often is not “the model wrote bad code.” It’s 3 agents editing the same repo from different panes, each looking useful in isolation, while nobody can explain which branch, prompt, or terminal actually produced the code now heading toward production.
That is the moment when one agent stops being enough and multiple agents start becoming dangerous. A single coding agent can still work for a contained feature. But once a delivery path spans application code, SQL migrations, workflow automation, secret handling, and policy checks, the bottleneck is no longer generation quality. It is orchestration: task boundaries, execution order, tool permissions, and auditability.
Why the single-agent pattern breaks down
The “one smart agent per repo” setup fails for the same reason one engineer should not simultaneously be product manager, implementer, reviewer, and release manager. Context gets overloaded, priorities collide, and mistakes become hard to localize. In real projects, one task touches 4 layers at once: business logic, database schema, automation, and controls.
On several recent client systems, I saw the same issue repeat: if one agent owns everything, it burns context switching across unrelated layers. If multiple agents share one workspace without strict boundaries, they duplicate work, invalidate each other’s assumptions, and create merge noise that humans must untangle later. The problem is not that a model is weak. The problem is that the execution topology is wrong.
| Layer | Typical task | Failure without orchestration |
|---|---|---|
| Application | Feature code, refactoring | Silent API contract drift |
| Database | SQL, migrations, indexes | Duplicate or unsafe migrations |
| Automation | n8n workflows, webhooks | Broken step contracts |
| Controls | SAST, secrets, policy | Checks happen too late |
OWASP’s guidance for LLM applications is clear: define trust boundaries and validate tool behavior instead of assuming prompts alone will keep a system safe. See the OWASP Top 10 for LLM Applications project and related prevention guidance (OWASP, 2024, https://owasp.org/www-project-top-10-for-large-language-model-applications/). In coding workflows, that translates into a practical rule: the same agent should not author, verify, and approve its own changes.
A workable model: role separation instead of terminal theater
I do not try to create one meta-agent that does everything. I split roles. Claude Code is useful for longer architectural threads and cross-file reasoning. Codex is useful for constrained implementation tasks and alternative drafts. Kiro can be useful as a separate research or helper lane, but not as the source of truth for a production repository. Source of truth belongs in git, CI checks, and an explicit task queue.
Minimal role design
- Planner: breaks a task into atomic changes and ordering.
- Builder: writes code in an isolated branch.
- Verifier: runs tests, semgrep, bandit, gitleaks, and policy checks.
- Merger: compares diffs, accepts or rejects changes.
The key constraint is simple: one agent, one responsibility, one branch, one editable file surface. Do not let 2 agents modify the same directories at the same time unless you enjoy reading conflict markers generated by machines that never spoke to each other.
git checkout -b agent/builder-task-142
pytest tests/unit -q
semgrep --config auto .
bandit -r app -q
gitleaks detect --source . --no-banner
git add .
git commit -m "task-142: isolated builder changes"
git push origin agent/builder-task-142Control lives in a queue, not in tmux
tmux is fine as an observation layer. It is a bad control plane. The moment your operating state lives mainly inside terminal panes, you lose reproducibility. I prefer a simple pattern: tasks in Postgres, status transitions through an API or n8n workflow, and agents only receive the permissions required for their current stage.
You do not need a new branded platform for this. Postgres, n8n, and discipline are enough.
create table agent_jobs (
id bigserial primary key,
task_key text not null,
role text not null check (role in ('planner','builder','verifier','merger')),
branch text not null,
status text not null check (status in ('queued','running','failed','done')),
payload jsonb not null,
created_at timestamptz default now(),
updated_at timestamptz default now()
);n8n becomes the dispatcher: create a job, call the agent, collect artifacts, trigger checks, and move the task forward or back. That matters operationally because any failure is visible as a tracked event, not as missing terminal output from a session nobody can reconstruct.
What should block merge
At minimum: unit tests, semgrep, bandit for Python code, gitleaks for secret leakage, SQL parameterization checks, and migration sanity checks. Anthropic’s tool use documentation recommends clear tool definitions and explicit confirmation for sensitive actions (Anthropic Docs, 2024, https://docs.anthropic.com/). In practice, that means an agent should never grant itself destructive access just because the prompt sounded confident.
steps:
- run: pytest tests/unit -q
- run: semgrep --config auto .
- run: bandit -r app -q
- run: gitleaks detect --source . --no-banner
- run: python scripts/check_sql_params.py
- run: python scripts/check_migrations.pyHow I assign Claude Code, Codex, and Kiro
I do not care which vendor wins an internet argument. I care about each tool’s failure profile inside a production stack.
| Tool | Best use | Restriction I keep |
|---|---|---|
| Claude Code | Long-context architecture and coordinated refactoring | No final merge authority without external checks |
| Codex | Fast local edits and alternative implementations | Not the only source for migrations or policy-sensitive code |
| Kiro | Separate helper lane, research, edge-case discovery | Not owner of the mainline branch |
A practical flow looks like this: Claude Code plans and executes a broader refactor in its own branch. Codex handles a constrained subtask such as rewriting tests or a single module. Kiro explores edge cases or proposes a fallback implementation. All outputs converge at a verifier stage. If verification fails, the task goes back to the queue, not into a human Slack thread where everyone debates whose pane caused the issue.
What changes in regulated European environments
This matters more in regulated contexts because process quality is part of the product. A client in logistics or fintech will ask who changed what, which access path the agent used, where secrets were stored, and how approvals were recorded. “We had four tmux panes open and it worked on my laptop” is not an operating model.
So I stick to 3 rules. First, agents do not receive raw secrets in prompts; they receive scoped access through a controlled secret layer such as Doppler. Second, every meaningful action leaves a trace in the task system or CI logs. Third, merge is a control event, not the natural end state of model output. If you build around those rules, multi-agent work stops being terminal chaos and starts becoming a production process.
FAQ
Do I need tmux at all?
No, not for control. It is useful for local observation and debugging, but your task state, checks, and audit trail should live outside the terminal.
Should each agent get its own workspace?
Yes for write operations. Separate branches and isolated workspaces reduce state contamination and make failures reproducible.
Is one verifier stage enough?
Usually not. I prefer fast checks before commit and stricter checks before merge so obvious failures never consume human review time.
Where should agent memory live?
Not in terminal history. Short-lived operational state belongs in Postgres or Supabase, while durable decisions belong in git, ADRs, and tracked issues.
When is multi-agent actually worth it?
When you have independent subproblems with different artifact types such as code, SQL, automation, and policy. For a small linear task, one agent is often cheaper and safer.
Which stage in your LLM delivery path causes more production pain right now: code generation, verification, merge control, or post-release behavior? I’d genuinely like to compare that with what I’m seeing across DACH teams.
I run a free 30-min stack audit for founders and CTOs building AI in regulated markets. DM me on LinkedIn or write to @ger_dennis_ai.
I build agents like this for businesses in Germany and the EU.
Tell me in two sentences what eats your team’s time – reply within 24 hours.
Turn your process into an AI system
Production quality. DACH B2B focus.