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
One agent, full control Use for: Writing code, modifying files, refactoringreserve_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
Multiple agents, read-only Use for: Code review, reading context, documentationreserve_file_paths ({
file_patterns: [ "src/types/User.ts" ],
reservation_type: "shared"
})
Behavior:
Multiple agents can hold shared reservations
Blocks exclusive reservations
Agents commit to read-only
Example: Agent A: Reserve types.ts (shared) ✅
Agent B: Reserve types.ts (shared) ✅
Agent C: Reserve types.ts (shared) ✅
Agent D: Reserve types.ts (exclusive) ❌ Blocked
Glob Patterns
Reserve multiple files at once:
Directory All files in directory Reserves all files in auth folder (one level)
Recursive All files recursively 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
Before editing, check: check_file_reservations ({
file_patterns: [ "src/components/UserProfile.tsx" ]
})
If reserved: ⚠️ Reserved by GreenCastle
- Type: exclusive
- Expires: 25 minutes
- Reason: Implementing export
💡 Wait for expiration or message GreenCastle
If not reserved: ✅ Available
You can reserve it now
Extend expiration: extend_file_reservations ({
file_patterns: [ "src/components/UserProfile.tsx" ],
additional_minutes: 30
})
When to extend:
Work taking longer than expected
Complex refactoring
Waiting for input
Testing requires more time
Release when done: // Release specific file
release_file_paths ({
file_patterns: [ "src/components/UserProfile.tsx" ]
})
// Release all your reservations
release_all_file_paths ({})
Why release promptly:
Unblocks other agents
Good coordination etiquette
Prevents unnecessary waiting
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
Agent A: Reserve file.ts (exclusive) ✅
Agent B: Reserve file.ts (shared) ❌
Error: Exclusive lock held by Agent A
Why blocked:
Exclusive lock means Agent A is writing, can’t allow readersAgent A: Reserve file.ts (shared) ✅
Agent B: Reserve file.ts (shared) ✅
Agent C: Reserve file.ts (exclusive) ❌
Error: 2 shared locks active
Why blocked:
Shared locks mean agents are reading, can’t allow writerAgent A: Reserve file.ts (shared) ✅
Agent B: Reserve file.ts (shared) ✅
Agent C: Reserve file.ts (shared) ✅
No conflict - multiple readers allowed
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
Blocked File - Wait Strategy
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 issues Why: 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 B Why: 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 everyone Why: Sets expectations, enables planning
Use Specific Patterns Avoid over-reserving with globs ✅ src/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 shared Why: 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
Can't reserve - already reserved
Cause: Another agent holds reservationCheck who: check_file_reservations ({
file_patterns: [ "src/components/UserProfile.tsx" ]
})
// Shows: GreenCastle, expires in 15 min
Solutions:
Message GreenCastle to ask status
Wait 15 minutes for expiration
Work on different file
Ask Human Overseer for force release (if urgent)
Reservation expired while working
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
Glob pattern not matching files
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
Shared reservation blocking me
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:
Wait for shared locks to expire
Message agents to ask if they’re done reading
If you only need to read, request shared instead
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.