A config is a record of zones, each a list of Record union members. The interpreter evaluates the whole program at startup, then walks the normal form into the server's in-memory zone table.
let Record = < A : { name : Text, ttl : Natural, value : Text }
| AAAA : { name : Text, ttl : Natural, value : Text }
| CNAME : { name : Text, ttl : Natural, value : Text }
| TXT : { name : Text, ttl : Natural, value : Text }
| MX : { name : Text, ttl : Natural, priority : Natural, exchange : Text }
| NS : { name : Text, ttl : Natural, value : Text }
| SOA : { name : Text, ttl : Natural, mname : Text, rname : Text
, serial : Natural, refresh : Natural, retry : Natural
, expire : Natural, minimum : Natural }
| CAA : { name : Text, ttl : Natural, flags : Natural, tag : Text, value : Text } >
in let Zone = { name : Text, records : List Record }
in let Config = { zones : List Zone }Owner names are relative to the zone (@ / "" = apex). rdata target names (CNAME/NS value, MX exchange, SOA mname/rname) are absolute FQDNs with a trailing dot.
Dhall program, not a file — so it is typechecked against its schema before the server ever binds a port.type error (e.g. a bad union label or value), reported at load.config.example.dhall for a full two-zone example.