Treat the parser upgrade as a data contract change
A report collector can continue displaying charts while losing the distinctions that the updated aggregate format was designed to carry. An RFC 9990 migration therefore needs more than accepting a new filename or ignoring validation errors. Define which wire formats are recognized, how their fields map into the internal model and how incompatible or suspicious input is handled before changing production ingestion.
Keep source receipt, decompression, XML parsing, schema interpretation and aggregation as separate stages. Each should produce a bounded outcome and preserve enough provenance for diagnosis. This article proposes that design and its test inventory. It does not provide a deployed parser, executed fixtures or evidence that any existing collector conforms to the new specification.
Identify the format without changing the DNS version
RFC 9990 Appendix A defines the current XML schema with namespace urn:ietf:params:xml:ns:dmarc-2.0. The optional version element has value 1.0 under section 3.1.1.2. Those identifiers describe the report format; neither means that a domain should publish v=DMARC2 in DNS. The DMARC policy version remains governed by RFC 9989 section 4.7.
A compatibility design should recognize a supported legacy profile separately from the current profile. Preserve which profile was selected and why. Do not rename an unfamiliar namespace to make an input validate, silently insert missing required fields or reinterpret a legacy report as current merely because the root element is named feedback. Unknown input should receive an explicit unsupported or quarantined outcome.
Retain the original report bytes under an appropriate access and retention policy, alongside a digest and normalized interpretation. If a later parser correction changes results, that separation makes reprocessing reviewable. It also prevents a normalized record from being mistaken for exactly what the reporter sent.
Preserve policy context and alignment meaning
The current policy_published structure includes optional discovery_method and testing information. Discovery can be reported as psl or treewalk, and testing carries the t value. An absent optional field is not proof of a particular implementation version. RFC 9990 section 3.1.1.5 defines these fields and their scope.
Keep policy_evaluated separate from auth_results. The former records DMARC-related alignment outcomes and disposition; the latter carries authentication results before that DMARC interpretation. A raw DKIM pass from an unrelated domain must not be promoted to an aligned pass during normalization. Preserve override reasons rather than changing the authentication result to match the final disposition. Sections 3.1.1.9 and 3.1.1.11 describe that separation.
Current DKIM result entries require the selector. A legacy record without one should not receive an invented value such as default to satisfy the current schema. Record the supported legacy interpretation or the validation failure. Multiple signatures, optional envelope information and policy changes during a report period also need explicit representation; collapsing them prematurely can erase the explanation an analyst needs.
Handle extensions without surrendering validation
The specification provides namespaced extension points at defined locations. The presence or absence of an extension is not itself an error, and arbitrary unfamiliar elements are not automatically valid everywhere. RFC 9990 sections 3.2 and 5 supply the distinction. Preserve supported extension content or bounded opaque data without allowing it to overwrite core field meanings.
Treat archive and XML input as untrusted. Section 8.1 identifies resource-exhaustion risks in decompression and parsing. Proposed implementation controls include limits on compressed and expanded size, nesting, element counts and processing time, plus disabling external entity resolution and network retrieval. Display report-supplied text as data. These are defensive design recommendations, not assertions that the collector has passed malicious-input tests.
Malformed input should not enter ordinary aggregates as if it were valid. Section 3.1.1 recommends discarding nonconforming reports while allowing a cautious attempt to use some data. If a product supports partial recovery, label the result and keep it outside normal decision totals until the recovery policy has been reviewed. Silent coercion is especially dangerous when a graph appears complete.
Make duplicate handling an explicit policy
Report-ID is intended to aid duplicate recognition, but a single identifier should not be assumed globally unique across unrelated reporters. Section 3.5.4 recognizes exact duplicates and overlapping information, leaving handling to the consumer. Preserve reporter and policy context, reporting period, identifier and content digest when proposing deduplication rules.
An exact repeat and a changed report covering overlapping time are not necessarily the same case. Avoid simply summing both or discarding one because their date ranges intersect. Record the resolution decision and retain a way to investigate policy changes and late corrections without rewriting history invisibly.
Fictional fixture worksheet and release gate
A fictional current-format case contains the dmarc-2.0 namespace, version 1.0, testing=y and an explicit DKIM selector. A separate invented legacy-shaped case lacks that selector. The planned acceptance worksheet expects distinct profile handling, not insertion of a made-up selector. Additional proposed rows cover a namespaced extension, exact duplicate, overlapping report and malformed input. None has been executed.
The exact original requirement remains: Run legacy and current schema fixtures, extension cases, duplicate reports and malformed inputs. The commissioning gate is: Validate current primary specifications and retain a worked example before drafting. The retained paper cases and source review do not satisfy runtime acceptance. Parser security, backward compatibility, human SME approval, production behavior and publication authorization remain open until the required tests and decisions exist.