The envelope

Last updated

The relay stores one unit, a deterministic CBOR envelope. Its header carries a protocol version, an encryption mode, an opaque group id, an MLS epoch, a BLAKE3 content address and the ciphertext. Nothing else about a message is legible to the relay.

What a relay validates

A relay checks the version, the encryption floor, that the group exists, the content address and the size. It also checks that the authenticated device session sits inside the group's access set. It checks nothing else.

The access check ignores the encrypted author field, which the relay cannot verify. Authorization comes from the connection and the access set.

Ordering and duplicates

Sequence numbers are per group, monotonic, and assigned by the relay inside the transaction that inserts the envelope. A duplicate content address is resolved before the counter is touched. A retry after a dropped connection returns the original sequence and takes no lock.

Nothing above the transport reads a sequence number for correctness. A gap left by a rolled-back transaction is legal, and clients tolerate one. Reconciliation works over the sequence space that exists and assumes no dense range.

Documents

  • Wire protocol. The envelope, the event kinds, the sync algorithm and the transport.
  • CDDL grammar. The machine-checkable grammar for every frame and every envelope.
  • Error registry. Every code a relay may return, with the condition that produces it.
  • Reconciliation. Range-based set reconciliation, and the bound on what it exchanges.
  • Channels. Channel state, ordering and the documents a workspace carries.
  • Retention. Checkpoints, snapshots and the rules for deleting below a barrier.

Version negotiation

A client offers its maximum protocol version in its connect frame. The relay selects the lower of the two ceilings and signs the selection into the challenge the client answers. A downgrade therefore breaks the signature.

Version 4 is current and version 1 is still served. Version 2 adds two frames and one event kind and leaves the envelope unchanged. A version 1 client keeps working and is never sent a frame it does not know.

A version error aborts the connection. A client that silently accepted a floor below its own would have no floor.

Errors

Every error carries a class and a stable code. Where relevant it also carries the current state hash, so a client can rebase. The five classes are retry, reject, denied, quota and version. The full registry is published with the condition that produces each code.

A send returns retry for infrastructure faults and never for contention. No server-side head chain exists to contend over, so a busy group never looks broken.