module-11/pocket-db.mdPRODUCTION MODULE

The Pocket DB

Server-grade data discipline on the device in someone's pocket.

Sensitive data in localStorage — unencrypted, 5MB-capped, and readable by anyone with the device.
Encrypted client-side storage — AES-256 at rest, relational queries offline, and automatic pruning.

The incident

The offline feature shipped fast by caching the working set in localStorage. Then a field tablet was stolen. localStorage is plaintext. The working set was patient appointment data. The incident report wrote itself; the disclosure letters took longer.

Why the obvious approach fails

localStorage is the path of least resistance and fails every requirement that matters: it's synchronous (blocking the main thread on every read), capped around 5MB, string-only (so every access pays serialization), and stored in plaintext readable by anyone with the device or any script that slips past your CSP. Offline-first applications don't need a cookie jar — they need a database at the edge: indexed, queryable, encrypted at rest, and disciplined about growth.

The standard

  • Client persistence uses a real store — IndexedDB (web) or SQLite (mobile) — behind one wrapper; direct localStorage use for domain data is banned.
  • Data is encrypted at rest with AES-256; keys derive from the authenticated session, so a stolen device without a session yields ciphertext.
  • The local store supports indexed, relational-style queries — offline search and filtering never require the network.
  • Growth is bounded: LRU pruning with declared per-entity retention keeps the footprint predictable.
  • Local schema is versioned with migrations, exactly like the server database — because it is one.

How Cortex validates it

At plan time

Offline blueprints declare the client data model, encryption approach, and retention bounds.

At validation

assert: localStorage.domain_data == noneassert: at_rest(client_store) == ciphertextassert: offline_queries.network_calls == 0

Assertion syntax is illustrative.

At review

The approver sees the device-extraction test: store dumped without a session, nothing readable; plus query performance on the seeded offline set.

Composes with

See where your codebase stands against this standard.