Quick Start
1
Read and write a chat
2
Store an API key
StoragePort.StoragePort
Persistence is opaque strings; serialisation lives incore/src/chat/repository.ts, not in the adapter.
Namespaces are a closed set:
chats, settings, drafts, cache.
Writes are atomic because iOS can kill a suspended app mid-write. A halfway write is a normal occurrence on mobile, not a crash scenario.
SecretsPort
API keys go to the iOS keychain or Android keystore, never toStoragePort.
The slot is a closed union —
openai, anthropic, google, openrouter, custom — so a bug cannot write an attacker-influenced string into the keychain namespace.
How Session Persistence Works
A completed turn is recorded through the session, which owns the join between the assistant-only run state and the two-sided stored chat.end.userIndex is produced by whatever actually did the write — null when the write failed.
An unreadable chat is skipped rather than crashing the list, and the webview isolates storage to its own origin.
The last-used engine is stored under the
engineId key in the settings namespace and honoured on next launch, so the app reopens on the engine the user chose rather than a compiled-in default.Best Practices
Route secrets through SecretsPort only
Route secrets through SecretsPort only
settings.set() refuses a secret-flagged key; setSecret is the only way in, and there is deliberately no getter in the UI facade. Persistence also strips any secret-flagged key from what it writes — plainOnly drops every def marked secret: true before the settings map reaches storage — so a bug that assigns a raw API key to a settings slot cannot end up on disk.Keep serialisation in core
Keep serialisation in core
Adapters store opaque strings, so swapping the backing store — Tauri store, SQLite, OPFS — changes no format and loses no data.
Show the hardware-backing state honestly
Show the hardware-backing state honestly
Surface
isHardwareBacked in settings so users know whether a key is keychain-protected or in memory.Related
UI Shell Port
The adapters that back these ports.
Approvals & Cancellation
Human-in-the-loop on the device.

