Files
cairnquire/.project/adrs/adr-002-sync-protocol.md

2.7 KiB

ADR-002: SimpleSync Protocol

Status

Accepted

Context

Users need to edit markdown files on their local filesystem (using any editor) and have changes reflected on the web automatically. Multiple users should be able to work on different files simultaneously without conflicts. We need a sync mechanism simpler than git but robust enough for production use.

Decision

Implement SimpleSync: a content-addressed, Merkle-tree-inspired sync protocol over WebSocket with the following characteristics:

  1. Content-addressed storage: All files identified by SHA-256 hash
  2. File-level granularity: Parallel editing of different files is conflict-free
  3. Automatic sync: File watcher detects changes and pushes to server
  4. Three-way merge: Only when same file edited concurrently
  5. No branches/commits: Just current state + history log

Protocol Flow

Client → Server: Sync Request

{
  "type": "sync_request",
  "client_root_hash": "abc123...",
  "client_files": {
    "getting-started.md": "hash1",
    "api-reference.md": "hash2"
  }
}

Server → Client: Sync Response

{
  "type": "sync_response",
  "server_root_hash": "def456...",
  "missing_from_client": ["hash3", "hash4"],
  "missing_from_server": ["hash5"],
  "conflicts": ["getting-started.md"]
}

Content Transfer

Files transferred by hash: GET /content/{hash} or WebSocket binary frames

Consequences

Positive

  • Dramatically simpler mental model than git
  • Automatic — no user commands needed
  • Works with any text editor
  • Immutable file store provides natural deduplication
  • Easy to implement offline queue: just store hashes and content

Negative

  • No offline branching (by design)
  • Conflict resolution UI must be built
  • No rebase/squash history manipulation (intentional simplicity)
  • Large binary files could bloat content store (mitigated by size limits)

Alternatives Considered

Git-based sync

  • Pros: Mature, well-understood, existing tools
  • Cons: Requires git on client, complex merge UX, repo-level locking
  • Rejected: Too complex for notes; overkill for target use case

CRDTs (Yjs, Automerge)

  • Pros: Real-time collaborative editing, automatic conflict resolution
  • Cons: Complex to implement correctly, memory overhead, designed for real-time not async
  • Rejected: Requirement is async-only; CRDTs are overkill

rsync / Unison

  • Pros: Battle-tested file sync
  • Cons: No concept of "versions" or "comments", no web integration
  • Rejected: Doesn't meet collaboration requirements

References