newdrive/docs/adr/0008-sync-capable-server-contract.md
Elijah 099c53badf
All checks were successful
CI / Backend (push) Successful in 26s
CI / Frontend (push) Successful in 11s
CI / Contracts and repository policy (push) Successful in 4s
CI / Container (push) Successful in 27s
Update architecture baseline for sync, sharing, and gateways
2026-07-16 18:40:12 -07:00

4 KiB

ADR-0008: Sync-capable server contract

Status: Accepted

Context

The desktop client is deferred, but the stable-v1 API must support a client that maintains a local replica without missing concurrent mutations or silently overwriting a newer revision. The previous plan named a change feed and one-way mirror but did not define a consistent initial baseline, delivery semantics, mutation attribution, or the difference between content and metadata changes.

Decision

Drive's REST API and application services are the canonical server interface. The server exposes neutral read, mutation, transfer, and change primitives; sync direction, deletion propagation, local filesystem policy, and three-way reconciliation remain client concerns.

Baseline and changes

  1. A client obtains opaque start cursor C0.
  2. It recursively enumerates a selected root using stable node and parent IDs with keyset pagination.
  3. It replays changes after C0 until caught up.
  4. It persists the cursor after the final event it has applied.

Enumeration and replay may contain duplicate observations but must not miss a committed mutation while the start cursor remains retained. No long-running PostgreSQL snapshot is held.

The change feed is ordered by a monotonic sequence and consumers treat delivery as at least once. A page cursor represents the position after its final event. Each versioned event stores either an immutable resulting-node snapshot or a deletion tombstone, node and content revisions, subtree effect, origin information, and useful previous-location diagnostics. Cursor expiry returns 410 Gone with stable code change_cursor_expired and requires rebaseline without discarding pending local work.

Subtree-scoped credentials consume an authorization-safe projection of the global sequence. A move into the granted root is represented by current state, a move out is represented as a tombstone/removal, and unrelated events are omitted while the cursor advances. Recursive baseline and replay use the same root anchor and visibility rules, so a restricted client can maintain its authorized replica without learning metadata outside it.

Identity, revisions, and idempotency

  • Node revision increments for any meaningful mutation. Content revision increments only when committed file content changes.
  • SHA-256 identifies committed content. Logical content_modified_at may preserve an authenticated client value; server metadata_updated_at records the latest mutation. Timestamps never decide conflicts.
  • Authenticated client instances may bind to API tokens and are independently revocable. Application services receive a protocol-neutral mutation context for actor, credential, client, operation, idempotency, and request IDs.
  • Idempotency records persist the authenticated scope, key, request fingerprint, operation, state, result reference, and expiry. Identical retries return the original result; a different fingerprint with the same key fails.

Capabilities and transfers

GET /api/v1/capabilities reports protocol compatibility and supported behavior rather than requiring consumers to infer it from a software version.

Upload creation may accept declared size, SHA-256, logical content mtime, target/precondition, and origin. After authorization, the server may avoid transfer or attach an already verified owner blob through the normal commit service. New content is always server-hashed and verified.

Hash preflight is target-scoped and must not reveal whether matching content exists outside the credential's authorized view. The server may conceal whether internal deduplication occurred.

Consequences

  • Phase 1 owns the supporting schema and mutation context; Phase 2 owns the functional baseline, changes, capabilities, and conformance mirror.
  • Web, importer, OnlyOffice, future desktop/rclone clients, and protocol gateways produce attributed events through the same application services.
  • Client sync modes, SQLite schema, watcher behavior, local conflict copies, and provider adapters are deliberately deferred to the desktop-client design.