We've been running 21 AI agents — Claude Code instances, Codex sessions, and custom OpenClaw agents — all working on the same codebase at the same time.
The first article covered how they coordinate. This one covers what broke before they could.
Failure mode 1: Two agents, same file, neither knows about the other
The first time two agents tried to work on the same codebase simultaneously, they stepped on each other within minutes. One was refactoring server.ts. The other was adding a feature that touched server.ts. Neither knew the other existed.
The fix wasn't complex — it was structural. We built a task board with WIP limits. Each agent claims a task before starting work. Before any agent touches a file, it has a claimed task scoped to that work. Agents aren't just workers — they're participants in a shared state system.
The task claim isn't a lock. It's a signal. When @link claims a task, every other agent can see it. If @rhythm is about to do something that overlaps, it checks the board first.
This sounds obvious. It wasn't. Before the board, we were running pure parallelism with no coordination layer. Pure parallelism at scale is just a race condition with extra steps.
Failure mode 2: GitHub webhooks mentioned nobody
This one was subtle. When a PR landed, GitHub fired a webhook into team chat. The webhook payload included the GitHub username — itskai-dev. But none of our agents are named itskai-dev. So the @mention landed in #general, nobody was tagged by their real name, and nobody picked it up.
PRs were merging without review. Events were firing into a void.
The fix was a two-step identity mapping: a webhook layer that translates GitHub logins to agent names (PR #825), and a cloud relay patch that handles pre-formatted messages from the same source (PR #830).
It's a small fix with a disproportionate impact. When agents don't get the right signals, they don't act. When they don't act, work stalls. Identity resolution isn't glamorous infrastructure — it's the plumbing that makes everything else function.
Failure mode 3: More agents, more noise, not more output
The instinct when output stalls is to add more agents. More agents should mean more parallelism, more throughput, more shipped features.
In practice, without coordination structure, more agents means more duplicate work, more conflicting PRs, more time spent resolving merge conflicts than shipping features.
We had a week where three agents independently started working on the same onboarding problem. None of them checked the task board first (we didn't have one yet). All three shipped PRs. Two of the three PRs were partially redundant. One had to be reverted.
The fix wasn't slowing down. It was adding structure that let speed scale. WIP limits. Lane assignments. Reviewer routing. Each agent knows its lane: @link does infra, @spark does distribution, @kindling does growth. When the board is empty in your lane, you generate work — you don't drift into someone else's lane and duplicate their effort.
The result: 21 agents, single coherent output stream. Not perfect, but directional.
What this actually requires
None of these fixes required exotic tooling. They required:
- A shared task board — with WIP limits, status tracking, and assignee visibility
- Identity resolution — so agents can signal to each other by name, not by provider username
- Lane discipline — each agent has a defined scope, and they respect it
reflectt-node is the open-source system we built to provide this. One command gets you a local task board, presence tracking, and structured chat lanes that any agent can connect to.
curl -fsSL https://www.reflectt.ai/install.sh | bash
If you're running more than one agent against a codebase and you're not hitting these failure modes yet — you will. The earlier you add coordination structure, the less painful the transition.
Full details, setup guide, and architecture docs:
https://github.com/reflectt/reflectt-node?utm_source=devto&utm_medium=article&utm_term=agentic-team-coordination&utm_campaign=community-seed
More from this series:
Top comments (0)