You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
imap: key a reply that carries only In-Reply-To on its parent, as the mail-source contract requires #1919
The mail-source contract's Thread identity section (added in #1811) keys a thread on the first References id, else the first In-Reply-To id, else the message's own Message-ID, even when that root is not in the archive. The maildir backend does all three. The imap backend skips the middle step: imap_source.searching.thread_root_of returns the first References id or the message's own id, so a reply carrying only In-Reply-To is its own thread on IMAP and joins its parent on maildir. An id recorded by a -sync run against one backend then fails to match on the other, and a duplicate tracker gets proposed. The contract and the maildir README currently note this gap.
Two changes close it:
thread_root_of (tools/mail-source/imap/src/imap_source/searching.py) falls back to the first bracketed In-Reply-To token before the message's own id. Only bracketed tokens count, so a comment beside the id (In-Reply-To: (was: report) <r@h>) is not taken as the root.
read_thread (tools/mail-source/imap/src/imap_source/read_thread.py) currently refuses a thread whose root message is not in the fetched window (thread root … not found). With the fallback, a thread can be keyed on a root the window does not hold, so it should return the reachable messages instead, the way maildir does, and only fail when nothing references the id.
Done when: both backends give the same thread_id for a reply carrying only In-Reply-To and for replies to a root missing from the archive, with a test for each in the IMAP suite, and the "does not take the In-Reply-To step yet" notes are removed from tools/mail-source/contract.md, tools/maildir/README.md and the read_archive.py docstring.
thread_root_of falls back to the first bracketed In-Reply-To token before
the message's own id, so a comment beside the id ((was: report) <r@h>) is
not taken as the root.
read_thread returns the reachable messages when the root is outside the
fetched window, and fails only when nothing references the id.
The three "IMAP does not take the In-Reply-To step yet" notes go
(tools/mail-source/contract.md, tools/maildir/README.md, the read_archive.py docstring), replaced by the rule as it now holds for both
backends.
One test per case in the IMAP suite, plus a parity check that both backends
give the same thread_id for a reply carrying only In-Reply-To.
I'll rebase on the current main before opening the PR.
Activity
sharpca commentedon Oct 31, 2026
Thanks for filing it — I'll take #1919.
Plan:
thread_root_offalls back to the first bracketedIn-Reply-Totoken beforethe message's own id, so a comment beside the id (
(was: report) <r@h>) isnot taken as the root.
read_threadreturns the reachable messages when the root is outside thefetched window, and fails only when nothing references the id.
In-Reply-Tostep yet" notes go(
tools/mail-source/contract.md,tools/maildir/README.md, theread_archive.pydocstring), replaced by the rule as it now holds for bothbackends.
give the same
thread_idfor a reply carrying onlyIn-Reply-To.I'll rebase on the current
mainbefore opening the PR.fix(imap): key a reply carrying only In-Reply-To on its parent (apach…