MUT Concurrency Model
PuppyOne uses the MUT (Mutation) engine to handle concurrent writes safely, using optimistic concurrency control and three-way merge.
How it works
Instead of explicit checkout/commit locks, PuppyOne's MUT engine provides concurrency control through base version tracking and three-way merge on push. This is an optimistic approach: multiple actors can write freely, and conflicts are detected and resolved at write time.
Agent A PuppyOne Agent B
│ │ │
├── read file (gets v3) ────────▶│ │
│ │ ├── read file (gets v3)
│ (edit locally) │ │ (edit locally)
│ │ │
├── write (base_version=3) ─────▶│ │
│ │── accept, create v4 │
│◀── success (v4) ──────────────│ │
│ │ │
│ │ ├── write (base_version=3)
│ │── detect conflict (base=3, current=4)
│ │── attempt three-way merge
│ │◀── merge result or conflict ──┤Writing with optimistic concurrency
When writing through the Content API, you can include a base_version to enable conflict detection:
API
# Write with base_version for optimistic concurrency
curl -X POST "https://api.puppyone.ai/api/v1/content/{project_id}/write" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{
"path": "/specs/api-design.md",
"content": "# API Design\n\nUpdated authentication endpoint documentation",
"base_version": 3,
"message": "Updated auth endpoint docs"
}'If the file has been modified since version 3, the MUT engine will:
- Detect the version mismatch — the current version is newer than the base version
- Attempt three-way merge — compare the base (v3), current version, and the incoming changes
- Return the result — either a successful merge or conflict details requiring resolution
Without base_version
If you omit base_version, the write uses last-write-wins semantics — it overwrites the current content directly. The previous version is preserved in commit history.
Three-way merge during push
The MUT engine's three-way merge compares three versions:
Base version (v3)
┌──────┴──────┐
│ │
Current (v4) Incoming write
(Agent A) (Agent B)
│ │
└──────┬──────┘
│
Merged result (v5)- If the two actors changed different parts of the file, the merge succeeds automatically
- If both actors changed the same part, a conflict is returned for resolution
Handling merge conflicts
When a conflict cannot be auto-resolved, the API returns conflict details:
{
"status": "conflict",
"base_version": 3,
"current_version": 4,
"conflicts": [
{
"path": "/price",
"base_value": 99,
"current_value": 89,
"incoming_value": 79
}
]
}You can resolve by:
- Keeping the current version — discard your changes
- Force overwriting — resubmit without
base_versionto use last-write-wins - Manual merge — combine both changes and submit a new write with the latest
base_version
Filesystem sync (MUT protocol)
For bidirectional local folder sync, the MUT protocol handles concurrency at the protocol level:
- Clone — download the current state of the project
- Push — upload local changes; three-way merge is applied automatically
- Pull — fetch remote changes since the last sync
- Negotiate — exchange state to determine what needs syncing
The sync daemon uses this protocol transparently. Conflicts during push are resolved using the same three-way merge logic.
Notes
- No explicit locks — the system uses optimistic concurrency, not pessimistic locking
- Automatic versioning — every successful write creates a new commit in
mut_commits - Full history — even overwritten content is preserved and can be rolled back
- Audit trail — every write operation is recorded in the audit log
Next steps
- Conflict Resolution Strategies - Learn about three-way merge and last-write-wins in detail
- Audit Log - Trace all operations
- Version Control - View and restore historical versions