Separate three questions before walking the tree
A DMARC discovery trace should answer which domain authored the message, which record supplies policy, and which organizational domain governs relaxed alignment. Those answers can be different. Reading the first parent TXT record and declaring it the winner is not a faithful implementation of the current algorithm. Start with the Author Domain extracted from RFC5322.From, then label each lookup by purpose: policy discovery or organizational-domain discovery for alignment.
RFC 9989 section 4.10 defines a bounded DNS tree walk. Section 4.10.1 applies it to policy selection; section 4.10.2 explains alignment. The distinction matters when the Author Domain has its own valid policy: that record supplies policy immediately, yet it does not automatically establish the organizational domain needed for every alignment comparison. Current specifications and observed receiver implementations must be documented separately.
Define a fictional tree with complete assumptions
Use alerts.ops.north.example as a fictional Author Domain. Assume it exists, has an address record, and has no policy of its own. Its parent ops.north.example has v=DMARC1;p=quarantine;psd=u. The higher north.example has v=DMARC1;p=reject;sp=quarantine;np=reject;psd=n. These are invented teaching fixtures, not records obtained from DNS and not values proposed for production publication.
The initial candidate name is _dmarc.alerts.ops.north.example. In this fixture it yields authoritative NOERROR with no TXT data, an SOA in the negative response and no alias or referral complication. The second name is _dmarc.ops.north.example, where the u record is retained as a candidate. The third is _dmarc.north.example, where psd=n stops the ascent. Keeping response context makes the trace reviewable rather than reducing everything to an ambiguous “not found” label.
Derive the result rather than stopping at the nearest record
The explicit n boundary identifies north.example as the organizational domain under section 4.10.2. The earlier u record does not win merely because it was encountered first. With no Author Domain policy, the organizational-domain record supplies policy. Since alerts.ops.north.example exists and is a subdomain of that policy domain, sp=quarantine is selected. Keep the selected tag as well as its value in the expected result.
Now change only the fixture's initial answer to a valid v=DMARC1;p=none record. Policy discovery selects this Author Domain record and its p value. Relaxed alignment may still require organizational-domain work, depending on the authenticated identifiers and the shortcuts in section 4.10.2. Do not reuse “policy lookup stopped” as proof that every possible alignment lookup also stops.
A strict-alignment comparison uses equality of the relevant domain strings. Another specified shortcut applies when the Author Domain and all authenticated identifiers are the same domain and that domain has a valid policy record. Otherwise, passing SPF and DKIM identities can require additional walks. The eight-query limit is per walk, not a promise that an entire message involves only eight DNS requests.
Make the depth limit visible
The generic walk queries a candidate, discards non-DMARC TXT material, and discards all DMARC policy records at that target if more than one remains. A single record containing psd=n or psd=y ends the walk. Without that stop, label removal follows the prescribed depth rule, not an unlimited parent-by-parent loop.
For the fictional nine-label name a.b.c.d.e.f.g.h.example, the initial lookup uses that complete name with _dmarc prepended. The next candidate is c.d.e.f.g.h.example, shortened to seven labels. Subsequent candidates are d.e.f.g.h.example, e.f.g.h.example, f.g.h.example, g.h.example, h.example and example. Each receives the _dmarc prefix. With no earlier stopping condition, these are eight candidate queries. The eight-label intermediate b.c.d.e.f.g.h.example is deliberately skipped.
This means a deeply nested administrative boundary can be missed when it is not the initial target. RFC 9989 section 5.1.8 explains the consequence for complex organizations and requires an exact Author Domain record for the described greater-than-eight-label case. A proposed test should include both the skipped boundary and the explicit initial record, rather than assuming that every ancestor is visited.
Classify errors without inventing a policy
Confirmed absence is different from a transient resolution failure. Section 4.10.1 prohibits applying DMARC when discovery produces no policy record through absence, while leaving handling of DNS errors to receiver discretion. A receiver may defer temporarily or choose a fail-open approach. SERVFAIL is not a negative existence proof and must not be inserted into the fixture as though it meant “continue normally with no record.”
An empty answer also needs interpretation. RFC 2308 section 2.2 distinguishes NODATA from referral and alias situations. Preserve question name, type, response code, authority context and alias chain. A missing _dmarc child does not establish that the Author Domain itself is nonexistent. That is a separate question used when selecting between sp and np.
Retain a trace that another engineer can challenge
The exact commission is: Build a concrete DNS tree and trace the current RFC algorithm against it. The pre-draft fictional tree provides a manually derived expected trace, but no controlled DNS fixture or receiver execution has been retained. The commissioned original-evidence gate therefore remains open. A future authorized test should preserve every candidate name, candidate record, rejection reason, stop condition, selected policy domain and alignment output.
Record resolver and receiver versions, observation time, cache context and the approved fixture version. Compare the actual trace with the expected one before changing anything. Current errata verification, technical SME review, production applicability, visual checks and owner release are still pending. A transparent expected trace is useful preparation; it is not an interoperability result.