Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Future Sync and Extension Platform

Sync model

The app owns the local source of truth and its full revision graph. This document is a future-design reference, not an initial-release feature specification. Release 1 ships no sync coordinator, destination adapter, connection settings, transfer queue, or plugin runtime. It preserves a small set of contracts and data boundaries so later work can introduce those components without breaking local data.

future workflow:
local edit -> transaction: current note + immutable revision + outbox event
                                                   |
                                             sync coordinator
                                                   |
                    +------------------------------+------------------------------+
                    |                                                             |
         history-aware destination                                      file/current-state destination
         can exchange revision graph                                    exchanges current .md + metadata

Placeholder contract for future destinations

Every future destination should declare a capability document rather than relying on its name or implementation type. These declarations may live as documentation/types in Release 1, but no adapter executes them.

CapabilityMeaning
remoteHistoryDestination stores and returns immutable revisions/parents
remoteTombstonesDestination can propagate deletions safely
stableItemIdsFiles/items keep a stable identity across rename/move
changeTokensDestination can provide incremental change discovery
atomicWriteDestination can commit an item without exposing partial content
backgroundSyncAdapter can operate under the platform’s background constraints
bidirectionalAdapter can both upload and import changes
conflictSignalsAdapter exposes version/ETag/precondition information

When implemented, the coordinator must use conservative behavior when a capability is unavailable. For example, a folder destination without remoteHistory must not claim remote version recovery, and a destination without conflictSignals should surface potentially concurrent changes instead of overwriting them optimistically.

Future adapter operations

The API should use domain-neutral values and avoid exposing database entities directly. A minimum contract includes:

  • describeCapabilities() — return the capability document and user-facing destination description.
  • authorize() / deauthorize() — obtain and remove access; secrets remain platform-owned.
  • discover(cursor) — list remote changes incrementally where supported, or perform a bounded scan.
  • fetch(item) — retrieve a current document or revision payload.
  • push(change, precondition) — write a change, with a remote version precondition when supported.
  • delete(item, precondition) — propagate tombstones when supported.
  • getStatus() — report connection health, last action, retryability, and user action needed.

Define transfer payload versions from the first implementation. Future apps must be able to recognize an unsupported payload and leave data intact rather than corrupting it.

Future sync lifecycle

  1. Local commit: save note and revision; enqueue an idempotent outbox event.
  2. Discovery: collect destination changes using a change token, version manifest, or constrained folder scan.
  3. Reconciliation: identify items using stable note IDs; compare revision parent/hash/version metadata.
  4. Apply: fast-forward safe remote changes or stage conflicts; never replace an unacknowledged local change.
  5. Upload: push queued local changes with preconditions when available.
  6. Acknowledge: update per-destination metadata only after the remote action succeeds.
  7. Report: expose pending count, last successful completion, meaningful warnings, and recovery actions.

Make operations idempotent. Sync may be interrupted, retried, or run concurrently by foreground and background scheduling.

Future Android local-folder sync extension

This is the planned first sync extension and should act as the reference implementation for the extension contract when that future phase begins.

User setup

  1. User selects a folder through Android’s Storage Access Framework.
  2. The app stores the persistable permission URI and validates read/write access.
  3. The extension writes a small app manifest (for example .notes-app-manifest.json) in the selected root to identify its managed layout and format version.
  4. The user is told that the folder preserves current Markdown notes, not the app’s complete revision history.

File behavior

  • Export every current, non-deleted note as deterministic .md with portable front matter.
  • Do not modify files outside the extension’s managed directory/layout.
  • Write via a temporary file plus replace/rename if the selected provider supports it; otherwise verify the completed content hash after write.
  • Detect changed files by metadata/hash and import them as new local revisions.
  • Treat an externally deleted managed file as a potential deletion request only after clear conflict checks; offer a safe confirmation/recovery path.
  • Keep a local mapping of note ID to provider document URI/version. Do not depend on filenames as identity.

Limitations to state explicitly

  • Folder copies/backups may retain historical versions, but the app cannot assume or manage them.
  • Concurrent edits on two devices can create conflicts; the future implementation must preserve both local and imported content rather than auto-merging silently.
  • Android background folder access and provider behavior vary. Failed background work must be retryable from the app.

Extension strategy

Release 1: placeholder only

Ship only documented/stubbed capability and extension contracts where they help preserve module boundaries. Do not package an extension registry, Android local-folder implementation, destination configuration, or third-party plugin runtime. This avoids premature lifecycle and security commitments while retaining a clear implementation path.

Future Android distribution

Consider separately installed Android companion apps or signed packages only after defining:

  • signature/trust policy and compatibility/version negotiation;
  • narrow IPC contracts and permission grants;
  • install/update/disable behavior;
  • background execution and crash isolation;
  • privacy disclosure, review, and revocation UX.

iOS constraint

iOS does not support arbitrary code plugins in the same model. On iOS, extensions should be built-in integrations, app extensions where Apple permits them, or protocol-compatible sync services. The shared capability contract still applies, but distribution is platform-specific.

For the broader set of expected plugin categories—templates/capture, metadata-driven views, research integrations, automation, and AI—see the extension design reference. These surfaces should use their own narrow contracts rather than overloading the sync API.

Future cloud destination requirements

Before committing to cloud sync, select a conflict model and threat model. A suitable history-aware cloud destination should support stable item IDs, revision parent links, change tokens, conditional writes, tombstones, and encrypted transport. If end-to-end encryption is required, design key generation, recovery, device enrollment, metadata leakage, sharing limits, and multi-device conflict recovery before implementation.