- Shipped
- August 14, 2026 at 2:57 AM UTC
- Author
- Kamo
- Commit
- 5c839bc
The migration has run, so is_answered exists and SearchIndexService now writes it alongside is_read and is_starred. The index has recorded two of the three flags for its whole existence; from here it records all three. The index-backed listing stays off, and the reason is not "not rolled out yet". Its check settles whether the index holds the same messages as the server. It cannot settle whether it holds the same flags, and it never will, because flags move without changing a message count or a UIDNEXT. That would be survivable if anything kept the indexed flags fresh. Nothing does. MessageIndexer reacts to exactly one thing — a message arriving — and writes the row once, from the message as it was at that instant. Read it on a phone an hour later and the index still says unread, permanently. A folder passing every check here would therefore be served with the read, starred and replied state each message had on the day it arrived: an inbox showing read mail as unread, which is worse than an inbox that takes another moment to load. The honest fix is to take flags from IMAP and only envelopes from the index. That works and is worth less than it sounds: reading flags means opening the folder, and once it is open the envelopes ride along in the same batched FETCH. What is left is the server's envelope construction, weighed against a second source of truth for the message list — and against an IMAP path that no longer issues a per-message round trip for content type and message id. Kept rather than deleted because the expensive part was learning this, and the staleness check and its tests are correct and reusable for whichever version turns out to be worth having.