# Protocol Flow
## Session Bootstrap
1. Upper layers derive or provision a 32-byte shared secret (for example via X3DH).
2. Both peers call `ensure_session_with` using the shared secret and their role (initiator or responder). This deterministically derives:
- Conversation identifier (UUID)
- Send/receive ratchet chains
- Associated-data salt that binds user identities to the session
3. Sessions live entirely in memory. Applications decide when to persist or drop them.
## Sending
1. Build a packet-level message (text or attachment fragment).
2. Call `encrypt_message` which:
- Encodes the `Message` via `enigma-packet`
- Advances the ratchet to obtain a per-packet AEAD key
- Encrypts the encoded bytes with `enigma-aead` using AD = conversation id + sender + receiver
3. Pass the ciphertext bytes to the active transport.
## Receiving
1. Transport delivers ciphertext bytes.
2. `decrypt_packet` pulls the next ratchet key, decrypts the AEAD envelope, and decodes the packet into a `Message`.
3. `MessengerClient::poll_once` emits a `ClientEvent` (`MessageReceived`, `AttachmentProgress`, `AttachmentCompleted`). Attachments are tracked by attachment id to enforce init → chunk → end ordering.
## Attachments
- `build_attachment_init`, `build_attachment_chunks`, and `build_attachment_end` construct the three-phase flow expected by `enigma-packet`.
- Each chunk is an individual message. Progress events expose chunk counts so applications can wire UI updates.