Protocol core

August 13, 2026 ยท View on GitHub

Status: adopted.

Protocol core describes what Marmot clients do with MLS group state.

These docs are the tour for implementers who do not already live inside MLS. Foundation docs define the stable building blocks. Protocol core explains the flow: create a group, invite members, process incoming bytes, publish local changes, resolve competing branches, and keep enough history to recover safely.

Transport documents say how bytes arrive. App component documents say how component bytes change. Protocol core says when those bytes become canonical group state.

Big picture

create group
  -> publish or retain initial state
  -> add member KeyPackage
  -> publish add Commit
  -> deliver Welcome through the active transport
  -> new member processes Welcome
  -> group traffic advances through proposals, commits, and app payloads

Marmot uses MLS for group security. A Marmot client does not invent group membership or epochs locally. It feeds valid MLS inputs into the group, checks Marmot policy around those inputs, and applies one canonical branch.

Main flows

Local group-state change:

prepare MLS commit
  -> hold pending state
  -> publish required transport bytes
  -> apply pending state only after publish succeeds
Inbound group traffic:

receive transport envelope
  -> peel transport
  -> retain protocol bytes
  -> classify as proposal, commit, or app payload
  -> run validation and convergence
  -> emit state notifications or delivered app payloads
Member join:

find compatible KeyPackage
  -> commit Add
  -> publish Add commit
  -> deliver MLS Welcome
  -> new member validates group state
  -> new member rotates consumed KeyPackage and self-updates

Files

Core rule

Marmot clients choose group state from MLS-valid protocol bytes and the pinned convergence policy.

They MUST NOT choose group state from transport arrival order, transport envelope timestamps, outer event ids, local receive order, or which transport source delivered a message first.