Overview

Memento Cloud Sync lets you push and pull observations between your local database and the cloud. This enables team collaboration and cross-device memory.

┌──────────┐     push      ┌──────────┐
│  Local   │ ─────────────▶│  Cloud   │
│  DB      │ ◀─────────────│  Server  │
└──────────┘     pull      └──────────┘
                                  │
                          ┌───────┴───────┐
                          │               │
                     ┌────▼────┐   ┌──────▼──┐
                     │ Team    │   │ Team    │
                     │ Member  │   │ Member  │
                     │ A       │   │ B       │
                     └─────────┘   └─────────┘

Commands

Push

Upload local observations to the cloud.

memento sync push
memento sync push --project my-app

Behavior:

  1. Query local observations newer than last sync cursor
  2. Send batch to cloud server
  3. Server returns new cursor
  4. Update local sync metadata

Pull

Download cloud observations to local database.

memento sync pull
memento sync pull --project my-app

Behavior:

  1. Send local cursor to cloud server
  2. Server returns observations newer than cursor
  3. Merge into local database (dedup by topic_key + content hash)
  4. Update local cursor

Cursor-Based Sync

Each sync operation uses a cursor — a timestamp or sequence number that tracks the last successful sync.

Local Cursor: 2025-01-15T10:30:00Z

Push: Send all observations where updated_at > cursor
Pull: Receive all observations where updated_at > server_cursor

Cursor Storage

{
  "project_id": "my-app",
  "last_push": "2025-01-15T10:30:00Z",
  "last_pull": "2025-01-15T09:45:00Z",
  "push_count": 42,
  "pull_count": 38
}

Conflict Resolution

When the same observation is modified locally and remotely:

Strategy Behavior
Last Write Wins Newer updated_at takes precedence
Merge Combine non-overlapping fields
Manual Both versions preserved, user decides

Default: Last Write Wins. You can configure per-project.

Deduplication

During pull, Memento deduplicates observations using:

  1. Exact match: Same topic_key + content hash → skip
  2. Similarity match: Jaccard similarity > 0.85 → auto-merge
  3. No match: Insert as new observation

Data Flow

1. memento sync push
   ├── Read local observations (updated_at > cursor)
   ├── POST /api/sync/push { observations, cursor }
   ├── Server: save + broadcast to team
   └── Update local cursor

2. memento sync pull
   ├── POST /api/sync/pull { cursor }
   ├── Server: return newer observations
   ├── Dedup + merge into local DB
   └── Update local cursor

API Endpoints

Push

POST /api/sync/push
{
  "cursor": "2025-01-15T10:30:00Z",
  "observations": [
    { "id": 42, "title": "...", "type": "decision", "content": "..." }
  ]
}

Response:

{
  "cursor": "2025-01-15T11:00:00Z",
  "synced": 5,
  "conflicts": 0
}

Pull

POST /api/sync/pull
{
  "cursor": "2025-01-15T09:45:00Z",
  "project_id": "my-app"
}

Response:

{
  "cursor": "2025-01-15T11:00:00Z",
  "observations": [...],
  "has_more": false
}

Configuration

Sync settings in .memento/config.json:

{
  "sync": {
    "enabled": true,
    "server_url": "https://api.memento.dev",
    "conflict_strategy": "last_write_wins",
    "auto_pull": true,
    "pull_interval_seconds": 300
  }
}