Skip to content

Import and Synchronization

We define import as the process of taking assets from an external source (a camera, a directory on the filesystem) and bringing them into Capsule’s management. Once imported, assets travel between devices via the upload protocol (client → server) and the sync feed (server → client).

The three concerns live in separate sub-docs because they correspond to distinct modules that can be implemented and validated independently:

Sub-docConcernPrimary crate(s)
PipelineLocal scan, plan, execute — the import workflow on a single devicecapsule-core::import
Upload ProtocolThe TUS-like wire protocol between client and server, session lifecycle, finalization, reliabilitycapsule-sdk::upload (client) + capsule-api-upload (server)
Download & SyncSync feed, tiered fetch, stale-revival defense, auto-synccapsule-sdk (client) + capsule-api-sync (server)

Encrypted backups are a separate artifact format; peering reuses the backup artifact for device-to-device sync rather than the upload/sync protocols.

[Local source]
▼ scan, extract metadata
[Pipeline] ── plan ──▶ user confirms
▼ encrypt + sign + generate derivatives
[Upload Protocol] ── session → chunks → finalize ──▶ server blob store + Postgres
▼ sync feed advances
[Download & Sync] ── /sync (metadata) → /blob/{hash} (lazy original) ──▶ peer devices

Every stage is content-addressed, idempotent, and resumable. Session state in the upload path and cursor state in the sync feed are the two pieces of mutable cross-module state; both are owned by their respective sub-docs.