Status: Accepted · Date: 2026-06-11 — the rule-3 behavior (stop-pushing + update notice) shipped via #258; schema bumps are now permitted under the rules below
SyncBlob.decode() returns null for blobs whose envelope schemaVersion
exceeds currentSchemaVersion; callers treat that as “skip this blob.” That
is a safe read rule, but there is no write/upgrade rule. As built
today, a device on an older app version silently skips newer-schema blobs
while continuing to push its own older-schema blobs — so two devices on
either side of a schema bump can fork last-writer-wins namespaces (sessions,
settings) without anyone noticing.
currentSchemaVersion
is reserved for changes old readers would misinterpret, and is treated
as a per-namespace flag day.../compatibility.md.app_settings (sync_upgrade_required_v1, sync-excluded — the record is
device-local by definition), SyncIdle.upgradeRequired drives a
persistent “Update Crosscue to keep syncing” status line, and the guard
self-clears once currentSchemaVersion reaches the observed version.test/core/sync/sync_upgrade_guard_test.dart: suspension +
selective pushing, restart persistence, auto-clear after update, and
malformed-bytes-don’t-suspend.