- Ya
- 14 Agosti 2026, 03:16 UTC
- Mwandishi
- Kamo
- Ahadi ya
- 8d33ea1
Turns the index-backed message list on, by fixing the thing that made it unsafe rather than by flipping the flag. The old check compared message counts and UIDNEXT. Both are blind to a flag moving, and nothing re-indexes a message when someone reads it on their phone, so a folder passing that check could be served with every message's read state frozen at the moment it arrived — an inbox showing read mail as unread. That is why it shipped disabled. CONDSTORE has the number that does move. HIGHESTMODSEQ is folder-wide and advances on anything at all: an arrival, an expunge, a flag set from any client anywhere. So "at modseq N the newest K messages were indexed" plus a fresh modseq of N is a proof that nothing has changed since, flags included. Verified on the live server before building on it — /usr/libexec/dovecot/imap (2.3.20) carries CONDSTORE, QRESYNC and LIST-STATUS. UIDVALIDITY is checked alongside, since a server that changes it has renumbered the folder and nothing indexed under the old value describes the same mail. Jakarta Mail's own STATUS only ever asks for the five classic items, so the extended form is issued directly and the reply parsed here — under test, against literal wire data, because that one number is the whole safety argument. The checkpoint lives in Redis, not a table. It is a sync marker whose correct behaviour on loss is "forget it and re-read", so a shared-library entity, a migration and a KamoInitializer run would be the wrong price for it. No backfill job, deliberately. When the proof fails the request reads from IMAP exactly as before and hands the result back to be indexed, so folders fill in as they are looked at — the same order in which being fast matters, and nothing that can run away across every mailbox on the platform. That also addresses why this would have been pointless before: the index held 31 rows in total. Two orderings matter and both fail in one direction only. The modseq stored is the one read before the fetch, never after, so a change landing mid-fetch leaves the checkpoint behind reality and costs one wasted fetch — the reverse would pair a current-looking modseq with stale mail. And rows already in the index have only their flags updated, never their body, because a row the full indexer wrote carries the text search is built from, and rebuilding it from an envelope would quietly drop messages out of search while making the list faster.