Shared plain-data contract for mix mail.doctor runtime results.
The result shape is the single source of truth for both human and JSON output. Formatters must consume this data directly rather than scraping text.
Status Contract
Findings use a closed status set:
:pass:warn:fail:cannot_verify
:cannot_verify is a first-class outcome. Resolver uncertainty, missing
explicit DKIM selectors, and malformed DNS answers must stay visible as data
instead of being coerced into :fail.
Summary
Types
@type status() :: :pass | :warn | :fail | :cannot_verify
@type summary() :: %{ pass: non_neg_integer(), warn: non_neg_integer(), fail: non_neg_integer(), cannot_verify: non_neg_integer() }
@type t() :: %{ schema_version: pos_integer(), domain: String.t(), dkim_selectors: [String.t()], summary: summary(), findings: [finding()], facts: facts(), resolver_errors: [resolver_error()] }
Functions
@spec empty_facts() :: %{spf: %{}, dkim: %{}, dmarc: %{}, mx: %{}, bimi: %{}}
@spec empty_summary() :: %{pass: 0, warn: 0, fail: 0, cannot_verify: 0}
@spec schema_version() :: 1
@spec statuses() :: [status(), ...]