aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/BACKLOG.md55
-rw-r--r--docs/specs/2026-09-09-report.md13
2 files changed, 43 insertions, 25 deletions
diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md
index 3ab642f..87ec4b3 100644
--- a/docs/BACKLOG.md
+++ b/docs/BACKLOG.md
@@ -8,7 +8,7 @@ number and gains a status rather than being renumbered.
| 1 | Skip boilerplate namespace URLs | XS | open |
| 2 | An IDN indicator resolves to no contact | S | open |
| 3 | Expose kept cases so qtmaildir can tag spam | ? | open, unsized |
-| 4 | `Report-Type: phishing` is unverified against x-arf | XS | open |
+| 4 | `Report-Type: phishing` is unverified against x-arf | XS | closed |
| 5 | `report.build()` raises KeyError on an identity with no email | XS | closed |
## 1. Skip boilerplate namespace URLs
@@ -114,27 +114,38 @@ to qtmaildir. The second is much more in keeping with the rest of the tool.
## 4. `Report-Type: phishing` is unverified against x-arf
-**Observed.** `report.feedback_fields()` emits `Report-Type: phishing` in the
-machine-readable part. Every other field there was verified against RFC 5965
-itself; this one was not, because no primary source for x-arf's own field
-semantics could be reached while building it. The abusix README documents only
-the v3 to v4 deprecation and does not define the field.
-
-**Cause.** Not a defect found in the code. The value follows the worked
-example in `docs/specs/2026-09-09-report.md`, so it is internally consistent,
-and the hybrid envelope means a strict RFC 5965 parser ignores the field
-either way (the RFC requires implementors ignore fields they do not support).
-The exposure is limited to x-arf tooling reading a field name or value that
-does not exist in the version it implements.
-
-**Approach.** Find a primary source for x-arf v4 field names, confirm or
-correct the value, and record what it was checked against. If x-arf turns out
-to name the field differently, the fix is one string and one test.
-
-**Constraints.** Low urgency: nothing here is a leak, and the failure mode is
-a field an x-arf parser skips rather than acts on wrongly. Worth doing before
-the first real report is filed, so a desk running x-arf tooling gets what it
-expects.
+**Closed** against the IANA MARF registry
+(`https://www.iana.org/assignments/marf-parameters/marf-parameters.xml`),
+checked 2026-09-10, plus RFC 5965 itself. The primary source the item asked
+for exists; it is IANA's, not x-arf's.
+
+Two things were wrong, and neither was a leak.
+
+`Report-Type` is NOT a registered field. The registry lists 25 field names
+and it is absent. It came from the worked example in the report spec rather
+than from a decision. It is now REMOVED: `Feedback-Type` already carries what
+it was saying. 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` was `abuse` and is now `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, so `fraud` is the registered value that says what the report is,
+and some desks route it separately from bulk spam.
+
+A third, cosmetic, finding: the module emitted `Reported-Uri` while the RFC's
+ABNF and its IANA registration both spell it `Reported-URI`. The RFC's own
+worked example writes `Reported-Uri`, which is where the module's spelling
+came from. Field names are case-insensitive per RFC 5322 so nothing was
+broken, and it now matches the normative spelling.
+
+`tests/test_report.py::FeedbackPart::test_no_unregistered_field_is_emitted`
+holds the registry's 25 names and asserts every emitted field is one of them.
+The single exception is `Source`, which is x-arf's and is the reason the
+envelope carries x-arf fields at all; it is named in the test so a NEW
+unregistered field cannot arrive unnoticed.
## 5. `report.build()` raises KeyError on an identity with no email
diff --git a/docs/specs/2026-09-09-report.md b/docs/specs/2026-09-09-report.md
index 12d2157..b3a67ae 100644
--- a/docs/specs/2026-09-09-report.md
+++ b/docs/specs/2026-09-09-report.md
@@ -111,20 +111,27 @@ second body to keep in sync with the first for no reader.
An RFC 5965 envelope carrying x-arf fields inside it.
```
-Feedback-Type: abuse
+Feedback-Type: fraud
User-Agent: abusectl/0.1.0
Version: 1
-Report-Type: phishing
Source: 198.51.100.7
Source-IP: 198.51.100.7
Reported-Domain: example.invalid
Arrival-Date: Mon, 08 Sep 2026 09:12:44 +0000
-Reported-Uri: http://login-example.invalid/verify?id=REDACTED
+Reported-URI: http://login-example.invalid/verify?id=REDACTED
```
`Feedback-Type`, `User-Agent` and `Version` are the three fields RFC 5965
requires. The rest are optional there or come from x-arf.
+**Every field name here is in the IANA MARF registry except `Source`**, which
+is x-arf's and is the reason the envelope carries x-arf fields at all. An
+earlier draft of this example also carried `Report-Type: phishing`, which is
+not registered anywhere; it was removed once the registry was checked, since
+`Feedback-Type` already says it. `fraud` rather than `abuse` because RFC 5965
+defines it as "some kind of fraud or phishing activity", which is what this
+tool reports. See backlog item 4 for what was checked against what.
+
**Why an RFC 5965 envelope with x-arf fields inside, rather than either
alone.** RFC 5965 is an IETF standard and universally understood, but it was
designed for feedback loops, where a report is ABOUT A MESSAGE. These reports