Account storage
Scope and identity
Rust owns the account SQLite database and its authenticated protocol truth. Android provides the app-private directory and account lifecycle. A logical rumor, a signed outer wrapper and a derived product view are distinct objects. Database tables are implementation details, not an Android persistence API.
Supported behavior
Atomic ingestion
shared.storage.atomic — An ingestion transition must commit its accepted
records and associated state changes coherently. Invalid input must not become
accepted protocol truth. A correlated boundary outcome and its persistence
mutations must commit as one transition so that replay can recover a consistent
result. External network and file effects do not run inside that transaction.
Logical identity
shared.storage.logical-identity — Repeated receipt of the same logical
rumor, including receipt in freshly encrypted outer wrappers, must produce one
logical event. Retained wrappers keep their separate provenance links. Neither
wrapper ID nor transport arrival order may become an alternative message ID.
Account binding
shared.storage.account-binding — The runtime derives the account identity
and database filename from the imported authority. An existing account file
must reject another account. Opening the same canonical account file twice in
the process must fail rather than create independently mutable account owners.
Persistence semantics
Exact authenticated records are retained separately from projections, relation targets, outgoing intents and account-local state. Product queries derive their answer from those records. A derived search index must be repairable without reinterpreting unauthenticated legacy rows as message truth.
The account-runtime architecture owns concrete tables, migrations, WAL settings and connection policy. Successful SQLite commit under that configured policy does not promise survival of every possible hardware or power failure. Account deletion is a different lifecycle operation from a protocol message deletion.
Observable behavior
A returned mutation result describes committed account state and its revision. Android must not open the SDK database, maintain a second authenticated message cache, or use a received byte count as proof of persistence. Directories, attachment files and WorkManager queues retain their platform ownership.
Verification and limits
Mapped cases cover atomic/idempotent ingestion, correlated boundary commits, multiple wrappers for one rumor, account-file identity mismatch and duplicate open. Text-message history and a selected schema upgrade are verified in the text-message contract.
Disk-full faults, corruption recovery, power interruption, and the complete matrix of historical database versions remain separate evidence requirements. Normal close/reopen tests must not be described as crash injection.
No execution report is bundled with this documentation. Linked test cases describe verification scope; their existence is not a passing result.
| Invariant | Required environments | Execution evidence |
|---|---|---|
shared.storage.atomicrust-core | rust-host | missing2 mapped test cases
Shared requirements |
shared.storage.logical-identityrust-core | rust-host | missing1 mapped test cases
Shared requirements |
shared.storage.account-bindingrust-core | rust-host | missing2 mapped test cases
|