Skip to content

Synchronization Contract

Assertions

SYN-001 - Planning is a deterministic three-way comparison

Contract: Planning MUST classify complete base, local, and remote note and notebook state without I/O and produce a stable operation order. Local-only changes MUST push, remote-only changes MUST pull, equal concurrent changes MUST rebase, unequal concurrent changes MUST conflict, and malformed or duplicate local identity MUST be blocked.

Evidence:

SYN-002 - Dry-run never mutates either side

Contract: Pull, push, and sync dry-runs MUST stop after planning, report the exact pending operation list, return exit 1 when work exists, and leave local files, internal state, and Joplin unchanged.

Evidence:

SYN-003 - Deletion propagation is opt-in and recoverable

Contract: Local and remote deletions MUST be reported but not propagated by default. With --propagate-deletes, a local deletion MAY move a Joplin note to trash and a remote deletion MAY move the local file to quarantine. Sync MUST never request permanent note deletion. Delete-versus-edit MUST conflict.

Evidence:

SYN-004 - Divergence creates evidence without overwriting

Contract: Divergent edits MUST create one conflict bundle containing the available base, local, and remote representations plus metadata and hashes. Detection MUST leave both sides unchanged. Joplin's own conflict notes MUST be reported and skipped rather than synchronized.

Evidence:

SYN-005 - Conflict resolution is explicit and freshness-checked

Contract: Resolution MUST accept only take-local, take-remote, or a valid explicit merged file. Both sides MUST be re-read before any resolution write; changed evidence MUST produce concurrent-modification failure. Discard MUST remove only the bundle and MAY allow later redetection.

Evidence:

SYN-006 - Every operation guards, applies, verifies, then commits

Contract: Immediately before a write, the executor MUST re-read the affected source and compare it with planned state. Drift MUST abort that operation with exit 5 without overwriting either concurrent edit. The base snapshot MUST update only after the intended post-state is verified.

Evidence:

SYN-007 - Ambiguous remote writes are settled without blind replay

Contract: A timed-out write MUST NOT be replayed automatically. The executor MUST re-read remote state: an intended result counts as applied, an unchanged pre-state is a partial failure safe to rerun, and any third state is a concurrent modification.

Evidence:

SYN-008 - Locking and journals make interruption explicit

Contract: One exclusive cross-platform workspace lock MUST guard commands that inspect or mutate shared state. Every mutating run MUST persist its plan and per-operation status. An incomplete journal MUST block later mutations until recover classifies each operation from verifiable current state without replaying it.

Evidence:

SYN-009 - State corruption and schema drift fail closed

Contract: Missing, corrupt, unsupported-newer, or un-migratable state MUST fail as an invalid workspace rather than start from an empty base. Known older schemas MUST migrate through the ordered migration chain.

Evidence: