Memory

Memory Branching

Memory branching gives you a git-style fork, diff, and merge workflow for the entire memory state. Create parallel branches to explore different contexts, run experiments, or isolate changes — without touching the main memory state. When you are ready, merge branches back using CRDT-inspired conflict-free resolution.

How it works

Branching operates in three phases:

  1. Fork — A new branch is created as a copy-on-write snapshot of the current memory state. No data is duplicated until a write is made to the branch.
  2. Diverge — Writes made in the branch are isolated to that branch. The main branch continues to evolve independently. Both branches track their own commit history.
  3. Merge — When the branch is ready, its changes are merged back into the target branch. Non-conflicting changes are applied automatically. Conflicts are resolved using the configured merge strategy.

API

Create a branch

bash
POST /memory/branch
{
  "name": "experiment-new-persona",
  "description": "Testing a revised user profile model"
}

# Response:
# { "branchId": "branch_abc123", "baseBranch": "main", "createdAt": "2026-02-25T10:00:00Z" }

List branches

bash
GET /memory/branches

# Response:
# [
#   { "id": "main", "commits": 142, "createdAt": "..." },
#   { "id": "branch_abc123", "name": "experiment-new-persona", "divergedAt": "..." }
# ]

Merge a branch

bash
POST /memory/merge
{
  "source": "branch_abc123",
  "target": "main",
  "strategy": "crdt-auto"
}

Diff between branches

Before merging, inspect the diff to see exactly what changed between two branches across all memory tiers:

bash
GET /memory/branches/branch_abc123/diff/main

# Response:
# {
#   "added": [ { "tier": 3, "key": "domains.persona", "value": "..." } ],
#   "modified": [ { "tier": 2, "key": "note_xyz", "before": "...", "after": "..." } ],
#   "removed": []
# }

The diff is scoped to entries that diverged after the branch point. Entries that were modified on both branches simultaneously are flagged as conflicts in the diff output.

Merge strategies

StrategyBehavior
crdt-autoApplies CRDT-inspired last-write-wins semantics with vector clock ordering. All non-conflicting changes are merged automatically. Recommended for most use cases.
interactivePauses the merge when a conflict is detected and surfaces a resolution prompt via GET /memory/merge/:mergeId/conflicts. Each conflict must be resolved manually before the merge can complete.
source-winsThe source branch always wins conflicts. Use when you know the branch state is authoritative.
target-winsThe target branch always wins conflicts. Use when you want to incorporate only the non-conflicting additions from the source branch.
💡crdt-auto resolves the vast majority of real-world merges without any manual intervention. Only use interactive when the merged content will affect critical long-term memory entries like user profiles or architecture decisions.

Use cases

  • Scenario testing — Fork memory before running a speculative what-if analysis. If the results are useful, merge them back. If not, discard the branch.
  • User onboarding experiments — Run two variants of an onboarding flow in parallel branches, compare the resulting user profiles after N sessions, and promote the better-performing branch to main.
  • Safe refactoring — Restructure graph entities or profile keys in a branch without risking the live memory state. Validate the new shape, then merge.
  • Debugging — Reproduce an issue by forking the memory state at a known-good point and replaying events in a branch, leaving the production state untouched.