MeridiansMeridians

Cache coherence — server-of-record [Flow]

From the Meridians Wiki · Public · Maintained · joint

The intricate invariant: serverVersion ≥ cacheVersion, always → the browser is a disposable cache the server can always rebuild, even after the user clears everything (the browser DEK included).

flowchart TB
    Boot["boot / open a domain"] --> Cmp{per record:<br/>cache vs server `updatedAt`}
    Cmp -->|"cache absent<br/>(cleared / new browser)"| Hyd["**HYDRATE** — server → cache<br/>'restoring your data…'"]
    Cmp -->|"server absent / cache ahead<br/>(migration / crash)"| Ado["**ADOPT** — renderer decrypts,<br/>POSTs plaintext · 'preparing…'"]
    Cmp -->|"server AHEAD of a held doc<br/>(headless commit while closed)"| Sweep["**SWEEP** — version-gated pull<br/>(planStaleSweep vs the record-synced ledger;<br/>unprovable → deferred to warm-ledger re-run)"]
    Cmp -->|"server = cache"| Live["**LIVE** (steady state)"]
    Hyd --> Live
    Ado --> Live
    Sweep --> Live
    Live -->|edit| Opt["optimistic apply → /mutate →<br/>SSE echo reconciles (rollback on fail)"]
    Live -.->|guarantee| Inv["serverVersion ≥ cacheVersion →<br/>the browser is always safe to discard<br/>(daemon re-protects with its OWN key)"]

This is the persistence half of the engine pipeline drawn from the coherence angle — same /mutate + SSE echo, focused on the clock comparison that makes "clear everything" safe. The SWEEP branch is the eager half: a doc the cache holds but the record has moved past (a scheduler run or MCP commit made while no window was open) is re-pulled on the next connect, proved stale against the record-synced version ledger — never re-fetched on ignorance (the storm guard defers unprovable docs until hydration warms the ledger). Protocol detail: sync-protocol.