Timeline
Purpose
The conversation as one member can actually read it — computed on the member's device over the copies that arrived in their inbox for this conversation, with no store anywhere asked for order. The copies are the players here: they arrive in no promised order and may repeat, and their interaction — each message naming the messages it follows, from inside the seal where no carrier can rewrite it — is what orders the reading. A message stands after the messages it names as parents, and messages that are concurrent — neither following the other — are placed deterministically, by message id, so every member reads the same timeline. A copy the ring can open becomes a readable entry; a parent id that no arrived copy answers to stands as a missing entry — awaited, or from before the member's time. And identity folds: when one message id arrives in more than one sealing, the causally latest is a correction of the earlier — the timeline shows that message once, with the latest writing, in the place the id first appeared. A copy the ring cannot open is noise on a public dead-drop and is dropped — there is no sealed placeholder, because a member is only ever handed copies for epochs they were in.
Role Players
- messages: EncryptedMessages — every copy that arrived in the member's inbox for this conversation, in no promised order, repeats and all; the players whose ancestry inside the seal orders the reading
Props
- ring: the member's
KeyRing, opened
Role Methods
messages
- ordered: given the
Messagesopened from the copies, provides theTimelineEntriesin reading order — each message id entered once, parents before the messages that follow them, concurrent messages by message id so every member reads the same timeline, the causally latest sealing of an id standing as its writing in the place the id first appeared, and a parent id no opened message answers to standing as a missing entry awaiting it. Result: theTimelineEntriesin reading order
Functionalities
present
Opens each copy the ring holds the key for — a copy the ring cannot open is dropped, noise and not
evidence — and produces the member's readable timeline through the messages' ordering: readable
entries carrying identity, sender, and writing from inside the seal, missing entries naming what
they await.
Result: the member's readable TimelineEntries, in order
Scenarios
Arrival order is not reading order
Given: a copy sealing Message "m-8002" by sofie.lind following "m-8001" and carrying "I'll bring the file.", and a copy sealing Message "m-8001" by anne.bruun following nothing and carrying "The hearing moved to Thursday." — both under "k-0163", in that order — and an opened ring holding the GroupKey "k-0163"
When: present is called
Then: the timeline reads "The hearing moved to Thursday." then "I'll bring the file." — the order came from inside the messages, not from arrival
Concurrent messages read the same for every member
Given: a copy sealing the opener Message "m-8001", and two copies sealing Messages "m-8002" and "m-8003" that each follow only "m-8001" — all under "k-0163" — and an opened ring holding "k-0163"
When: present is called
Then: the two concurrent messages stand after the opener in the order of their message ids — deterministic, so every member reads the same timeline
A correction folds into the message it corrects
Given: copies under "k-0163" sealing Messages: "m-8001" carrying "Meet at 14 Marstrandsgade.", "m-8002" following it carrying "Noted.", and "m-8001" again, following both, carrying "Meet at 14 Marstrandsgade, 2nd floor." — and an opened ring holding "k-0163"
When: present is called
Then: the timeline is two entries — "Meet at 14 Marstrandsgade, 2nd floor." in the first place, "Noted." in the second — the corrected message appears once, with the latest writing, where it first appeared
A duplicated copy is counted once
Given: two identical copies sealing Message "m-8001" carrying "The hearing moved to Thursday." under "k-0163", and an opened ring holding "k-0163"
When: present is called
Then: the timeline is a single readable entry — the message id was counted once however many copies arrived
What has not arrived stands as awaited
Given: a copy under "k-0163" sealing Message "m-8002" that follows a MessageId "m-8001" no arrived copy carries, and an opened ring holding "k-0163"
When: present is called
Then: the timeline is a missing entry awaiting "m-8001" followed by the readable entry — the hole is visible, and it is not yet an accusation
The entry names its sender by sub, not by shown name
Given: a copy under "k-0163" sealing Message "m-8001" by anne.bruun — whose shown name is "Anne Bruun" — carrying "The hearing moved to Thursday.", and an opened ring holding "k-0163"
When: present is called
Then: the readable entry's sender is "anne.bruun" — the sub read from inside the seal, the identity a reader can compute on; turning it into a shown name is the presentation's job, one layer up