DEV Community

Cover image for Coordinating multiple AI coding agents on one repo or multiple in your own ecosystem — without git worktrees
Miroslav Šotek
Miroslav Šotek

Posted on

Coordinating multiple AI coding agents on one repo or multiple in your own ecosystem — without git worktrees

If you have run more than one AI coding agent at once, you have met the failure
mode: agent A is editing src/auth.py while agent B rewrites the same file. One of them loses. The usual fixes are real, but they both dodge the actual problem.

The two usual answers, and what they dodge

Git worktrees. Give each agent its own checkout sharing one .git. They cannot collide on disk, and conflicts surface at merge time. This is isolation — it keeps agents apart so they never have to coordinate. Great until the merges fight.

Agent frameworks (LangGraph, CrewAI, AutoGen). You write the agents and their control flow in one process; one orchestrator spawns sub-agents. Powerful, but it assumes you are building the agents. If you are running off-the-shelf terminal assistants from different vendors, that is not your situation.

Neither lets several independent agents coordinate in real time on a shared tree:
claim work, see a shared plan, talk to each other. That layer — call it a
coordination bus — is what was missing for us, so we built one: SYNAPSE CHANNEL, a local-first WebSocket hub. One dependency, runs on your machine.

pip install synapse-channel
synapse hub --port 8876 --db ./synapse.db   # the coordination hub (crash-safe)
Enter fullscreen mode Exit fullscreen mode

1. Claim before you edit

The core primitive is an advisory file-scope claim. An agent leases a task and declares the paths it will touch; the hub refuses an overlapping claim. The hub never reads your filesystem — the globs are agent-declared.

from synapse_channel import SynapseAgent

agent = SynapseAgent("backend", uri="ws://localhost:8876")
# ... after connect():
await agent.claim("auth-refactor", paths=["src/auth.py", "src/session.py"])
# A second agent claiming any overlapping path is denied — they never touch
# the same file. Leases expire and carry an epoch, so a crashed agent never
# holds a claim forever.
Enter fullscreen mode Exit fullscreen mode

No central orchestrator decides this. Each agent claims for itself; the hub is the single arbiter of overlap.

2. A shared plan, on the command line

There is a dual-ledger blackboard — tasks and progress, with dependencies — that you can drive without writing a client:

synapse task declare BUILD --title "compile" 
synapse task declare TEST --title "run tests" --depends-on BUILD
synapse task update BUILD --status done      # unblocks TEST
synapse board                                # print the shared plan
Enter fullscreen mode Exit fullscreen mode

A held task can be handed off atomically to another agent (scope, status, and context preserved), and an LLM-free supervisor re-offers work that stalls.

3. The interesting bit: waking a turn-based agent

Here is the problem nobody talks about. A turn-based assistant (the kind in your terminal) cannot hold a socket open between turns. So how does it learn a message arrived without burning turns polling?

SYNAPSE turns it into a push. synapse wait blocks on the connection and exits the instant a message addressed to you arrives. You run it as a background task; when it exits, your harness re-invokes the agent. No message → it costs nothing.

# backgrounded: exits + wakes the agent the moment a directed message lands synapse wait --name backend-rx --for backend --directed-only
Enter fullscreen mode Exit fullscreen mode
# from anywhere — message one agent, a project group, or everyone
synapse send --target backend "rebased main, re-pull"
synapse send --target "quantum/*" "freeze, I'm tagging"
synapse send --target all --priority "[deploy] prod is green"
Enter fullscreen mode Exit fullscreen mode

--directed-only keeps routine broadcasts from waking you, while priority messages still get through. Serialise the things that must not overlap — commits above all — by wrapping them in a lease:

synapse lock myrepo:git -- git push   # holds the lease while pushing; others wait
Enter fullscreen mode Exit fullscreen mode

4. It survives a restart

Every claim, release, task, and checkpoint goes into an append-only SQLite log and is replayed on start-up, so a hub restart resumes live leases instead of dropping them. A lapsed claim keeps its checkpoint, so the next agent to take the task resumes rather than restarts. The same log doubles as a cross-agent audit trail — who claimed what, when, and who handed off to whom.

The honest part

We did not design this in the abstract. SYNAPSE coordinates the agents that develop SYNAPSE, every day. Most of the rough edges in the changelog — a missed wake, a waiter that hung after a restart, a ghost connection blocking a re-arm — were problems we hit using it, fixed the same day because they annoyed us directly. A tool its authors depend on gets sharp quickly.

It is local-first by design: a loopback hub, single owner, no cloud. Licence is AGPL-3.0 (free for OSS / research / personal); a pay-what-you-want commercial licence from CHF 9.99 covers closed-source and SaaS use.
Also, you still can buy me a coffee :)

pip install synapse-channel
synapse team   # hub + a couple of local workers, to kick the tyres
Enter fullscreen mode Exit fullscreen mode

If you coordinate parallel agents some other way, I would like to hear it — what breaks at three agents? At ten?

Top comments (0)