How it works
When any tab edits a file (viaedit_file, multi_edit, rename_symbol, move_symbol, rename_file, refactor, or shell writes), the file is automatically claimed for that tab. Other tabs see the claim and get advisory warnings.
Claim lifecycle
| Event | What happens |
|---|---|
| Agent edits a file | File claimed for the tab via checkAndClaim |
| Another tab edits the same file | Warning returned: “File X is being edited by Tab Y” |
| Tab goes idle (prompt finishes) | Claims released after 5 seconds |
| User aborts (Ctrl+X) | Claims released immediately |
| Tab closes | Claims released + tab marked as closed |
| Stale sweep (every 30s) | Claims older than 5 minutes released |
| Leaked agents (15 min) | Agent counters cleared by sweep |
Git blocking
Git operations that modify the working tree (commit, stash, restore, branch switch) are blocked while another tab has active dispatch agents. This prevents partial commits during concurrent edits.
The block is per-tab —a tab’s own agents don’t block its own git operations. When blocked, the tool returns a terminal error instead of a retryable error, preventing token-burning retry loops.
Contention handling
Whenedit_file fails with old_string not found AND the file is claimed by another tab, a terminal CONTENTION error is returned instead of the normal rich error. The agent stops and informs the user instead of retrying.
Commands
| Command | Description |
|---|---|
/claims | Show all active file claims across tabs |
/unclaim <path> | Release a specific file claim from current tab |
/unclaim-all | Release all claims from current tab |
/force-claim <path> | Steal a file claim from another tab |
Architecture
Events
All claim state changes emit batched events viaqueueMicrotask:
claim—file claimed by a tabrelease—file releasedconflict—tab tried to claim a file owned by another tab
Tool integration
Every file-modifying tool callscheckAndClaim before execution or claimAfterCompoundEdit after:
edit_file,multi_edit—checkAndClaimbefore editrename_symbol,move_symbol,rename_file,refactor—checkAndClaimbefore +claimAfterCompoundEditaftershell(sed, cp, mv, tee, >) —claimAfterCompoundEditaftertest_scaffold—claimAfterCompoundEditafter
Design decisions
Advisory, not blocking. Edits always proceed. The warning tells the agent another tab owns the file —the agent can choose to skip or proceed. This avoids deadlocks.
Git is the exception. Git operations during active dispatch are hard-blocked because committing mid-dispatch produces garbage. This is the only hard gate.
Claims are transient. Auto-released on idle (5s), on abort, on tab close. The stale sweep (5 min) is the safety net. Nothing persists forever.