Observable state
Scope and identity
A query returns a bounded snapshot of account state. A Kotlin Flow observes
that query; it is not an ordered event log or a promise to emit every database
revision. This contract covers the authored Android facade over the Rust account
runtime. The semantic type determines how the snapshot interprets its records.
Supported behavior
Committed snapshot
shared.observation.committed-snapshot — A newly collected account query
must produce the current snapshot. After a committed mutation publishes a
revision, an active observation reruns the complete query and can expose the
updated result. Coalescing revisions may skip intermediate snapshots; it must
not manufacture an uncommitted product state.
Publication occurs inside the native call's dispatched mutation boundary. A caller cancelled after the native commit must not prevent other collectors from learning that the state changed. Concurrent publishers retain the highest revision and cannot reopen a terminal observation signal.
Direct message lookup, message pages, search, context and conversation previews must use the owning message contract's effective-state rules. Several separate queries are not a single atomic multi-query snapshot while concurrent writes continue. Comparisons must use a stable point or the recorded revision.
messages.getMany(ids) / messages.observeMany(ids) resolve up to 512 unique
message IDs in caller order, omit unknown IDs, and include deletion tombstones.
Empty input returns an empty snapshot. Observations retain a copy of the input
IDs and refresh their complete effective state, including older messages beyond
the newest page. Duplicate and oversized inputs are rejected before the query.
Apps split larger loaded windows into bounded groups; separate groups are
separate snapshots and do not provide a shared revision barrier.
Observation closure
shared.observation.close — Closing an account terminates its observations.
When close wins a pending query race, the observer must not report account
closure as an ordinary query failure or emit a value from the closed owner.
A new account lifecycle requires a new observation owner.
Observation callbacks may synchronously close their account or transport, including from completion handlers. Reentrant teardown must not destroy a native handle twice. Managed snapshots remain monotonic and terminal; a delayed snapshot from a stopped owner cannot overwrite a replacement transport's state.
Persistence semantics
The observation signal is process-local. SQLite state and revision are durable; collectors and their pending emissions are not. Reopening the account rebuilds observations from a fresh query rather than replaying an in-memory cache. Implementation details belong to the account-runtime architecture.
Observable behavior
Android renders complete returned values. It must not merge raw protocol tags, choose its own edit winner, or clear a durable draft solely because an observer was cancelled. UI selection, scroll position and transient loading/error state remain application-owned. Their full lifecycle contract is outside this first SDK contract set.
Verification and limits
The packed-AAR Android case checks initial and updated observations around message changes; a focused Kotlin case covers close winning a pending-query race. The message contract separately maps typed query and reopen checks. These cases are not an exhaustive scheduler/model check of every concurrent writer, collector cancellation or account switch.
A deterministic Kotlin dispatcher case also cancels the caller after its mutation commits but before the return continuation executes. Shutdown checks verify that the managed owner publishes its final native snapshot even when its observer never ran.
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.observation.committed-snapshotshared-boundary | android-device, android-jvm | missing4 mapped test cases
Shared requirements |
shared.observation.closeshared-boundary | android-jvm | missing8 mapped test cases
|