Sync Groups

A Sync Group is just the set of devices that share data. Every blob sent by any member is delivered to every other member. Membership isn’t implicit — it lives in a signed document called the Group Manifest, which every member holds a copy of and any member can update.

TL;DR

  • A group is its manifest. No central registry, no server-side state.
  • Any member can update it. Authority is membership; no admin role exists.
  • Updates converge by version. Higher version wins. No consensus protocol involved.
  • The relay sees nothing. It routes blobs by recipient public key. It has no concept of “group.”

The Group Manifest

The manifest is the authoritative, versioned record of who’s in the group. It contains a stable Group ID, a version number that only goes up, the member list (each member’s noise and signing public keys), and an Ed25519 signature from whoever issued this version.

Any current member can cut a new version. No coordinator, no privileged device. Authority comes from membership — if you’re in the current manifest, you can issue the next one.

For the byte-level layout, see Group Manifest in the component reference.

Validity and convergence

When a device receives a new manifest, it accepts it only if all of these hold:

  1. The signature checks out.
  2. The issuer is a member of the device’s current manifest — i.e. the update came from someone who was actually a member at the time.
  3. The version number is strictly higher than the current one.

If two members issue conflicting updates at roughly the same time — A removes B while C adds D — both propagate. Whichever has the higher version wins. Convergence falls out without any consensus protocol.

Sending to the group

When a device calls send(), trueseal-sync reads the current manifest and produces one encrypted blob per member, each addressed individually to that member’s noise public key. The relay receives N independent blobs and drops each into the right Inbox.

From the relay’s point of view, there’s no group — just N blobs going to N public keys. It doesn’t know they’re related or that the parties share any membership.

Receiving and filtering

Every inbound blob gets checked against the current manifest. If the sender’s signing public key isn’t in the manifest, the blob is dropped silently — even if the Ed25519 signature itself is fine.

This is how soft removal actually takes effect. When a device gets removed, the remaining members update their local manifest and start dropping that device’s messages on receipt. The removed device can technically still push blobs to the relay (the relay doesn’t enforce anything about sender identity), but nobody will accept them.

Joining the group

A new device joins through Pairing. Once the initiator accepts, two things happen:

  1. The current manifest is sent to the new device, giving it a complete view of who’s in.
  2. A new manifest version including the new device is issued, signed by the admitting device, and pushed to every existing member.

No convergence lag — everyone gets the same authoritative document.

Offline members

A device that’s offline when a manifest update is issued will pick it up when it reconnects, via deferred delivery on the relay. Until then it’s running on a stale manifest:

  • It won’t send to newly added members yet.
  • It won’t filter messages from newly removed members yet.

That window is narrow and self-healing — the moment the device reconnects, the queued update lands and the membership view catches up immediately.