How file locking works

Switchman prevents file conflicts using a three-layer model: tasks, leases, and claims. On newer governed workflows, those claims also feed the write gateway and landing checks.

The problem it solves

When two AI agents edit the same file simultaneously, you get a merge conflict. In the best case it's annoying to resolve. In the worst case — when both agents have made significant changes to the same file — one agent's work gets thrown away entirely.

Traditional tools detect conflicts at merge time. Switchman prevents them at claim time — before a single conflicting line is written.

Three layers of coordination

Tasks

A task is a unit of work. Tasks live in a shared queue and have a title, priority, and status. Agents pick tasks up one at a time via switchman_task_next. The dequeue operation is atomic — no two agents can get the same task simultaneously.

switchman task add "Add auth middleware" --priority 9
switchman task add "Write auth tests" --priority 7
switchman task list

Leases

When an agent picks up a task, it gets a lease — a time-bounded ownership token. The lease has a heartbeat that the agent must refresh every 60 seconds. If the heartbeat stops, the lease expires, the task is released, and another agent can pick it up.

This prevents work from getting stuck forever if an agent crashes or the user closes their editor mid-task.

The Switchman MCP server handles heartbeats automatically. If you're using the CLI directly, call switchman lease heartbeat <lease-id> periodically.

Claims

Within a lease, an agent registers claims on the specific files it will edit. A claim says "I own this file for the duration of my lease." Any other agent that tries to claim the same file gets blocked immediately.

This is structural, not advisory. File claims are enforced at the database level using a partial unique index on active claims. Two concurrent claim attempts resolve with exactly one winner — guaranteed, even under concurrent load.

The claim lifecycle

  1. Agent calls switchman_task_next → receives task + lease ID
  2. Agent calls switchman_task_claim with file paths → claims are registered
  3. Agent edits the claimed files
  4. Agent calls switchman_task_done → lease closes, claims released
  5. Files are now available for other agents to claim

What happens when a claim is blocked

If agent2 tries to claim src/auth.js while agent1 owns it, the claim is rejected. The agent receives a clear error:

{
  "ok": false,
  "reason": "file_already_claimed",
  "claimed_by": "agent1",
  "task_id": "task-auth-001"
}

The agent should then either:

Stale lease recovery

If an agent crashes or stops sending heartbeats, its lease is marked stale after the timeout (default: 15 minutes). Switchman then:

  1. Expires the lease
  2. Releases all file claims held by that lease
  3. Requeues the task so another agent can pick it up

This happens automatically. You can trigger it manually:

switchman lease reap     # reap all stale leases
switchman status         # shows any stale work detected

The enforcement gateway

For the strongest conflict prevention, agents should write files through the Switchman gateway instead of directly:

# MCP tool — validates claim before writing
switchman_write_file

# CLI equivalent
switchman write <path> <content>

Related MCP tools include switchman_append_file, switchman_make_directory, switchman_move_path, and switchman_remove_path. The gateway checks that the agent has an active claim on the file before allowing the write. Direct file system writes are not blocked, but they are detected by the background monitor:

switchman monitor status    # check for rogue edits

Concurrency model

Switchman uses SQLite with WAL mode and BEGIN IMMEDIATE transactions. The file claims table has a partial unique index on (file_path, status='active'). This means: