Skip to main content

File Reservations

Advisory locks prevent merge conflicts. Agents reserve files before editing, others see what’s reserved and work elsewhere.
Like “caution tape” at a construction site — respectful coordination, not enforcement.

Quick Start

Reserve before editing:
// Agent wants to edit file
reserve_file_paths({
  file_patterns: ["src/components/UserProfile.tsx"],
  reservation_type: "exclusive",
  duration_minutes: 30
})
Check who has what:
list_file_reservations({})
// Shows: GreenCastle reserved UserProfile.tsx (expires in 25 min)
Release when done:
release_file_paths({
  file_patterns: ["src/components/UserProfile.tsx"]
})

How It Works

Without Reservations:
2:00 PM → Agent A edits UserProfile.tsx
2:05 PM → Agent B edits UserProfile.tsx
Result: Merge conflict 💥
With Reservations:
2:00 PM → Agent A reserves UserProfile.tsx
2:05 PM → Agent B tries to reserve → Blocked
2:05 PM → Agent B works on different file
2:20 PM → Agent A releases
2:21 PM → Agent B reserves → Success ✅

Reservation Types

  • Exclusive
  • Shared
One agent, full controlUse for: Writing code, modifying files, refactoring
reserve_file_paths({
  file_patterns: ["src/auth/AuthService.php"],
  reservation_type: "exclusive"
})
Behavior:
  • Only 1 agent can hold exclusive reservation
  • Blocks all other reservations (exclusive and shared)
  • Agent can read and write
Example:
Agent A: Reserve auth.php (exclusive) ✅
Agent B: Reserve auth.php (exclusive) ❌ Blocked
Agent C: Reserve auth.php (shared) ❌ Blocked

Glob Patterns

Reserve multiple files at once:

Directory

All files in directory
"src/features/auth/*"
Reserves all files in auth folder (one level)

Recursive

All files recursively
"src/features/auth/**/*"
Reserves all files in auth folder and subfolders

File Type

All TypeScript files
"src/components/**/*.tsx"
Reserves all .tsx files in components

Multiple Types

Multiple extensions
"src/components/**/*.{tsx,ts}"
Reserves both .tsx and .ts files
Common Patterns:
"src/auth/*"                    // One directory level
"src/auth/**/*"                 // Recursive
"**/*.tsx"                      // All .tsx anywhere
"src/**/*.{tsx,ts}"             // Multiple types
"!src/components/test/**"       // Exclude tests

Managing Reservations

  • List Active
  • Check Specific File
  • Extend
  • Release
See all reservations:
list_file_reservations({})
Returns:
📋 Active Reservations (5)

1. src/components/UserProfile.tsx
   - Agent: GreenCastle
   - Type: exclusive
   - Expires: 25 minutes
   - Reason: Implementing export

2. src/types/User.ts
   - Agents: SwiftEagle, BoldMountain
   - Type: shared
   - Expires: 15 minutes

3. src/services/AuthService.ts
   - Agent: ClearRiver
   - Type: exclusive
   - Expires: 5 minutes

Conflict Detection

ULPI prevents conflicts automatically:
  • Exclusive vs. Exclusive
  • Exclusive vs. Shared
  • Shared vs. Exclusive
  • Shared vs. Shared
Agent A: Reserve file.ts (exclusive) ✅
Agent B: Reserve file.ts (exclusive) ❌

Error: File already reserved by Agent A
Expires in: 25 minutes
Resolution:
  • Wait for expiration
  • Message Agent A to ask status
  • Work on different file

Glob Pattern Conflicts

Patterns can overlap:
// Agent A reserves directory
Agent A: Reserve "src/components/*" (exclusive)

// Agent B tries specific file
Agent B: Reserve "src/components/UserProfile.tsx" (exclusive)
Result: ❌ Conflict (file matches Agent A's pattern)
// Agent A reserves all TypeScript
Agent A: Reserve "src/**/*.tsx" (exclusive)

// Agent B tries components only
Agent B: Reserve "src/components/*.tsx" (exclusive)
Result: ❌ Conflict (patterns overlap)
// Different directories
Agent A: Reserve "src/features/auth/*" (exclusive)
Agent B: Reserve "src/features/profile/*" (exclusive)
Result: ✅ No conflict

Common Patterns

Pattern: Check → Reserve → Edit → Release
// 1. Check availability
check_file_reservations({
  file_patterns: ["src/components/UserProfile.tsx"]
})

// 2. Reserve (if available)
reserve_file_paths({
  file_patterns: ["src/components/UserProfile.tsx"],
  reservation_type: "exclusive",
  reason: "Implementing export button"
})

// 3. Edit the file
[Make changes]

// 4. Release
release_file_paths({
  file_patterns: ["src/components/UserProfile.tsx"]
})
Duration: 10-20 minutes for simple changes
Pattern: Reserve all files together, work, release all
// Reserve everything needed
reserve_file_paths({
  file_patterns: [
    "src/components/UserProfile.tsx",
    "src/components/UserAvatar.tsx",
    "src/styles/profile.css"
  ],
  reservation_type: "exclusive",
  reason: "User profile export feature",
  duration_minutes: 60
})

// Work on all files
[Implement feature across all files]

// Test
[Run tests]

// Release all
release_file_paths({
  file_patterns: [
    "src/components/UserProfile.tsx",
    "src/components/UserAvatar.tsx",
    "src/styles/profile.css"
  ]
})
Duration: 30-60 minutes for feature work
Pattern: Reserve entire module with glob pattern
// Reserve entire auth module
reserve_file_paths({
  file_patterns: ["src/features/auth/**/*"],
  reservation_type: "exclusive",
  reason: "Refactoring authentication flow",
  duration_minutes: 120
})

// Message other agents
send_message({
  recipient_ids: [],  // Broadcast
  subject: "Auth Module Refactor",
  body: "Refactoring auth module for 2 hours. Reserved all auth files."
})

// Perform refactor
[Refactor across multiple files]

// Release
release_file_paths({
  file_patterns: ["src/features/auth/**/*"]
})
Duration: 1-2 hours for module refactorsWhy broadcast: Let everyone know you’re doing big changes
Pattern: Shared reservation for reading
// Reserve for reading
reserve_file_paths({
  file_patterns: [
    "src/types/User.ts",
    "src/types/Auth.ts"
  ],
  reservation_type: "shared",
  reason: "Reviewing type definitions",
  duration_minutes: 15
})

// Read files for context
[Review code, understand types]

// Release when done reading
release_file_paths({
  file_patterns: [
    "src/types/User.ts",
    "src/types/Auth.ts"
  ]
})
Duration: 10-15 minutes for reviewWhy shared: Multiple agents can review simultaneously
Pattern: File reserved? Work on something else
// Try to reserve
check_file_reservations({
  file_patterns: ["src/components/UserProfile.tsx"]
})

// Response: Reserved by GreenCastle, expires in 15 min

// Option 1: Message GreenCastle
send_message({
  recipient_ids: [GreenCastle_ID],
  subject: "UserProfile.tsx status?",
  body: "Are you still working on UserProfile.tsx? I need to edit it for export feature."
})

// Option 2: Work on different file
reserve_file_paths({
  file_patterns: ["src/components/UserAvatar.tsx"],
  reservation_type: "exclusive",
  reason: "Work on avatar while waiting for UserProfile"
})

// Option 3: Wait for expiration (15 min)
[Wait 15 minutes, then try again]

Best Practices

Always Check First

Before editing, check reservations✅ Check → Reserve → Edit → Release❌ Edit → Conflict → Fix merge issuesWhy: Prevents conflicts before they happen

Reserve Together

Reserve all related files at once✅ Reserve [A, B, C] → Edit all → Release all❌ Reserve A → Edit A → Reserve B → Edit BWhy: Atomic operations, clearer intent

Release Promptly

Don’t hold longer than needed✅ Reserve → Work → Release (15 min)❌ Reserve → Break → Lunch → Work (2 hours)Why: Unblocks other agents

Communicate Large Changes

Broadcast before big refactors✅ Message team → Reserve module → Refactor❌ Reserve silently → Surprise everyoneWhy: Sets expectations, enables planning

Use Specific Patterns

Avoid over-reserving with globssrc/features/auth/**/*.ts (just auth)**/*.ts (entire codebase!)Why: Better resource sharing

Choose Right Type

Exclusive for writing, shared for reading✅ Editing? Use exclusive✅ Reviewing? Use sharedWhy: Correct semantics enable coordination

Human Oversight

Human Overseers have special powers:

Force Release

When agents crash or take too long:
// Human can force release any reservation
force_release_file_paths({
  agent_id: "crashed_agent_id",
  file_patterns: ["src/components/UserProfile.tsx"],
  reason: "Agent crashed, unblocking file"
})
Use cases:
  • Agent crashed without releasing
  • Emergency requires immediate access
  • Agent taking excessively long

View All Reservations

Dashboard shows:
  • All active reservations across agents
  • Expiration times
  • Reservation reasons
  • Quick actions (extend, force release)

Extend Reservations

Extend any agent’s reservation:
extend_file_reservations({
  agent_id: "other_agent_id",
  file_patterns: ["src/components/UserProfile.tsx"],
  additional_minutes: 60,
  reason: "Complex refactor legitimately needs more time"
})

Automatic Expiration

Reservations expire automatically: Default TTL: 30 minutes Lifecycle:
2:00 PM → Reserve (expires 2:30 PM)
2:25 PM → Should extend if still working
2:30 PM → Auto-expires
2:31 PM → File available again
Why auto-expiration:
  • Prevents deadlock if agent crashes
  • Unblocks files automatically
  • No manual cleanup needed
  • Safety net for coordination
If you need longer:
// Extend before expiration
extend_file_reservations({
  file_patterns: ["src/components/UserProfile.tsx"],
  additional_minutes: 30  // Now expires in 60 min total
})

Troubleshooting

Cause: Another agent holds reservationCheck who:
check_file_reservations({
  file_patterns: ["src/components/UserProfile.tsx"]
})
// Shows: GreenCastle, expires in 15 min
Solutions:
  1. Message GreenCastle to ask status
  2. Wait 15 minutes for expiration
  3. Work on different file
  4. Ask Human Overseer for force release (if urgent)
Cause: Didn’t extend before 30-minute TTLSolution:
// Re-reserve immediately
reserve_file_paths({
  file_patterns: ["src/components/UserProfile.tsx"],
  reservation_type: "exclusive"
})
Prevention:
  • Extend before expiration for long tasks
  • Set reminders at 25-minute mark
Cause: Incorrect pattern syntaxTest pattern:
list_file_reservations({
  file_pattern: "src/components/*.tsx"
})
// See what files match
Common mistakes:
  • Missing ** for recursive: src/components/**/*.tsx
  • Wrong base path
  • Incorrect exclude pattern
Cause: Shared reservations block exclusive (expected)Check who has shared locks:
check_file_reservations({
  file_patterns: ["src/types/User.ts"]
})
// Shows: SwiftEagle, BoldMountain (shared)
Solutions:
  1. Wait for shared locks to expire
  2. Message agents to ask if they’re done reading
  3. If you only need to read, request shared instead

MCP Tools Reference

Reserve files:
reserve_file_paths({
  file_patterns: ["src/file.ts", "src/**/*.tsx"],
  reservation_type: "exclusive" | "shared",
  duration_minutes: 30,
  reason: "Why you need this"
})
Check reservations:
check_file_reservations({
  file_patterns: ["src/file.ts"]
})
List all reservations:
list_file_reservations({})
Extend reservation:
extend_file_reservations({
  file_patterns: ["src/file.ts"],
  additional_minutes: 30
})
Release files:
release_file_paths({
  file_patterns: ["src/file.ts"]
})

// Or release all
release_all_file_paths({})
Full API Reference →

Next Steps


Advisory locks prevent conflicts without blocking humans. It’s coordination, not enforcement.