Skip to content

Repository files navigation

Pairlane

Languages: English · 简体中文

Copy-only exact-file sync for an operator laptop and an agent host, over object storage.

Deletes never propagate. Local delivery is not cloud backup.

Pairlane is a protocol and a reference daemon. It is not a Dropbox replacement, not a pip standard library, and not rclone bisync.

Who this is for

Run the agent on a 24/7 overseas VPS. Keep a live, editable workspace on your laptop.

Agent traffic -- model APIs, browsers, downloads, retries -- stays on the machine with cheap unmetered egress. Your home network only pays for workspace files you actually need locally. This has been production-proven on our own Linux VPS pair (including an xAI Grok Bot cloud computer) with a Windows workstation. That is a self-owned deployment, not an xAI product.

The unit of deployment is a pair: one operator workspace and one agent host. That is the topology we run and document. It is not a two-device product limit. A second agent host is another pair with its own work tree, control plane, and object-storage namespace. We run two such pairs in production. A later revision can name more than two roles on one tree; v0.1 does not claim that mesh.

Invariants

  1. Exact-file events. A watcher publishes one immutable JSON event per completed file or directory. There is no whole-tree listing and no --resync.
  2. Copy-only. The protocol has put and mkdir. There is no delete operation. Deletes never travel.
  3. Hash OCC. A receiver replaces a destination only if it is missing, already identical, or still matches the event's base_sha256. Concurrent edits become .sync-conflict-<source>-<event> siblings, never silent winners.
  4. LOCAL_VERIFIED is not CLOUD_VERIFIED. Bytes arriving on the peer are not the same receipt as a verified object-store copy.
  5. Control plane != payload plane. JSON events travel on a control channel (persistent SSH and/or a JSON-only Syncthing folder). File bytes travel through an object-store adapter.

Two transports

On a high-RTT laptop-to-VPS path, bulk bytes should not ride SSH. In our production pair (mainland laptop to an overseas VPS, measured 2026-09 over the overlay we actually use), scp sat at about 70-80 KB/s at ~260 ms RTT. That is fine for JSON and files <=64 KiB. Multi-megabyte images and video go through object storage instead.

Lane What it carries
Control JSON Immutable events, ACKs, conflict receipts
Small files (optional, <=64 KiB) Persistent SSH snapshot; cloud object verified later
Large files Object store via rclone copyfile, not bisync / sync

Runtime dependency: rclone (MIT). Pairlane calls a user-installed binary (rclone rcd + operations/copyfile). This repo does not vendor rclone, does not wrap bisync, and does not copy rclone source.

Syncthing, if used, is also an external program. Point it only at the JSON control folder, never at the work tree.

Not this project

  • Whole-disk mirroring or Git
  • Propagating deletes, or treating sync as backup
  • A GUI, a consumer cloud drive, or a one-click VPN
  • Mutagen-style whole-tree SSH sync
  • rclone bisync / OpenClaw mailbox-or-bisync plugins
  • Same-tree N-way editing in v0.1 (pairs scale out; a third writer on one relative path is not a v0.1 promise)

Install

Python 3.11+. Watchdog is required only for serve.

python -m pip install "git+https://github.com/MerryEcho/pairlane.git"
python -m pip install "git+https://github.com/MerryEcho/pairlane.git[serve]"

From a checkout:

python -m pip install -e ".[serve]"
python -m unittest discover -s tests -v

CLI language: pairlane --lang zh-CN --help, or set PAIRLANE_LANG=zh-CN. Protocol JSON field names stay English.

Agents: read AGENTS.md (Chinese: AGENTS.zh-CN.md) and run the local-store demo there before touching rclone or SSH.

Minimal demo (no rclone, no SSH)

Two hosts, one directory as a fake object store:

python examples/local_demo.py

That publishes hello.txt from laptop and consumes it on agent using --transport local.

Production shape

Each host runs pairlane serve with:

  • --host / --peer -- opaque ids, not OS names
  • --work-root -- the editable workspace
  • --control-root -- JSON events only
  • --state-file -- host-local version state, outside the control folder
  • --include / --include-file -- explicit allowlist
  • --transport rclone --rclone-remote <name> -- your already-configured remote
  • optional --rclone-rc-url http://127.0.0.1:5572 -- persistent rclone daemon
  • optional --fast-port + --small-file-limit -- SSH lanes

OAuth, rclone.conf, Syncthing keys, and SSH identities stay on the host. They never enter Git, events, or logs.

See docs/PROTOCOL.md and docs/DESIGN.md. Chinese: docs/PROTOCOL.zh-CN.md, docs/DESIGN.zh-CN.md.

Related tools

rclone bisync, Mutagen, Syncthing, Unison, OpenClaw workspace-sync, and syncrclone all move files between machines. None of them combine copy-only exact-file events, hash OCC, LOCAL != CLOUD, and a split control/payload plane. Pairlane is a niche protocol with a reference daemon, not a claim to replace those tools.

License

MIT. rclone remains a separate MIT program that you install yourself.

About

Copy-only exact-file sync for a laptop and an agent host over object storage. Deletes never propagate.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages