Principles
Principles
Section titled “Principles”Purpose
Section titled “Purpose”This document defines the product thesis, architectural boundaries, and non-negotiable principles for Synchro.
It is the highest-level source of truth for the new system. Lower-level specs must conform to it.
Product Thesis
Section titled “Product Thesis”Synchro is an offline sync product for teams building serious native apps.
It is designed to beat current alternatives on:
- extension-based server architecture instead of a separate sync tier
- developer experience
- lower adoption friction
- predictable sync semantics
- end-to-end synced CRUD
- native client parity
- performance through extension-side execution and deterministic sync scopes
Synchro is not a generic local-first substrate first. It is an opinionated sync product first.
Product Promise
Section titled “Product Promise”The promise of Synchro is:
- extension-based server execution close to the data
- full synced CRUD for synced tables
- thin, replaceable host adapters
- native client engines with local SQLite on device
- shared sync semantics across adapters through the Rust core
- minimal required application schema changes
- deterministic selective sync with explicit rebuild semantics
Layer Model
Section titled “Layer Model”The system is composed of four layers:
extensions/synchro-core: shared deterministic sync semanticsextensions/synchro-pg: PostgreSQL extension that executes those semantics close to the dataapi/go: one reference host layer that implements the contract over the extension- end clients: Swift, Kotlin, React Native
api/go is not an end client. It is one host layer.
Architectural Principles
Section titled “Architectural Principles”Shared Core Semantics
Section titled “Shared Core Semantics”All core sync semantics should live in the shared Rust core wherever possible.
That includes:
- deterministic sync rules
- conflict semantics
- checksums
- diffing and dedup logic
- protocol-level semantic invariants
Extension-Centered Execution
Section titled “Extension-Centered Execution”The PostgreSQL extension is the authoritative execution environment for server-side sync logic.
The system should prefer:
- WAL/CDC-driven server-side change detection
- extension-owned sync metadata
- extension-side membership materialization
- extension-side write application for synced CRUD
The system should not depend on a separate sync database or sync service database on the server.
Thin API Adapters
Section titled “Thin API Adapters”api/go and future adapters should remain thin.
They may own:
- transport
- authentication integration
- version gating
- HTTP validation and translation
They should not own:
- sync semantics
- scope membership semantics
- conflict resolution semantics
- rebuild semantics
- synced-table write semantics
Thin End Clients
Section titled “Thin End Clients”Swift and Kotlin should be as thin as possible without becoming fake-thin.
They still need to own:
- local SQLite integration
- local change capture
- local queueing
- scheduling and retry orchestration
- applying server-delivered state safely
They should not invent server sync semantics.
React Native should remain a thin bridge over the native clients, not a separate sync engine.
Selective Sync Model
Section titled “Selective Sync Model”Synchro uses server-defined deterministic sync scopes.
The public abstraction is:
- scope definition
- scope instance
- scope membership
- scope checkpoint
- scope rebuild
Clients do not define arbitrary replication queries.
The system should not use client-authored dynamic shape graphs or arbitrary client-side replication predicates as the primary sync model.
Scope Design Principles
Section titled “Scope Design Principles”This section is normative. It defines the architectural rules. Detailed operational guidance and examples live in Scope modeling.
Deterministic Membership
Section titled “Deterministic Membership”Scope membership must be deterministic and server-defined.
The server decides which rows belong to which scope instances.
Materialized Membership
Section titled “Materialized Membership”The system should materialize membership and metadata so that:
- pull is cheap
- rebuild is explicit
- per-scope cursor progression is explicit
- checksums are explicit
Scope Count vs Fanout
Section titled “Scope Count vs Fanout”A high number of scope instances is acceptable.
The true scaling danger is fanout:
- for one changed row, how many scope instances must be updated or notified
The system must optimize for low fanout.
Shared Data Strategy
Section titled “Shared Data Strategy”Shared or public data should prefer shared scopes with many subscribers.
The system should avoid duplicating shared rows into large numbers of private scopes unless there is a strong reason to do so.
Recommended pattern:
- private rows in private scopes
- shared rows in shared scopes
- both may materialize into the same local table
- bundled seeds export those same shared scopes, not seed-only variants
Example:
documents_user:{user_id}for user-owned documentstemplates_publicfor public templatestemplates_user:{user_id}for user-created templates
These are example names, not automatic assignments.
The default identity scope is user:{user_id}.
Custom private scopes require an explicit server-side grant, and shared scopes require registration.
See Scope modeling.
The system should prefer one shared scope with many subscribers over copying the same shared rows into every private scope.
Shared scopes should be grouped by operational behavior, not only by visibility. One shared global scope is acceptable for small stable datasets that change together. Larger or more independently changing public datasets should use separate shared scopes.
Advanced Scope Logic
Section titled “Advanced Scope Logic”The system must support advanced scope logic as an escape hatch.
Common cases should be handled by first-class structured configuration.
Advanced cases may use custom SQL.
Write Model
Section titled “Write Model”Synchro owns row-level CRUD for synced tables end-to-end.
That includes:
- create
- update
- delete
- policy enforcement
- conflict handling
- canonical server response
- resulting scope membership effects
Synchro does not attempt to own arbitrary business workflows or domain commands.
Business commands that are not row-level synced CRUD remain outside Synchro.
Configuration Model
Section titled “Configuration Model”Configuration should live in SQL migrations in the consuming application’s database repo.
The preferred authoring model is:
- structured Synchro SQL configuration for common cases
- custom SQL escape hatches for advanced cases
The system should not use YAML or server-language config as the primary source of truth for sync semantics.
Schema Friction
Section titled “Schema Friction”Synchro should require only extension-owned infrastructure tables on the server.
It should not require application teams to modify every application table as a prerequisite for adoption.
Minimal schema friction is a goal, but not at the cost of ambiguous or under-specified behavior.
Performance Principles
Section titled “Performance Principles”The system should outperform alternatives by combining:
- local SQLite on device
- extension-side execution near the data
- deterministic scopes
- materialized membership
- cheap incremental pull
- scoped rebuild instead of broad destructive resync
- no unnecessary extra network round trips for core sync logic
The system must explicitly optimize for:
- low row-change fanout
- cheap pull
- efficient shared/public data handling
- explicit rebuild costs
Competitive Positioning
Section titled “Competitive Positioning”Synchro is intended to beat alternatives by being:
- more complete than systems that stop at read sync and ask users to invent their own write API
- more predictable than systems centered on arbitrary replication shapes
- better for native mobile DX
- better for thin adapter implementations
- better for shared semantics across multiple adapters and client SDKs
Non-Goals
Section titled “Non-Goals”Synchro is not trying to be:
- a generic workflow engine
- a client-defined arbitrary query replication system
- a system whose main value is “bring your own backend write path”
- a system whose semantics are inferred from implementation accidents instead of the release contract