Problem
During a delegate-migration rehearsal on 2026-08-12, a room restored from the chat delegate rendered with one member and no messages, while the predecessor generation still held the full state (2 members, 5 messages, verified directly against the fixture node before the run).
The room slot in the delegate is a debounced cache of room_state (RoomData.room_state, persisted at room_data.rs:200). The debounce is ROOM_SNAPSHOT_MIN_INTERVAL_MS = 5 minutes (chat_delegate.rs:4677). That explains a snapshot being stale by up to five minutes. It does not explain one that is nearly empty.
Something else emptied it, and that is unexplained.
Why this is worth its own investigation
This surfaced while diagnosing #621 (the backward probe cannot fire for delegate-restored rooms, because a PUT of this cached snapshot precedes the migration GET and suppresses the probe's trigger). The two are separate defects:
The interaction is what makes it worth attention. A full-but-stale snapshot pushed forward would have looked almost correct to a user, and #621 could have stayed hidden for several more releases. The near-emptiness is what made the symptom loud enough to investigate. If the emptiness has an independent cause, it may be producing quieter damage elsewhere.
Evidence available
room_synchronizer.rs:1504: No new messages detected for room MemberId(LZS6FCWR) (old_ids: 0, post-merge: 0) — confirms local state held zero messages before the merge, but says nothing about why.
- Delegate slot ciphertext sizes at baseline: public room 1293 bytes, private room 2150 bytes,
rooms_meta 134 bytes. The slots are encrypted under the node-local KEK, so contents could not be decoded directly.
- Timing, offered as data and not as an explanation: seeded activity spanned 20:20:32 to 20:21:24, and the fixture snapshot was taken around 20:26, roughly five minutes after the last write. Whether the debounce deferred those writes, whether a teardown flush ran, and whether either relates to the emptiness are all unknown.
Questions to answer
- What writes
room_state into the delegate slot, and under what conditions can it write a state with no messages when messages exist in memory or on the contract?
- Does a teardown or page-unload path flush the pending snapshot? If not, what happens to writes deferred by the debounce when the page closes?
- Can a room be persisted before its first contract sync completes, so the cached snapshot reflects a pre-sync state?
- Is the 5-minute debounce ever bypassed for a first write, and should it be?
Explicitly not assumed
No cause is proposed here on purpose. The rehearsal that found it did not have evidence to decide, and attaching a plausible-sounding guess to it would make it less likely that someone measures it.
Related
[AI-assisted - Claude]
Problem
During a delegate-migration rehearsal on 2026-08-12, a room restored from the chat delegate rendered with one member and no messages, while the predecessor generation still held the full state (2 members, 5 messages, verified directly against the fixture node before the run).
The room slot in the delegate is a debounced cache of
room_state(RoomData.room_state, persisted atroom_data.rs:200). The debounce isROOM_SNAPSHOT_MIN_INTERVAL_MS= 5 minutes (chat_delegate.rs:4677). That explains a snapshot being stale by up to five minutes. It does not explain one that is nearly empty.Something else emptied it, and that is unexplained.
Why this is worth its own investigation
This surfaced while diagnosing #621 (the backward probe cannot fire for delegate-restored rooms, because a PUT of this cached snapshot precedes the migration GET and suppresses the probe's trigger). The two are separate defects:
The interaction is what makes it worth attention. A full-but-stale snapshot pushed forward would have looked almost correct to a user, and #621 could have stayed hidden for several more releases. The near-emptiness is what made the symptom loud enough to investigate. If the emptiness has an independent cause, it may be producing quieter damage elsewhere.
Evidence available
room_synchronizer.rs:1504:No new messages detected for room MemberId(LZS6FCWR) (old_ids: 0, post-merge: 0)— confirms local state held zero messages before the merge, but says nothing about why.rooms_meta134 bytes. The slots are encrypted under the node-local KEK, so contents could not be decoded directly.Questions to answer
room_stateinto the delegate slot, and under what conditions can it write a state with no messages when messages exist in memory or on the contract?Explicitly not assumed
No cause is proposed here on purpose. The rehearsal that found it did not have evidence to decide, and attaching a plausible-sounding guess to it would make it less likely that someone measures it.
Related
[AI-assisted - Claude]