Files
amethyst/commons
Claude 53de512559 feat(cordn): carry the conversation through a device handoff
A migration moves every group's MLS state, cursor, draft, read position
and KeyPackages to the new phone — and left the conversations behind.
Every other piece has a second source: MLS state re-derives from the
coordinator's stream, a KeyPackage can be republished. A cordn message
has none. It is readable exactly once, at ingest, because both seal keys
are epoch-derived and the cursor this very document carries has already
advanced past everything behind it. A device seeded without the messages
arrives holding every group and no conversation, permanently.

Carried as `amethystMessages` on the group document, beside the other
additive `amethyst*` fields, so an older reader ignores it rather than
failing.

Bounded per group by a byte budget, newest first. These blobs go to hosts
whose limits we do not know, and a handoff that fails outright because
one group is chatty is a worse outcome than one that carries a deep but
bounded history. Budgeted in bytes rather than messages because a single
long message can cost as much as a hundred short ones.

Written before the cursor on import, for the same reason the live path
writes them in that order: a seeding that saved the cursor and then
failed would leave a device holding a cursor past a conversation it never
wrote, with no way to ask for it again. My first version had the comment
saying that and the code doing the opposite.

Mutation-checked: a document that silently drops the messages fails the
round-trip test and nothing else.

Backup still excluded, per the plan — that call is still open.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012BfD4txdnsaPRXmNXbup9n
2026-09-24 15:47:20 +00:00
..