mirror of
https://github.com/karatektus/pl_mail.git
synced 2026-10-25 10:04:18 +00:00
plMail could tell you a message had been READ. It could not tell you the opposite. A bounce arrived in the Inbox as a machine-generated mail titled "Undelivered Mail Returned to Sender" whose body is an SMTP transcript, and the message it was about went on sitting in Sent saying "Sent" — which at that point is a lie. The one delivery outcome a person has to act on was the one outcome attached to nothing. The structure was already here. A DSN is ReadReceiptCorrelator's twin: same multipart/report envelope, same Original-Message-ID lookup, same "stamp the sent row" payoff. BounceCorrelator is a separate service anyway, because the two disagree on every judgement that matters. ONLY `Action: failed` A DSN reports four things and three of them are not bounces. `delayed` in particular is a message STILL IN FLIGHT — Postfix emits one after four hours and keeps trying for five days — and stamping it as undelivered would tell the user their mail failed at the exact moment it is being retried, with nothing to clear the stamp when it went through. `delivered` and `relayed` are good news and set nothing. THE BOUNCE IS NOT FILED AWAY A read receipt is noise once correlated and gets marked read and taken off the Inbox. A bounce stays exactly where it landed, unread. Its body is routinely the only readable statement of what went wrong, and a failure the user may have to act on is not something to tidy up on their behalf. NOTHING IS CLASSIFIED The status is stored as the reporting MTA wrote it — "5.1.1", "4.4.7" — and never reduced to a boolean "permanent". No address is disabled, nothing is removed from a contact list, no resend is attempted. plMail records what one server said about one delivery attempt. Deciding an address is dead on that basis is a conclusion this codebase has been wrong about before, and the sweep that led here said so repeatedly. A BOUNCE WAS BEING READ AS A READ RECEIPT Found by the first fixture written against this, and reachable before it. Both are multipart/report and both carry Original-Message-ID, so a DSN satisfied ReadReceiptCorrelator's body fallback, got correlated there, and put "Read at …" on a message that was never delivered — not merely missing information but the precise opposite of the truth. The two field blocks have mutually exclusive discriminators, so that is what tells them apart now: `Disposition:` is an MDN, `Action:` is a DSN. Both arms of the detection refuse a delivery-status report first. ON THE DEMO The demo seeds a reply sent to a typo'd domain and the MAILER-DAEMON answer four minutes later, correlated by the real BounceCorrelator rather than by writing the columns directly. A demo that stamps the result itself would stay green while the feature broke; this way the red panel disappearing from the demo IS the alarm. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>