EMAIL-WP-0005-T01: add Maildir mailbox source
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Adds MaildirMailboxSource reading new/ and cur/, wired through
source.maildir_dir and mailbox.protocol: maildir. Message identity is the
Maildir unique name without its :2,FLAGS suffix, so it survives the new/ to
cur/ move; it is carried on MailboxSourceMessage.dedup_uid and appended to the
message dedup key only when set, leaving fixture and IMAP keys unchanged.

Cursor ordering parses the Maildir delivery time instead of comparing names
lexically. mark_seen and a missing directory are rejected, matching the
read-only IMAP contract.

Also fixes the parse-failure path, which keyed identity on raw_message_ref.
A new/ to cur/ move rewrites that ref, so an unparseable message re-registered
as new on every rescan; it now prefers the source uid when one exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-08-14 01:31:58 +02:00
parent 9c0d6f1b40
commit 86f22c2e65
9 changed files with 365 additions and 18 deletions

View file

@ -18,10 +18,17 @@ It scans an inbound return mailbox source, classifies messages, stores scan
state in SQLite, updates endpoint-quality hints, and writes timestamped CSV
evidence reports.
The source layer supports deterministic fixture directories and a read-only IMAP
connector. IMAP scans select the configured folder with `readonly=True`, fetch
messages using `BODY.PEEK[]`, and reject `mark_seen` because mailbox write-back
actions are out of scope for this MVP.
The source layer supports deterministic fixture directories, Maildir trees, and
a read-only IMAP connector. IMAP scans select the configured folder with
`readonly=True`, fetch messages using `BODY.PEEK[]`, and reject `mark_seen`
because mailbox write-back actions are out of scope for this MVP.
Maildir scans read `new/` and `cur/`, key message identity on the Maildir unique
name without its `:2,FLAGS` suffix so identity survives the `new/` to `cur/`
move, order by delivery time for cursor purposes, and reject `mark_seen` for the
same reason IMAP does. Maildir exists for the test harness
(`EMAIL-WP-0005`) and for MTAs that deliver locally; it does not make
`email-connect` a mailbox owner.
## Package Layout