# Multi-machine ParallelClaw

> 🆕 **Update (v0.13):** настоящий двусторонний sync встроен и ставится **двумя
> copy-paste шагами**: агент на сервере выполняет `memex-sync sync-server install
> --bind 127.0.0.1` + `memex-sync sync-server invite --join`, ты на ноуте — одну
> команду `memex-sync sync-join <токен>`. Туннель (самовосстанавливающийся),
> расписание, watchdog и проверка петли ставятся автоматически; никаких
> публичных портов и ручных ключей. Полный гайд — [SYNC.md](SYNC.md),
> краткий — README → Cross-device.
>
> Паттерны A/B/C ниже — **DEPRECATED legacy-обходные пути** (file-sync с
> ограничением single-writer). Подходят только тем, кто сознательно не хочет
> включать sync-движок. Для всех новых установок — `sync-join`.

## Почему это сложно

memex — это локальный SQLite-файл (`~/.memex/data/memex.db`) который активно пишется (auto-capture daemon, MCP-сервер при импорте inbox). Если **два экземпляра memex** на разных машинах одновременно пишут в **один и тот же** SQLite-файл через filesystem-sync (Syncthing/Dropbox/iCloud), почти гарантированный исход — повреждение БД. SQLite WAL-mode безопасен только когда все процессы видят одну файловую систему, не когда файл синкается «снаружи».

Поэтому ниже — паттерны которые **обходят** проблему конкурентной записи, не решают её.

---

## Паттерн A — Hub + read-replicas (рекомендуется)

**Идея:** одна машина «hub» — основная (например рабочий ноут). Только на ней крутится daemon и memex MCP-сервер. Остальные машины получают **read-only копию** БД через любой filesystem-sync.

**Как настроить:**

На hub-машине (рабочий ноут):
```bash
npx memex-sync install        # как обычно
```

Подключи Syncthing / iCloud Drive / Dropbox / OneDrive только к **папке `~/.memex/data/`**, не к `~/.memex/inbox/`:
```
Source on hub:    ~/.memex/data/         (read-write)
Target on B/C/…:  ~/.memex/data/         (read-only)
```

На read-replica машинах:
- НЕ запускай `memex-sync install` (иначе будет конкурентная запись)
- Подключи memex как обычный MCP-сервер в Claude Code config
- Доступ к памяти полный read-only — `memex_search`, `memex_get_conversation`, `memex_overview` все работают

**Плюсы:** простая настройка, single-writer гарантирован, не нужны custom-скрипты.

**Минусы:** read-replica eventually consistent (latency 5-30 секунд в зависимости от sync-провайдера). Если сидишь на ноутбуке-replica и одновременно ведёшь сессию Claude Code — она НЕ попадёт в memex пока ты не вернёшься к hub. Для большинства пользователей это OK.

**Гочи:**
- На read-replica добавь `&mode=ro` в путь к БД если возможно — снижает риск случайной записи
- Не запускай `npx memex-sync install` на replica — проверь через `npx memex-sync status` что daemon **не** установлен
- Если ты редактируешь конфиг через MCP (например `memex_archive_conversation`) на replica — изменение **не** залетит обратно на hub

---

## Паттерн B — Per-machine independent + shared archive

**Идея:** каждая машина ведёт свою memex.db самостоятельно (свой daemon, свой MCP). Синкается только **архив исходных файлов** (`~/.memex/data/conversations/`). Когда хочешь чтобы machine B увидела сессии с machine A — кладёшь файлы из архива в её inbox.

**Как настроить:**

На обеих машинах:
```bash
npx memex-sync install
```

Sync через Syncthing/iCloud только папки:
```
~/.memex/data/conversations/    (bi-directional)
```

Когда хочешь импортировать чужую активность на текущую машину:
```bash
# скопировать все накопленные с другой машины JSONL в свой inbox
cp ~/.memex/data/conversations/claude-code/*.jsonl ~/.memex/inbox/
cp ~/.memex/data/conversations/claude-cowork/*.jsonl ~/.memex/inbox/
```

