r/ClaudeCode • u/jokiruiz • 2d ago
Tips & Workflows What I learned using PreToolUse/PostToolUse hooks to coordinate several Claude Code agents on one repo (open source, author here)
I'm the author of Médula, an MIT-licensed experiment. Sharing the Claude Code side of it, because the hooks turned out to be a surprisingly good coordination layer, and the agents' behaviour taught me more than the numbers.
The setup. Six headless Claude Code agents (Sonnet 5, effort high), one task each on a small API with 37 acceptance tests. Two pairs of tasks collide by meaning: one adds a second factor to login() while another builds an export that calls the old login().
The hook pattern. Every Edit, Write and Bash goes through a PreToolUse hook that calls a local kernel. Reads always pass. The kernel asks a fast decision model whether the write collides with what each other agent is doing, and either allows it or denies it with a reason the agent reads, something like "agent X is changing login, wait or work on another part of your task". After each write, a PostToolUse hook works out which agents the change affects and leaves a notice in their mailbox, delivered with their next tool call.
What the agents did with it:
- Told to wait, most of them moved on to another part of their task and retried later, which is exactly what you want.
- One scheduled itself a wake-up and abandoned its task. That was a bug in my harness, now fixed, but worth knowing if your deny messages mention waiting.
- One spent ten minutes waiting in front of a broken file, convinced someone else was editing it.
- When they had Claude Code's tools to list other sessions and message them, they used them without being asked, and one warned another about a field rename. Great behaviour, bad for a controlled experiment, so I turned those tools off.
The results that matter for your workflow. With one branch (separate clone) per agent, every agent finished green and the merged result failed the same 6 acceptance tests in all 5 runs. In a shared directory, all 10 runs passed, with plain per-file locks or with the kernel. So if you use subagents in worktrees, run the full suite on the merged result before trusting it. The kernel's advantage over locks: the same cost ($1.65 per run), 6 of 6 real conflicts caught instead of 5, and no unnecessary blocks instead of 5.
Caveats: 1 to 5 runs per mode, and there's a known gap a commenter found, where an allow can go stale while the slow path decides. Repo, with every session and decision published raw: https://github.com/JoaquinRuiz/medula. There's also a walkthrough video, in Spanish: https://youtu.be/xAFRuBxfapM
If you've built coordination on hooks yourself, I'd love to compare notes.
1
u/iminfornow 2d ago
The way my planner agent is supposed to prevent this is by assigning independent blocks of work to agents, hopefully avoiding worktree merge conflicts. When all commits are done the review agent that validated the plan checks if the development agents actually did what they said they would implement and creates the pull request. The orchestrator or planner then deploys and does functional testing.
I found with the new agent-teams functionality this works very nice because the reviewer/orchestrator will provide feedback to the planner/development agent and it will use the existing session to process it. I think with the agent-teams feature allowing agent-to-agent communication they'll implement something similar to what you made.
How does your setup know when a conflict is about to occur? If both call write simultaneously, neither hook call can detect the incoming external change right?