What Breaks First When Agents Share a Workspace
A shared agent that a whole team can direct is useful. Keeping that team from redirecting it into its own stale work is the hard part.
Here is the shape, from a channel that looks like a lot of channels right now.
It is Monday morning in #payments. Priya tags the agent: find out why checkout latency spiked overnight, and write it up in the incident doc. The agent reads the doc, starts pulling traces, and works. Twenty minutes later Sam scrolls up, catches the thread, and tags the same agent: add the rollback timeline to that doc. The agent picks up where the last person left off.
From which version of the doc?
Priya’s run read version 4. While it was working, Sam’s edit landed version 5. If the agent finishes Priya’s task by writing back the document it read, Sam’s timeline is gone. Nothing errors. The doc looks complete. The next person to read it builds on a version that never existed.
Why this arrives now
Anthropic shipped Claude Tag in June, and its own description of the product is the clearest statement of this shape I have seen from a vendor. Within a given Slack channel, there is “one Claude that interacts with everyone.” The announcement calls it “multiplayer.” Anyone can “pick up the conversation from where the last person left off,” and the agent “works asynchronously.”
Each of those is a good product decision, and together they describe something specific: several people directing one worker against shared state, on their own schedules. Workspaces are getting larger, and agents are starting to work alongside each other inside them. The coordination questions that follow are not a flaw in any one product. They are what happens to shared mutable state once more than one actor touches it.
Here is what changes: the failures arrive in a fixed order.
That order is useful, because it means you can find your rung and see the next one before it costs you anything.
The ladder
| Rung | Setup | What breaks first |
|---|---|---|
| 1 | One agent, one artifact, one requester | nothing |
| 2 | One agent, many requesters, asynchronous | stale read |
| 3 | Many agents, overlapping runs on a shared artifact | concurrent lost update |
| 4 | Long-running agents that get reclaimed | zombie write |
| 5 | Agents across machines or services | cross-host coordination |
Rung 1. One agent, one artifact, one person. Nothing breaks. This is worth naming because it is where most teams still are, and it is why everything below reads as theoretical right up until it isn’t.
Rung 2. One agent, many requesters, asynchronous. This is Priya and Sam. The agent holds a copy of version 4, the world moves to version 5, and the agent writes anyway. The failure is a stale read followed by a write, and it needs no concurrency at all. The two requests never overlapped. They only shared a document. The retrieval version of the same rung: one agent refreshes a shared corpus while another is mid-task, and the answer regresses.
The mechanism that closes it is old. Track which actor holds which version, and when a peer commits, invalidate the copies that are now behind. The stale writer gets refused and has to re-read before it can land anything. That is the same idea CPUs have used for decades to keep one core from reading a cache line another core just wrote.
Rung 3. Many agents, overlapping runs. Now two workers finish in the same second. Both write the shared artifact. Both writes report success. One result is not there afterward. This is the oldest bug in the database book, the lost update, and agents make it worse than ordinary services because nobody re-reads the document with suspicion. In a coding fleet it looks like an agent writing back over a plan a second agent already moved: last write wins, and the run looks green.
Invalidation alone does not close this one, because there is no gap between release and write to catch. What closes it is putting the version on the write itself. The writer submits the version it read, and the store commits only if that version is still current. The loser gets a typed, retryable conflict instead of a silent overwrite.
Rung 4. Long-running agents that get reclaimed. An agent stalls holding the right to write. Your recovery logic correctly takes that right back so the rest of the fleet is not blocked. An hour later the stalled process wakes up and finishes its write.
Here is the trap. If nothing else touched the artifact in between, the version number is exactly what it was. Every version check passes. The late write lands on top of state the system settled long ago, and the version-on-the-write fix from rung 3 waves it through. In a workflow fleet this surfaces as a duplicate action: the reclaimed task already re-ran, the original wakes up and finishes too, and a record gets the same step twice.
Catching it needs something that moves when the writer is reclaimed, not when the data changes. Give each artifact an ownership generation, bump it on every reclamation, record the generation each writer claimed under, and check both at commit. The zombie gets rejected with a reason it can act on. The mechanics behind rungs 3 and 4, and the invariants that check them, have their own receipt.
Rung 5. Agents across machines or services. Once the actors are on different hosts, the coordination point itself has to be reachable and correct from all of them. This one is open. Production cross-host fencing is not shipped here. A demo-grade, default-off transport shows the shape of it, and I have not seen the production version solved in the agent tooling layer by anyone else either. If your fleet already spans machines, you are ahead of the tooling, and I would genuinely like to hear how you are handling it.
Do agents need versioning, or rollback?
The three middle rungs all depend on the same thing: the system knows which version a write was built on. Versioning is not a feature that sits next to coordination. It is the prerequisite that makes coordination checkable at all. A write can only be refused for being stale if something knows what stale means. That part ships today: durable version retention with read_at_version, snapshot reads for a consistent view, and an all-or-nothing multi-file publish, all single host.
Rollback is where the reasoning has to stop and be careful. Rolling a stored artifact back is a storage problem, and retention makes it tractable: the prior version is there to read, and the same guarded write path that protects every other commit protects the restore. Rolling back what an agent already did is a different question, because the agent already sent the Slack message, opened the pull request, and triggered the deploy. Those effects escaped before any commit boundary could hold them.
So the honest line is transactional artifacts, never transactional agents. You can get real guarantees over the documents a fleet shares. You cannot get them over the fleet’s actions on the world, and any layer that implies otherwise is selling you a boundary it does not have.
You are here
Rungs 2, 3, and 4 have working answers today, on a single host and for writers that go through the coordinator. Rung 2 is invalidation and a fail-closed deny. Rung 3 is write_cas, an optimistic commit that checks the version at the moment it lands. Rung 4 is a read-generation fence. Each one is a safety invariant model-checked in TLA+, with specs that run in CI on every push, and each spec carries a deliberate mutant that has to turn the checker red. If deleting a guard does not fail the model, the invariant was not load-bearing. And the guarantees no longer live only in this library’s own surfaces: the same protocol now rides the store you already run, a Postgres row or an S3 object, without migrating anything.
Rung 5 is the open one. Production cross-host fencing has not shipped, and the standing not-shipped list stays what it is: no cross-artifact write-skew prevention, no semantic constraints, no advisory-versus-enforce toggle, no source-watcher. The gap between the shipped list and that one is where this category still has work to do.
Why does the pressure keep rising?
Coordination pressure is not random. It rises with the size of the workspace, the number of actors touching it, and how long each run holds a read before writing. Bigger workspaces mean more artifacts per task. More actors mean more overlap. Longer runs widen the window between the read and the write, and that window is exactly where rungs 2 and 4 live. All three numbers are going up right now, and the failures do not announce themselves when they arrive. They look like an agent that forgot, a document missing a section, a model that got worse. Teams debug the model first. The model was fine.
Find your rung. If you are on rung 2 or 3, the smallest useful move is to put the version on the write: read a base version, submit it with the write, and handle the conflict you get back. You can add that over the store you already have.
The full taxonomy of how a shared write disappears is here, and the repo, with deterministic reproductions you can run offline, is at github.com/Cohexa-ai/agent-coherence. If your fleet is somewhere on this ladder and the failure looks different from what I described, tell me. That is the version of this post I want to write next.
Frequently asked
What breaks when multiple agents share a workspace?
In a fixed order: stale reads when one shared agent serves several people asynchronously, lost updates when several agents write the same artifact, and zombie writes when a reclaimed agent finishes late. Each needs a different mechanism, and the earlier fixes do not catch the later failures.
Do I need versioning or rollback for AI agents?
Versioning comes first, because a write can only be refused for being stale if the system knows which version it was built on. Rolling back a stored artifact is a storage problem that version retention makes tractable. Rolling back what an agent already did in the world is not, because those effects have already left the system.
Why doesn't a version check catch a late write from a stalled agent?
If nothing else changed the artifact while the agent was stalled, the version still matches and the check passes. Catching it needs an ownership generation that moves when a writer is reclaimed, not only when the data changes, so the late commit is rejected with a typed reason.
Can these failures happen without any real concurrency?
Yes. One shared agent serving two people asynchronously can write from a view a peer already replaced, with no overlapping execution at all. That sequential stale-read-then-write is the first rung most teams hit.