My agents kept overwriting each other, so I gave them claims
I run several agent sessions in parallel, each in its own project, all on the same machine. For a while I believed that was safe because every session had its own repo. It wasn’t. Sessions reach outside their home tree more often than you think, a memory file here, a shared config there, a quick fix in a sibling project because the finding happened to surface elsewhere.
The collisions, when I audited them, all had the same shape. The second session was never blind. It saw the signs of the first one working, a fresh claim in a status file, a half-written directory, and it proceeded anyway. I want to be clear that this is not a model being careless. Under context pressure, an agent treats another agent’s presence as noise. Politeness is not a mechanism, so it doesn’t survive.
Also worth telling, my staging rule failed the same week. I wrote down “stage explicit paths only, never git add -A” after a session swept another session’s in-progress files into its commit. The rule was written, recorded, plainly worded. It was broken again 67 minutes later by the next session, which had never lived the incident and read the rule as advice.
So arbitration became a file. Before any session writes outside its own tree, it takes a claim, a small JSON file named after the target, holding who, when, and what for. It beats a heartbeat every writing turn and releases at the end. If another session already holds the claim and its heartbeat is fresh, the answer is REFUSED, and REFUSED is an answer, not an obstacle. The refused session queues a handover note instead, and the work happens later, in order.
The part I did not expect to matter, and it mattered most, was verifying the guard itself. Early on, the claim script printed “claimed” even when writing the claim file had silently failed (a slash in a target name broke the path). A guard that reports success on failure is worse than no guard, because sessions proceed believing they hold a lock that doesn’t exist. The fix was small, slugified names and a checked write, but the lesson was bigger. When you build a safety mechanism for agents, test the mechanism with the same suspicion you had for the agents.
A healthy machine, at rest, has an empty claims directory. Claims that outlive their session are the first thing I look at when something seems half-written. The whole mechanism is about sixty lines of shell. The value was never the code though. It’s the moment REFUSED shows up on screen and the wrong move becomes loud instead of silent.