Running one AI coding agent is last year’s workflow. My normal setup today is two or three Claude Code sessions working the same repository from separate git worktrees — one refactoring, one writing tests, one chasing a bug. It is a genuine productivity multiplier, with one recurring failure mode:
Agent A is halfway through refactoring
src/auth. Agent B decides the quickest fix for its bug also lives insrc/auth/token.go. Neither knows about the other. The result is silent overwrites or an unmergeable diff — produced by two tools that were each doing their job correctly.
Sessions do not share state, so the failure is not intelligence — it is coordination. And every existing fix I evaluated asked me to run an orchestration server with a database and a web dashboard to solve what is, at its core, a mutual-exclusion problem between processes on my own machine.
That seemed like the wrong trade. So I built dibs: a single Go binary that gives coding agents the one primitive they are missing — calling dibs on files.

$ dibs claim src/auth --reason "refactor auth" --agent alice
✓ claimed src/auth/** — lease 82fead6e as alice, expires in 29m
$ dibs claim src/auth/token.go --agent bob --reason "fix token bug"
✗ denied
src/auth/token.go held by alice (refactor auth), expires in 29m
wait, work elsewhere, or coordinate: dibs note "..."
The insight: git already provides a shared channel Link to heading
The reason other solutions reach for a server is that parallel agents appear to have no common ground — separate processes, separate worktrees, separate conversations. But they share something already: every git worktree of a repository shares one .git common directory.
That observation is the entire architecture:
repo/.git/dibs/ coordination state — leases, presence, notes, journal
machine-local, invisible to `git status`, visible to
EVERY worktree instantly; no commits, no daemon
repo/.dibs/ knowledge — lessons/*.md
committed and reviewed like any other file, shared
with your team and CI through git itself
A claim is a JSON file with an owner, a set of glob patterns, a reason, and an expiry. Conflict checks run under a kernel file lock (flock on Unix, LockFileEx on Windows), so a crashed process can never leave the store wedged — the operating system releases the lock with the process. Expiry is evaluated lazily whenever state is read. There is no background process, no port, and nothing to deploy.
Claims are leases, not locks: they expire on their own (default 30 minutes, renewable, capped at 24 hours). An agent that crashes while holding a claim costs you nothing but the remainder of its TTL. You cannot deadlock a repository with dibs, by construction.
Advisory coordination is not enough Link to heading
An uncomfortable truth about agent protocols: models under context pressure forget instructions. A polite “please check before editing” in AGENTS.md works until the agent is eighty turns deep in a debugging spiral.
So dibs closes the loop with enforcement, at two levels:
Claude Code — dibs hook install claude registers a PreToolUse hook. An edit that targets a file claimed by another agent is blocked before it executes, and the model is told exactly why:
dibs: src/auth/token.go is claimed by alice (refactor auth) — the claim expires in 29m.
Coordinate instead of colliding: wait for the lease, message them with `dibs note`,
or work on files outside their claim. Run `dibs status` to see all active claims.
The agent does not merely fail — it learns the situation and adapts. In my testing this message is enough for Claude to pick a different task or leave the holder a note, without being asked.
Everything else — dibs hook install pre-commit refuses commits that touch someone else’s claim, which covers Codex, Cursor, and humans.
Both hooks fail open: if dibs itself malfunctions, editing and committing proceed normally. A blocked edit should be a coaching moment; a bricked repository is a bug. Hook installation is additive and idempotent — existing settings and hooks are preserved exactly.
Presence, handoffs, and an audit trail Link to heading
Coordination is more than mutual exclusion. dibs keeps three small streams of context flowing between agents:
$ dibs status
agents
bob (you) active 0s ago on main — new endpoints
alice active 2m ago on main — refactor auth
claims
● src/auth/** alice (refactor auth) expires in 27m
● src/api/** bob (you) (new endpoints) expires in 29m
dibs note "renamed User.ID to User.UUID — regenerate mocks" broadcasts a handoff to every agent on the repository, with per-agent read tracking. And every claim, denial, release, expiry, and note lands in an append-only JSONL journal — dibs log answers “what have the agents actually been doing?”, which turns out to be a question you ask often.
Lessons: memory that travels with the repository Link to heading
The second thing parallel agents lose is knowledge. One session discovers that the rate limiter panics if it registers before the auth guard; the next session rediscovers it the hard way.
dibs stores lessons as markdown files with YAML frontmatter under .dibs/lessons/ — which means they are committed, diffed, reviewed in pull requests, and shared by git pull. CI agents receive the team’s accumulated knowledge with zero infrastructure, because the knowledge lives where the code lives.
$ dibs lesson search "why does the rate limiter panic"
1.91 rate-limit middleware must register after auth
The limiter reads ctx.User set by the auth guard. Registering it earlier panics...
Search is BM25 with light stemming, computed in memory per query. No embedding model, no vector database. At the scale of a repository’s accumulated lessons — hundreds of documents, not millions — lexical search is instant, deterministic, and fully sufficient.
Agents use it natively over MCP Link to heading
dibs ships an MCP server (dibs mcp, stdio) with eight tools: dibs_claim, dibs_check, dibs_release, dibs_status, dibs_note, dibs_notes, dibs_lesson_add, and dibs_lesson_search. The server instructions and tool descriptions encode the protocol itself — claim before editing, release when done, leave notes, record lessons — so any MCP client learns the workflow from the tools alone.
claude mcp add dibs -- dibs mcp
Codex, Cline, Cursor — anything that speaks MCP gets the same tools. For agents that coordinate via CLI instead, dibs init --agents-md appends the protocol to AGENTS.md.
What dibs deliberately is not Link to heading
- Not a task tracker. beads already does issues-as-agent-memory well; dibs claims pair naturally with it (
--reason "bd-142: refactor auth"). - Not a session manager. claude-squad and vibe-kanban launch and organize agent sessions; dibs coordinates file access between whatever you already run.
- Not a platform. No server, no dashboard, no accounts, no telemetry. One binary, some JSON under
.git/, some markdown in.dibs/.
Two limitations are worth stating plainly, because they are design decisions rather than gaps. First, live coordination is per-machine — which matches how parallel agents are overwhelmingly run today — while lessons travel across machines through git; a cross-machine backend is on the roadmap. Second, dibs is a cooperative mechanism with enforcement hooks, not a security boundary: it coordinates well-behaved tools, and the hooks catch the forgetful ones.
Try it Link to heading
go install github.com/polymatx/dibs/cmd/dibs@latest
# or a prebuilt binary: https://github.com/polymatx/dibs/releases
cd your-repo
dibs init
dibs hook install claude
claude mcp add dibs -- dibs mcp
Then open two Claude Code sessions and watch them negotiate instead of collide.
The code is MIT licensed at github.com/polymatx/dibs, and the core is deliberately small enough to read in an evening. Bug reports are welcome — especially from worktree topologies I have not met yet.