Expand description
Messenger homeserver: protocol decisions and the Client-Server HTTP routes.
Decision functions take an already-open rusqlite::Connection.
http::router mounts those decisions on axum. The process opens the
store with store::open_messenger_db (tesserax-store: SQLCipher, one
writer; store::open_read_pool adds parallel readers), calls
store::set_matrix_server_name once, and serves http::Homeserver.
There is no tariff logic and no product identity database; products plug in through
identities (signed assertions from m4a-seam) and policy.
Re-exports§
pub use error::MatrixError;pub use http::router;pub use http::Homeserver;pub use typing::TypingRegistry;
Modules§
- account
- Account data, tags, filters, and public-room listing. Profile nick lookup and any restricted user directory are product concerns, not in this crate.
- ephemeral
- Typing, receipts, and read markers.
crate::typing::TypingRegistryis in memory. This module does not wake. - error
- Matrix Client-Server error envelope.
statusis the HTTP status.IntoResponsewrites it. The body is the serde JSON.statusitself is not serialized. - events
- Format one stored event the way a Client-Server response carries it.
- fed_
rooms - Federation F1/F2 room layer (storage side, no network).
- federation
- Federation stage F0: this server’s signing keys, canonical-JSON signing,
X-Matrixrequest authentication, and remote key resolution/cache. - http
- Client-Server HTTP routes. Paths are relative; the process nests them
under
/_matrixif it wants that prefix. - identities
- Nick + domain identities of this messenger server.
- key_ops
- Device keys, to-device, cross-signing, and backup decisions. Signature checks that the protocol requires stay here. Transport does not.
- keys
- Devices, E2E key material, to-device inbox, device-list change log,
cross-signing, and key backup — the devices/keys/backup half of
messenger.db(the rooms/events/state half ismatrix_store.rs, a separate work item). Seethe messenger protocol notes§2 second SQL block for the DDL this module implements, §1.1 for the device-per-credential model, and §3.7 for the/syncdelta shapes this module’s read functions serve. - live
- Wake-only long-poll plumbing for
GET /client/v3/sync, plus the per-caller token bucket forPOST /client/v3/keys/claim. - media
- Media repository for attachments. Blobs are opaque bytes: in E2E rooms
clients upload AES-CTR ciphertext (Matrix encrypted attachments), so the
server stores ciphertext only. They follow the ciphertext-pump rule: kept
for a TTL (see
purge_expired) and then deleted. Plaintext uploads for public channels use the same table and the same TTL for now; a separate persistent public-media store is a named seam, not built. - messaging
- Timeline send, redact, and history paging over an open connection. Entitlements are the builder’s. A private room does not consult a paid flag.
- nick
- Nick stored on
messenger_sessions. The HTTP layer stamps member display names fromeffective_labeland refuses create/invite whenrequire_nickfails.set_nickwrites that session row. There is no reserved-nick list, no cooldown, and no billing.matrix_users.nickis not the source of truth. - policy
- Neutral policy hook. The server asks the hook before an action; the
default allows everything. The server defines no tariff or tier: the
product’s assertion carries opaque claims (see
claims_from) and the hook decides what they mean. - public_
channels - Public plaintext store (channels; a forum could join later).
- public_
forum - Public forum store (plaintext, server-side state). Seam only: storage and a small API, no HTTP routes yet.
- retention
- Delivery-window retention (design: docs/mail4agent/messenger-model.md, “Server is a router”). The server is not an archive: a message event is only needed until every live device of every joined member has fetched it.
- rooms
- Room and membership decisions over an open messenger connection. The builder supplies user ids, mxids, and display names, and enforces entitlements before it calls in. Nothing here authenticates, bills, or wakes a socket.
- spaces
- Domains with sub-rooms, the Matrix way: a domain is a Space (a room whose
m.room.createcarriestype: m.space), a sub-room is linked by anm.space.childstate event in the space (state_key = child room id, contentvia= servers) and, optionally, a back-linkm.space.parentin the child. Everything here is derived from ordinary state events, so no extra table exists and federation can later carry it unchanged. - store
- Matrix-shaped event store — rooms/events/state/members/relations/
receipts/account-data/txn-dedup/filters half of
messenger.db(the devices/keys/backup half ismatrix_keys_store.rs, a separate work item). Seethe messenger protocol notes§2 for the full DDL this module implements (the “Manager decisions on this plan” section at the top of that file overrides the body — this module follows those corrections, noted inline where they apply) and §1 for the id-format rules. - sync
/syncsnapshot. Returns JSON. Does not wait, poll, or wake.- sync_
token - The Matrix sync-token format
GET /sync(P10) emits andGET /keys/changes(P9) also consumes — defined here, once, so every future caller that needs a sync token parses/formats through this module rather than growing a second implementation. - typing
- In-memory typing set. Never written to the messenger database.
The builder seeds
TypingRegistry::with_seedfrom a clock and notifies clients itself whenset_typingorrooms_with_expired_typingreport a change.