aboutsummaryrefslogtreecommitdiffstats
path: root/docs/specs/2026-09-09-report.md
AgeCommit message (Collapse)AuthorFilesLines
4 hoursfix: emit only registered ARF fields, verified against IANAHEADmasterDanilo M.1-3/+10
Backlog item 4 asked for a primary source for the machine-readable part. It exists, and it is IANA's MARF registry rather than x-arf's own docs. Checked against that registry and RFC 5965 itself on 2026-09-10. Report-Type is not a registered field. The registry lists 25 names and it is absent; it came from this spec's worked example rather than a decision. Removed, because Feedback-Type already says it. Keeping it would have been harmless, since RFC 5965 section 6 makes ignoring an unknown field a MUST for the receiver, but that same section requires an extension field be registered, and a desk should be able to look up every field in a document this tool sends. Feedback-Type moves from abuse to fraud. RFC 5965 registers fraud as "indicates some kind of fraud or phishing activity" and abuse as "unsolicited email or some other kind of email abuse". This tool reports phishing, and some desks route fraud separately from bulk spam. Reported-Uri becomes Reported-URI, the spelling in the ABNF and the registration. The RFC's own worked example uses the other one, which is where this came from. Names are case-insensitive so nothing was broken. A new test holds the registry's 25 names and asserts every emitted field is one of them, with Source named as the single deliberate exception, so a new unregistered field cannot arrive unnoticed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LByBnw83xr9YP85nskzkyE
20 hoursfix: strip the envelope recipient in every shape the grammar allowsDanilo M.1-0/+31
The for-clause rule anchored on the clause terminator, which is strictly stronger than RFC 5321 4.4: For sits inside Opt-info, so With, ID, Via or a CFWS comment may legitimately follow it, and its ABNF is 1*( Path / Mailbox ) where Mailbox carries no angle brackets. Only the tidiest shape was stripped. Four ordinary ones published the victim's address in the one header a report reproduces verbatim, including "for <a@b> (envelope-from <c@d>);", which is routine Exim and Sendmail output. Anchored on the address instead. The envelope SENDER survives the cut, since that is what the report is about, and the leftover whitespace, orphan separator and emptied comment are tidied because the line is published to a third party verbatim. Table-driven over all five shapes; reverting the regex fails six of nine tests in the class. Two accepted disclosures are now named in the spec's "Where the headers come from" rather than living in a test comment: our own relay's hostname, which the by and authserv-id clauses carry by construction, and attacker-controlled free text in Subject and the From display name, which the whitelist does not and should not filter. The second is asserted as a documented limit so it reads as deliberate, and the manifest assertion now bars the obfuscated you%40example.org spelling alongside the plain one. case.create() seeds an empty headers block so an unparsed case has the same shape as a parsed one. Additive, so FORMAT_VERSION is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xj1ayFRSUQ2u7cwb3S4axE
21 hoursdocs: settle the report specDanilo M.1-0/+412
Settles the three questions the umbrella design left open for report: the X-ARF schema, which fields the reporting identity fills, and the plain-text alternative. The message is not attached. RFC 5965's text/rfc822-headers carries a whitelist of headers instead, and parse stores that whitelist in the manifest so report never opens source.eml, which is the first property applied one level down. Also settles destination grouping per abuse address, an explicit unreportable list, and a freeze rule: any sent destination freezes the whole case, marked by a write-once field, with body integrity checked by content hash rather than mtime. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xj1ayFRSUQ2u7cwb3S4axE