Groups with no shared group repository
A group chat usually wants a shared place: one room, one inbox, one server that fans the line out. Glitr does not have that place. There is no shared group repository. A group is a fan-out thread: one cascaded copy per other member, written to your mailbox, tagged with the same groupId.
That is a product choice, not a missing checkbox. Glitr’s mailbox rule is that you never write into someone else’s repository. A shared group repo would break the rule — someone would have to own the room, and everyone else would write into it. Fan-out keeps the rule: each send encrypts one outbound copy per other member, carrying the same groupId in the ciphertext envelope.
Group messaging is in progress on the roadmap. The data model is there (schema v5). Treat it as research and development — subject to change — not as a finished group product, and not as MLS.
What a group is
A Group row is sealed in your mailbox: title and member profile ids. You created it or you ingested it. There is no group host and no group remote.
Profile ids are how two repositories address each other. Contact ids are local only: “this person in my address book.” A group send addresses members by profile id, then writes outbound the same way a 1:1 send does — once per recipient.
Optional groupId on outbound, inbox, and sent files the line under that thread. After decrypt, a 1:1 text send is still raw UTF-8. A group send or attachment is a JSON object { v: 1, body, … } with optional groupId, groupTitle, groupMemberIds, and attachment fields. That inner envelope is what ingest files under a group and what fills inbox attachment columns.
Older mailboxes migrate in place. Group fields stay empty until you create or ingest a group.
Groups stay on git
Live is a 1:1 data link. Group sends always use the mailbox, even while members are Live. Groups never use the live file path.
Offline git DMs and group attachments write the file inside the outbound ciphertext envelope. A live 1:1 file stays on the data channel (plus a resume row under file-transfers/). The same composer; a different path once the send is a group.
That is why a group thread does not become instant just because two members happen to be online. Instant is the live path for a 1:1 contact. A group line waits on the same git clock as any other outbound: you push, they fetch, they ingest, they write a receipt on their repo.
Why not a shared repo, and why not MLS
A shared group repository would be a third mailbox that every member writes. Someone would own the credentials. The host would see a room-shaped pile of files. Conflict would be “the whole room,” not “one outbound row.” Glitr’s conflicts are per document. Fan-out keeps them that way.
MLS (Message Layer Security) is a different design: a shared group state, epochs, a ratchet tree. Glitr does not ship MLS as the group mechanism. An older research tutorial exists elsewhere; it is not what this messenger does. Here, one mailbox per member and groupId on send/ingest is the whole idea.
The cascade is still the recipient cascade: AES → Signal → PQXDH, then RSA hybrid → ML-KEM. Each copy is encrypted to that member. Password sealing of your group row stays outside that stack — it is your document, unlocked with the encryption password you typed at connect.
What this costs
Fan-out is honest about work. Three other members means three outbound ciphertexts. A large group is a large send. There is no shared ciphertext that everyone unwraps with a group key.
You also inherit the mailbox’s visibility story. Bodies are sealed. A host can still see that outbound files appeared, how large they are, and how often the repo moves. Three copies are three files. See What a git host can still see.
If you need a polished group product with shared state and a dedicated protocol, you will want something else — and you will be renting a room again. If you want a thread that fans out to mailboxes people already own, this is the shape.
Record shapes live on Data structures. How to send: Send and receive. Status: Roadmap.