memex inbox-watcher подберёт их за секунды, дедуп через UNIQUE(msg_id) отсечёт уже виденные сообщения.

**Плюсы:** обе машины полностью функциональны независимо. Никаких read-only ограничений.

**Минусы:** ручной шаг «принести историю с другой машины». Возможно автоматизировать через cron, но это уже custom.

**Гочи:**
- НЕ синкай `~/.memex/data/memex.db` — каждая машина имеет свой
- НЕ синкай `~/.memex/inbox/` — race с inbox-watcher
- Важно — у нас сейчас daemon процессит ингест **в архив автоматически после import**. Так что после первого ингеста на A, файл попадает в `data/conversations/`, Syncthing-копирует его на B. На B этот файл **уже** в архиве — не нужно повторно его инжектить.

---

## Паттерн C — Single-master через rsync (для CLI-power-users)

**Идея:** не используем непрерывный sync вообще. По требованию делаем `rsync` всего `~/.memex/` с одной машины на другую. Single-master, никаких race-условий.

**Как настроить:**

```bash
# Из B "забрать" свежее состояние с A
rsync -av --delete user@hostA:.memex/ ~/.memex/

# Не забудь остановить daemon на B перед rsync если он установлен:
launchctl unload ~/Library/LaunchAgents/com.parallelclaw.memex.sync.plist

# После rsync — снова запусти, но осторожно: 
# state-файл daemon'а тоже синкается, теперь B будет считать что уже видел все источники A
```

**Плюсы:** простой mental model, никаких длительных процессов sync, явный контроль когда происходит обмен.

**Минусы:** ручной запуск, потенциальная проблема с offset state daemon'а (если на B раньше был свой daemon — его state перезаписывается).

---

## Сравнительная таблица

| | Паттерн A (Hub+replicas) | Паттерн B (Per-machine) | Паттерн C (rsync) |
|---|---|---|---|
| Свежесть данных | 5-30 сек lag | сразу после copy | по нажатию |
| Сложность настройки | низкая | средняя | низкая |
| Риск повреждения БД | нулевой (single-writer) | нулевой (отдельные БД) | нулевой |
| Работает offline | ✅ | ✅ | ✅ |
| Запись с любой машины | ❌ | ✅ | ❌ (single-master) |
| Custom-скрипты нужны | ❌ | да (cp в inbox) | да (rsync wrapper) |

---

## Что сделать **нельзя** (общие грабли)

- ❌ **Синкать `~/.memex/data/memex.db` между двумя машинами с активным daemon'ом** — гарантированное повреждение БД через несколько часов
- ❌ **Синкать `~/.memex/inbox/`** — chokidar-watcher на одной машине может удалить файл из inbox раньше чем sync долетит до второй, второй машина потеряет данные
- ❌ **Хранить БД на сетевой ФС (NFS/SMB) и работать с ней с двух машин одновременно** — SQLite WAL не дружит с network FS

---

## Что в roadmap

**v0.4 — Multi-device sync через CRDT.** Каждая машина хранит локальную копию + change-log. Синхронизация через любой transport (cloud relay, peer-to-peer, USB). Конфликтное состояние невозможно by-design. Это нетривиальная инженерная задача (~3-4 недели), но она в плане.

До v0.4 — пользуйся паттернами выше. Для большинства pro-юзеров **Паттерн A (Hub + read-replicas)** покрывает 90% потребностей.

---

## Помощь

Если у тебя нестандартный setup и непонятно как лучше — открой [issue](https://github.com/parallelclaw/memex-mvp/issues) с описанием:
- сколько у тебя машин
- какой sync-провайдер ты уже используешь (Syncthing / iCloud / git-annex / etc.)
- ОС каждой машины
- хочешь ли write-доступ с каждой или только с одной

Подскажем какой паттерн оптимален.
