Where Should Canonical State Live in a Product?
Cache, optimistic UI, recovery storage and cloud data can coexist, but only one layer should own canonical authority.
“Source of truth” is used so often that it can become meaningless. The practical question is simpler:
If two layers disagree about an entity, which one is allowed to win?
If that answer is not explicit in the codebase, the product will eventually produce races, silent overwrites or inconsistent behaviour across devices.
State is not one thing
The same note can exist simultaneously in several forms:
- a PostgreSQL row,
- a query cache,
- optimistic UI state,
- local durable recovery storage,
- a realtime update received from another device.
All of those are state. They are not all authority.
I find it useful to name the roles:
Canonical — the last accepted product truth. Cache — a temporary representation for speed. Optimistic — user intent that has not yet been accepted by the authority. Mirror — a copy of canonical state on another surface. Recovery journal — durable protection for intent that still needs reconciliation. Derived — a view computed from other state. Legacy — an old source that must no longer act as authority.
Problems start when those roles blur.
Why Ordovia needs cloud authority
Ordovia runs across web, Android and Windows. The same account can change tasks, notes, rituals and planning state from several devices.
A model where “the last device opened decides the truth” is not reliable. The durable cloud model needs to remain authoritative, while clients act as synchronized working surfaces.
That does not mean local state is bad. Local cache, optimistic UI and durable pending mutations can make the product substantially better. Their job, however, is not to silently replace the canonical state.
Recovery is not the same as authority
Kurmaca has a different risk profile. Long-form writing needs aggressive recovery protection. A writer can lose network, close a tab or continue editing while another revision already exists in the cloud.
Local recovery is essential. But “the newest local text always wins” can turn recovery into data loss.
A safer model is:
- local recovery preserves unaccepted authoring intent,
- cloud revisions represent accepted history,
- reconciliation compares revision context,
- conflicts are surfaced instead of silently overwriting one side.
That is not merely database correctness. It is product trust.
Choosing a canonical store is not enough
“Supabase is the source of truth” is only the first sentence.
You still have to inspect every path that can change or restore data:
- UI writers,
- background writers,
- hydration,
- retry logic,
- realtime updates,
- restore and migration paths,
- permissions and ownership checks.
One canonical database with several uncontrolled writers can still produce inconsistent state.
Do not promote UI state into business state
selectedFolder, expandedCard or isArchiveViewOpen can be UI state. note.status, task.completedAt and scene.revision are business state.
When those roles mix, mount/unmount behaviour or navigation lifecycle can accidentally change domain truth.
The decision test
For any important state, I ask:
1. Is it durable for the user? 2. Can multiple devices change it? 3. Can conflicts occur? 4. Do we accept offline changes? 5. Which layer is auditable? 6. Which permissions apply? 7. Is recovery being confused with authority? 8. Would losing or resurrecting this state be dangerous?
State architecture is not mainly a Redux-versus-Zustand decision. It is a decision about how long each representation lives, what authority it has and what it is allowed to overwrite.
State copies may multiply. Authority should not.
Architecture in the Wild
Field architecture through live state, information, interaction and product-boundary decisions rather than abstract diagrams.