Report
From Ivvor: "you can't read your own sent DMs any more on the new node." Received DMs are fine; the user's OWN sent DMs render as sent — ciphertext only. Also observed: some sent DMs visible, others missing.
Root cause
An in-room DM (common/src/room_state/direct_messages.rs) is stored as ECIES ciphertext encrypted only to the recipient's member_vk. The sender cannot decrypt their own sent DM from contract state. The sender's plaintext is kept in a device-local chat-delegate cache (outbound_dms, #256) that never travels the network.
So a sent DM is readable only on the node whose local cache holds its plaintext:
- Sent from this node → cached here → readable.
- Sent from another node, or before a delegate-key change stranded the cache (the migration gate only probes
outbound_dms when the current delegate has no rooms) → plaintext absent → placeholder.
This is a design limitation of the local-only cache, not a regression from a specific PR. Recent delegate-key churn (#394, #411, #416) turned existing caches "legacy" and made it surface.
Fix
Seal a second ECIES envelope of each DM body to the sender's own key, carried in the message (DirectMessage.sender_ciphertext), so any device with the sender's signing key reads its own sent DMs from contract state — like received DMs already work. Forward-looking (does not recover DMs sent before the change). Room-contract + chat-delegate wire change → both re-key (migration).
[AI-assisted - Claude]
Report
From Ivvor: "you can't read your own sent DMs any more on the new node." Received DMs are fine; the user's OWN sent DMs render as
sent — ciphertext only. Also observed: some sent DMs visible, others missing.Root cause
An in-room DM (
common/src/room_state/direct_messages.rs) is stored as ECIES ciphertext encrypted only to the recipient'smember_vk. The sender cannot decrypt their own sent DM from contract state. The sender's plaintext is kept in a device-local chat-delegate cache (outbound_dms, #256) that never travels the network.So a sent DM is readable only on the node whose local cache holds its plaintext:
outbound_dmswhen the current delegate has no rooms) → plaintext absent → placeholder.This is a design limitation of the local-only cache, not a regression from a specific PR. Recent delegate-key churn (#394, #411, #416) turned existing caches "legacy" and made it surface.
Fix
Seal a second ECIES envelope of each DM body to the sender's own key, carried in the message (
DirectMessage.sender_ciphertext), so any device with the sender's signing key reads its own sent DMs from contract state — like received DMs already work. Forward-looking (does not recover DMs sent before the change). Room-contract + chat-delegate wire change → both re-key (migration).[AI-assisted - Claude]