Skip to content

Consistency, sequencing and coordination

22. Consistency, Sequencing, and Coordination

Section titled “22. Consistency, Sequencing, and Coordination”

APPEND data converges by set union.

APPEND_DELETE data converges from the set of data objects plus delete objects.

Neither requires a leader.

MUTABLE state converges according to SSP/1.

MLS groups maintain ordered epochs.

That linearity is accepted because group membership is security control state, not ordinary user-data mutation.

The architecture MUST NOT route ordinary append operations through MLS group Commits.

Expected MLS Commit triggers include:

  • node add;
  • node remove;
  • domain-scope membership change;
  • security-motivated group update;
  • explicit group reinitialization.

RFC 9420 requires applications to have an established mechanism for resolving conflicting Commits for the same epoch. SOVM prevents ordinary honest-client forks by serializing Commits through a blind per-group sequencer at the SSP Delivery Service.

MLS PrivateMessage framing exposes group_id, epoch, and content_type without exposing the encrypted Commit body. SOVM MLS group identifiers MUST therefore be random opaque values suitable for routing.

For each opaque group_id, the sequencer maintains the currently accepted MLS epoch and applies an atomic first-Commit-wins rule:

accept commit iff:
content_type == commit
AND commit.epoch == sequencer.current_epoch(group_id)
AND no commit has already been accepted for that epoch
on acceptance:
durably store/forward opaque MLS bytes
advance sequencer.current_epoch(group_id) by 1

A second Commit based on the same epoch is rejected as stale and MUST be rebuilt by its sender after processing the canonical Commit.

The sequencer reads only standard MLS framing fields that are already unencrypted; it MUST NOT decrypt the Commit body or decide whether the membership change is semantically authorized.

Clients MUST still perform full MLS validation and SSP-policy validation. An authorized malicious or buggy member can submit a syntactically routed but semantically invalid Commit and cause an availability failure; the sequencer does not convert an untrusted Delivery Service into a cryptographic validator. Recovery from that exceptional case remains part of G4.

The CAS rule prevents honest races; it does not by itself constrain a malicious sequencer, and the threat model (Section 23.1) includes hostile relay infrastructure. A malicious sequencer cannot forge a valid Commit, but it can withhold messages, misreport its epoch state, or equivocate by presenting different valid competing Commits as the winner to different members. Therefore each accepted Commit MUST be acknowledged with a signed hash-chained sequencing receipt:

receipt_n = COSE_Sign1_sequencer(
{
group_id,
epoch,
commit_hash,
previous_receipt_hash
}
)

Clients retain receipts for their groups and gossip current receipt heads through the control group. Two valid receipts for the same (group_id, epoch) with different commit_hash values, or divergent chains, are proof of sequencer equivocation.

Detected equivocation is handled as sequencer compromise: the fleet migrates the group to a new sequencer (Section 22.6), audits group state before proceeding, and surfaces the event to the user. Receipts do not remedy withholding, which remains an availability attack handled by Commit queueing and sequencer migration.

The sequencer’s receipt-signing identity is registered with the fleet and is rotatable; its lifecycle is part of the SOVM control-plane profile. Sequencing receipts and membership authorization records (Section 5.7) share one chained-record schema in the SOVM COSE profile: one mechanism, instantiated per authority.

22.6. Sequencer state, bootstrap, singularity, and recovery

Section titled “22.6. Sequencer state, bootstrap, singularity, and recovery”

Sequencer correctness depends on durable per-group epoch state and on singularity. Three cases are normative.

Bootstrap: the first Commit-bearing message observed for an unknown opaque group_id initializes the sequencer’s epoch tracking for that group. A group creator SHOULD explicitly register a new group_id with its initial epoch before inviting members, so the initialization point is unambiguous.

Singularity: an MLS group MUST be bound to exactly one sequencer at a time. Two sequencers with independent state cannot jointly enforce first-Commit-wins. Migrating a group between sequencers is an explicit control-plane operation that transfers the current accepted epoch value and the head of the receipt chain (Section 22.5), so the new sequencer’s first receipt chains to the old sequencer’s last; the old and new sequencer MUST NOT operate concurrently for the same group.

State loss: a sequencer that loses its epoch state MUST NOT resume from a naked member epoch assertion.

Recovery uses the signed receipt history introduced in Section 22.5:

  1. reachable current members submit their latest retained sequencing receipt chain (or a chain suffix anchored at a previously registered receipt head) together with an authenticated attestation of their current MLS epoch;
  2. the recovering sequencer verifies receipt signatures, hash-chain continuity, and consistency between the receipt head and attested epoch;
  3. if all available valid evidence converges on one receipt head/epoch, the sequencer resumes CAS enforcement from that state and chains its next receipt to the recovered head;
  4. two valid divergent receipt chains, or two receipts for the same (group_id, epoch) with different Commit hashes, are proof of prior sequencer equivocation and MUST fail closed; the group is audited and migrated to a new sequencer; and
  5. if no usable receipt evidence survives, recovery MUST use the domain genesis-reset procedure in Section 22.10 rather than inventing history.

Receipts are deliberately retained client-side because they are small security-audit records. A storage compaction policy MAY checkpoint old receipt prefixes, but MUST preserve a verifiable chain to the currently registered head.

If the blind sequencer is unavailable, membership-changing Commits queue.

Ordinary SOP data creation and existing-authority data synchronization MAY continue.

Clients MUST NOT create divergent offline membership histories and later expect automatic merge.

Sequencing MLS Commits does not make the relay authoritative over trust or application data.

The relay can order or reject stale opaque Commit envelopes but cannot decide:

  • whether a node is trusted;
  • whether an Add/Remove is authorized by SSP policy;
  • which application rows are valid;
  • which object state wins.

Clients still perform all MLS and SSP validation.

Schema evolution remains a control-plane problem.

SOP/1 does not define a schema CRDT.

22.10. Group recovery: domain genesis reset

Section titled “22.10. Group recovery: domain genesis reset”

MLS protocol state is reformable, not load-bearing for data. Recovery requires three components — SOP ciphertext, its ObjectManifest/AccessRecord catalog state, and applicable KEK history (Section 12.7) — none of which is MLS protocol state: KEKs and object DEKs are application state (Section 7.8), and manifest/access metadata is durably replicated through catalog checkpoints named by RecoveryRoot records. Loss of usable MLS group state therefore never implies loss of data access while one recoverable copy of each component exists (Appendix B, invariant 22).

The recovery procedure when no surviving node has usable current MLS state for a domain group is the domain genesis reset:

  1. surviving nodes re-establish mutual trust through the standard SSP pairing ceremony where required;
  2. a new MLS group is created under a fresh opaque group_id, registered with the blind sequencer (Section 22.6 bootstrap), starting a fresh receipt chain;
  3. a member holding retained application KEK history redistributes it through the standard COSE key-history package (Section 8.5) inside the new group;
  4. where local catalogs were lost, the domain catalog is restored from the latest RecoveryRoot and catalog checkpoint (Section 12.7);
  5. the old group_id is marked dead in the catalog and its sequencer binding is retired.

The degenerate single-node case requires no MLS at all: the node resolves its objects locally from its retained key store and catalog, or from a RecoveryRoot/catalog checkpoint plus retained KEK history.

The genesis reset MUST be exercised as a recurring drill (Phase 2), and full disaster recovery from a blind archive plus a bare key store is gated by G10; recovery procedures that are never rehearsed do not exist.