LC-77-MID-DEDUP: exactly-once dedup via Message-ID table #202
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Background
LC-77 v1's poll loop posture is at-least-once with
\Seen-after-attempt:BODY.PEEK[]for an unseen UID.A crash between (2) and (3) means the message has been processed (the chat row exists) but the IMAP UID is still UNSEEN, so the next tick reprocesses it and posts the same message a second time.
Duplicates are rare in practice (crashes between two adjacent IMAP commands are infrequent), but possible. v1 accepts the tradeoff because the alternative (Seen-then-process) would lose a message on crash, which chat tolerates worse than a duplicate.
When to act
If operators report duplicate posts in practice, OR if a future change makes the processing step heavier (e.g. external API calls during attachment processing) such that the crash window widens.
Scope
Add an exactly-once dedup layer keyed on the message's RFC 5322 Message-ID header.
processed_message_ids(chat.db or settings.db; chat.db likely) with(inbox_id, message_id_hash, processed_at)and a UNIQUE constraint on(inbox_id, message_id_hash).LETS_CHAT_SECRET_KEYso the table doesn't leak which senders the operator has been receiving mail from.Anti-scope
\Seen-after-attempt posture (we still want poison messages to not retry-forever).Test requirements
process_polled_messagetwice withoutmark_seen); the second call should be a no-op (no second row inmessages).References
docs/email-ingress.md"Not supported" section names this asLC-77-MID-DEDUP.