# dns.squish.net / dnstraverse — Reference Behaviour Spec Compiled 2026-07-07 for diffing ExploreDNS against the original. Source precedence used throughout: **archived/live site output > Ruby source (squish/dnstraverse @ 733cc0b, v0.1.13) > secondhand accounts**. Each claim is tagged [LIVE] (probed 2026-07-07), [WB] (Wayback capture, date given), [SRC] (Ruby source file), or [DOC] (author's own docs at www.squish.net/dnstraverse/). Raw artifacts referenced are preserved under `/private/tmp/claude-502/-Users-ghansen-src-ExploreDNS/8c18e9d7-a07d-43e8-a21b-b9aad8182912/scratchpad/` (subdirs `squish/`, `websweep/`, Ruby clone in `dnstraverse/`). --- ## 1. Availability **The site is UP.** [LIVE] `https://dns.squish.net/` and `http://dns.squish.net/` both return HTTP 200 (Cloudflare edge; backend `X-Powered-By: Phusion Passenger 5.0.30`, Rails session cookie `_dnstraverseweb_session`). Footer: **"UI 2.0.1 / Engine 0.1.14"** — the engine is the Ruby `dnstraverse` gem; the Rails wrapper ("dnstraverseweb") is closed-source (not in any public repo of GitHub user `squish`). "Kindly hosted by the ISC"; author James Ponder. Practical constraints on the live site: - Anonymous submission requires solving a Google reCAPTCHA v2 (a captcha-less POST to `/traverses/create_anon` gets 302 → `/` with flash `Sorry, the captcha did not succeed, please try again.`). [LIVE] - **Old traverse data is purged**: pre-2026 traverse IDs still return the page shell (Name/Type/Date), but `/fetch` replies only `setTimeout("poll()", 1000);` forever and `/detail/fetch` replies `count = 0; setTimeout("poll()", 1000);` — results are never re-rendered. [LIVE] So a fresh captcha-solved run in a browser is the only way to capture new complete output. Best archival/primary sources, in order of authority: 1. **Wayback Machine** — ~4,076 archived `/traverses/<32-hex>` show pages and 114 `/detail/fetch` RJS streams (CDX API). Best complete artifacts: careerhosts.net/A show+detail+servers (2016-03), learningsuite.byu.edu/A (2015-03), dadzi.ir/A all-failure (2019-06), www.ilpd-afrique.com/A NXDOMAIN (2017-11), intellivida.ca/A mixed (2011-09), www.nike.com CNAME chain detail/fetch (2018-03), `/info?packet=N` popups (aruba.it, 2021-01). Site captured live as recently as 2026-06-20; page wording is essentially unchanged 2011→2026 (engine only moved 0.1.11→0.1.14), so any era is representative. [WB] 2. **Ruby engine source** — github.com/squish/dnstraverse master @ 733cc0b (2011-12-17, v0.1.13; rubygems shows 0.1.14 released 2012-04-30). Cloned locally; this is the exact engine behind the site. 3. **Author's engine docs** — `http://www.squish.net/dnstraverse/` (+ manual.html, switches.html), live. [DOC] 4. **Old v1 Perl service** — `http://www.squish.net/dnscheck/dnscheck.cgi` **still executes live queries with no captcha** (verified 2026-07-07; full www.example.com/A run captured). It is a different, cruder engine (author's FAQ: the new one "is more accurate than the Perl-based dnscheck service, including DNS bailiwick concepts, simulation of the resolver cache"; v1 source "is not available") — useful only for cross-checking aggregate percentage math, not wording. --- ## 2. Inputs ### 2.1 Web form (dns.squish.net, confirmed identical 2011→live 2026) [LIVE][WB] Form `id=new_traverse`, POST `/traverses/create_anon`, submit button `name=commit value=Create`: | Field | Details | Default | |---|---|---| | `traverse[domain_name]` | text, size 30, hint "e.g. www.example.com". Help: "This is the full DNS entry to check. For example: www.google.com, news.bbc.co.uk, or www.cnn.com" / "If your web site is http://www.example.com/ you should enter the www.example.com component only." | (empty) | | `traverse[domain_type]` | select, options exactly in order: **A, NS, MX, PTR, TXT, AAAA, SOA, SPF**. Caption: "Leave as 'A' unless you know what you're doing." Help notes PTR format is `D.C.B.A.in-addr.arpa`. | **A** | | Human Check | reCAPTCHA v2 (sitekey `6LdIf08UAAAAAJgYP1bvi7vmf-EXEHWXH_AqthF9`), required for anonymous; "Registration is optional, but means you don't need to enter a reCAPTCHA every time!" | — | | `authenticity_token` | Rails CSRF, session-bound | — | That is the **entire** web surface: no root-server, depth, retries, UDP size, fast-mode or IPv6 options ("Currently this is IPv4 only."). Success redirects to `/traverses/<32-hex-id>` (ID is random per submission, **not** md5(name/type) — tested [WB]; "Friendly URLs for emailing"). Other routes: `/traverses//detail`, `/traverses//servers`, `/traverses//info?packet=N`, POST `/traverses//fetch` and `/detail/fetch?count=N` (1 s Prototype.js polls); `/login`, `/register`; `/traverses` index requires login. Note the web type menu (adds SPF; lacks SRV/WKS/CNAME/HINFO/MINFO/ANY) is a deliberate restriction of the engine's larger CLI list. ### 2.2 CLI options (`dnstraverse [options] DOMAIN`) — [DOC manual.html, confirmed against SRC bin/dnstraverse] | Option | Meaning | Default | |---|---|---| | `-v/--[no-]verbose` | verbose progress ([qname]/ shown) | false | | `-d/--[no-]debug` | debug; twice = library debug | 0 | | `-r/--root-server HOST` | initial root | nil (ask local resolver) | | `-a/--all-root-servers` | traverse all roots | **false** (one root) | | `-t/--type TYPE` | A, AAAA, SRV, WKS, NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY | `:a` | | `--udp-size SIZE` | 512 turns EDNS0 off | **2048** | | `--allow-tcp` | retry over TCP on truncation | true | | `--always-tcp` | | false | | `--max-depth DEPTH` | | **20** | | `--retries TIMES` | "Number of 2s retries before timing out" | **2** | | `--[no-]follow-aaaa`, `--[no-]root-aaaa` | documented "isn't implemented yet" | false | | `--[no-]show-progress` | | true | | `--[no-]show-resolves` | | false | | `--[no-]show-servers` | | false | | `--[no-]show-versions` | | true | | `--[no-]show-all-stats` | | false | | `--[no-]show-results` | | true | | `--[no-]show-summary-results` | | true | | `--save-objects` | | false | | `--[no-]fast` | "Fast mode (default true) turn off to be more accurate" | **true** | | `-q/--quiet`, `-V/--version`, `-h/--help` | | | Caveat [SRC]: the `Traverser` library class internally defaults to maxdepth 10 / udpsize 512 / fast false — the **CLI overrides** to 20/2048/true, and observed web behaviour matches the CLI-style config (fast mode "completed earlier" labels, single root), except the web's packet dumps show **EDNS0 payloadsize 4096** [WB 2021 `/info?packet` pages] — the web app evidently runs with udp_size 4096, not 2048. Archived output wins here. ### 2.3 Old v1 form (www.squish.net/dnscheck/v1.html — different engine, listed for completeness) [LIVE] `host` text; `type` select: Choose…/A/SOA/CNAME/MX/NS/PTR/AAAA/ANY; checkboxes (checked by default unless noted): show_rootservers, findroot (unchecked), removebroken, cnameprocessing ("Indirect through CNAMEs encountered"), show_mainworkings, show_resolving (unchecked), show_allservers, getbindversions; `retries`=3 (exponential delay); `querylevel`=10 (max query depth). --- ## 3. Traversal semantics All from [SRC] unless noted; web/CLI observations corroborate. ### 3.1 Entry and roots - `Traverser#run_query` builds a root pseudo-Referral ("rootroot", server=nil) with qname/qtype and runs an **explicit stack loop** (not recursion); `:calc_resolve`/`:calc_answer` markers give post-order stats computation after all children finish. - **Default is ONE root server** per run: `get_a_root` queries `'' NS` at the local resolver and picks the first root with an A record in additional (else resolves root names). `--all-root-servers` asks that root for the full set. Rationale [DOC FAQ]: "since most DNS problems are not because of a root server problem, the default mode is to only use one." The web service also uses a single root, which **varies per run** (f/m/e/b roots observed): detail page shows `Initial Root: f.root-servers.net, 192.5.5.241` + `(1 roots returned)` [WB]. Rootroot's children (one per root) combine with equal weight. ### 3.2 Branching - `Referral#process` queries **each IP** of the current server (recursion-desired off; EDNS0 OPT added when udp_size>512). Children referrals are created for statuses `:referral` and `:restart` — one child per nameserver returned in the referral, **including glueless ones** (shown with empty parens `ns1.virtualempire.com ( )` on the web [WB]). Child order is randomized per run [WB]. - **Refids**: dotted path per node — `1`, `1.1`, `1.1.1`… Children number from 1; a **resolve subtree inserts a `.0` component** (e.g. `1.2.0.1`); nested resolves nest further (`1.1.2.0.1.4.2.0.2.0.2` observed [WB]). If more than one IP of a server produced children, an extra "childset" digit is added. - **Depth limit**: refid components excluding `0` counted against maxdepth (CLI/web 20); exceeding injects RuntimeError `Maxdepth N exceeded` as an `:exception` response. ### 3.3 Response classification (`DecodedQuery#process`, in order) 1. network exception → `:exception` 2. follow CNAMEs **within the message** (`msg_follow_cnames`; a chain leaving the bailiwick stops following and returns the target; an in-message loop returns nil → `:cname_loop`) 3. rcode != NOERROR → `:error` with messages: `Formate error (FORMERR)` [sic, typo in source], `Server failure (SERVFAIL)`, `No such domain (NXDOMAIN)`, `Not implemented (NOTIMP)`, `Refused`, else rcode string 4. answers exist for endname/qtype → `:answered` 5. endname != qname (CNAME landed elsewhere) → `:restart` 6. SOA in authority, or no NS in authority → `:nodata` 7. NS in authority → `:referral`; else `:restart` Response layer adds `:referral_lame`; the resolve phase adds `:noglue` and `:loop`. Full outcome vocabulary: **answered, nodata, referral, restart, referral_lame, error, exception, cname_loop, noglue, loop**. ### 3.4 Bailiwick and per-branch cache - `inside_bailiwick?(name)` = bailiwick nil, or name == bailiwick (case-insensitive), or name ends with `.`. - `msg_cacheable` partitions **all** sections (answer/authority/additional; OPT discarded) into in-bailiwick "good" (cached) vs out-of-bailiwick "bad" (discarded). [DOC FAQ confirms: "keeps track of the bailiwick from the referring parent and discards entries that are outside… additional record hints are typically ignored".] - **InfoCache is hierarchical per branch** (each Response creates `InfoCache.new(parent)`); `add()` clears same name:class:type key before storing; lookups recurse to the parent. `get_startservers(domain)` walks labels upward to the nearest cached NS RRset; returns `[{:name, :ips-or-nil}]` plus newbailiwick = NS owner. - **Lame referral detection**: a `:referral` becomes `:referral_lame` unless the new zone is *strictly deeper* than the current bailiwick (`starters_bailiwick =~ /\.#{bailiwick}$/i`, or bailiwick nil). Warning `Referred authority names do not match query cache expectations` when starter names ≠ referred NS names. ### 3.5 Glue / resolve / loop - Child with ips=nil: if the server name is **inside the current bailiwick** with no glue → `:noglue` dead end (probability mass retained). [DOC FAQ: "dnstraverse has nobody to go to next, so this error is generated as the domain is unreachable."] - If an ancestor Referral had the same qname/qclass/qtype/server with unresolved IPs → `:loop` dead end. - Otherwise a **resolve sub-traversal** for `A ` starts (refid `.0.` component), starting from `get_startservers(server)` in this branch's cache — never the local resolver [DOC FAQ]. Every `:answered` leaf of the resolve distributes its probability evenly across returned A records into `serverweights[ip]`; non-answered outcomes carry the failure probability up as pseudo-IP `key:...` entries. ### 3.6 Probability model (exact) - On Referral creation with known IPs: `serverweight = 1.0/serverips.length` per IP. - `stats_calculate_children(stats, children, weight)`: `percent = (1.0/children.length) * weight`; each child stat's prob accumulates `child_prob * percent`. I.e. **equal split among sibling children, multiplied down the tree**; all root-level probabilities sum to 1.0. - Leaf aggregation key: `key:#{status}:#{ip}:#{server}:#{qname}:#{qclass}:#{qtype}` (+`:#{exception message}` for :exception, +`:#{parent_ip}` for :referral_lame; NoGlue/Loop use `key:#{status}:#{ip}:#{qname}:#{qclass}:#{qtype}:#{server}:#{bailiwick}`). Identical keys merge by adding prob. - **Summary** groups by status, summing probs; answered entries additionally grouped by sorted rdata strings joined `@@@` (so one summary line per distinct RRset content). - Corroborating observations: 13 gTLDs → 7.7% each; 7 google NS → 14.3%; 2 NS → 50.0%; 3 → 33.3%; 4 → 25.0% [WB, DOC]; deep resolve failures → 0.2%/0.0% [mcgill.org.za CLI run, 2017]. ### 3.7 Fast mode and low-level cache - **Fast mode (default on)**: global hash keyed `"#{qname}:#{qclass}:#{qtype}:#{server}:#{txt_ips_verbose}".downcase` (txt_ips_verbose embeds per-IP weights like `50.0%=1.2.3.4`). A completed `:normal` Referral with no `:referral_lame` response is stored; a hit replaces the child before processing and marks it "completed earlier". [DOC FAQ: fast mode "will make the assumption that the cache won't make any difference to the result"; normal mode re-walks because per-branch caches may differ.] - Independently, a **low-level packet cache** ensures each (server IP, question, udp_size) is asked only once per run regardless of options (`CachingResolver`, key `key:res:#{ip}:#{name}:#{klass}:#{type}:#{udp_size}`). ### 3.8 CNAME restarts `:restart` children are built like referrals but with qname = CNAME target, starters from the **per-branch cache** — so the restart resumes from the deepest cached zone, not always the root. Confirmed [WB www.nike.com 2018 detail/fetch]: restart for `www-geo.nike.com.akadns.net` began at a root (nothing cached); later restarts began directly at `` / `` servers. Each restart adds a new Query Key legend entry; in CLI the bracketed qname simply changes mid-tree (`[www.google.com]` → `[www.l.google.com]`) with refid numbering continuing. In-packet CNAME chains are followed silently inside one response (byu.edu answers show only the target's A records [WB 2015]). ### 3.9 Resolver details Retries default 2 (2 s delay, 2 s timeout); recurse off; dnssec off; src 0.0.0.0. EDNS fallback: on FORMERR/NOTIMP/SERVFAIL with udpsize>512, retry at 512; success adds warning `#{answerfrom} doesn't seem to support EDNS0`. Other warnings: `... allows recursion`, `... doesn't allow recursion` (local queries), `... sent truncated packet`. IPv4 only. --- ## 4. Output format ### 4.1 Web show page `/traverses/` [WB, structure confirmed LIVE] Details table: **Name / Type / Date** (e.g. `2016-03-13 19:05:26 -0700`; live 2013 shell shows UTC) and, while running, **Progress** (` - ` + integer percent, e.g. `1.9 - testcname.yellowtealpurple.net` / `61%`, updated by 1 s polls to `/fetch`). Then: **Summary** (`div#traverse_summary_stats`, heading "Summary"): ```html
100% answered with
careerhosts.net. 86400 IN A 38.71.67.100
``` [WB 2016 careerhosts.net]. Percent format = `sprintf("%.1f%%", prob*100).sub(/\.0%/, '%')` right-justified to width 5 [SRC summary_stats.rb:135-136] — so `100%`, ` 93.3%`, ` 6.7%`, ` 50%` (archived HTML shows the `100%` case unpadded; padding is whitespace-collapsed in rendering). Category wordings [SRC:76-99, all confirmed in WB captures except the last three]: `N% answered with `, `found no such record`, `resulted in a lame referral`, `resulted in an exception`, `resulted in an error`, `found no glue`, `resulted in a loop`, `resulted in a CNAME loop`. Multiple RRs join with `
`; CSS renders the answer italic, offset under its line. Observed mixes: `93.3% answered with … / 6.7% resulted in an exception` [WB 2011 intellivida.ca]; `100% resulted in an error` (all-NXDOMAIN) [WB 2017]; `100% resulted in an exception` [WB 2019 dadzi.ir]; `100% resulted in a lame referral` [WB 2013 g-p.es]. **Results** (`div#results`, heading "Results"), one `

` per aggregated outcome, percent as `%5.1f%%` (no colon on web): ```html

50.0% Answered from ns1.virtualempire.com (38.71.66.4)

careerhosts.net.	86400	IN	A	38.71.67.100

``` (note **two spaces after "from"**, tab-separated dig-style RRs in `
`; failure lines have no `
`). Verbatim failure catalogue from archived pages [WB]:
- `No such domain (NXDOMAIN) at ns1.cctld.co (156.154.100.25)`
- `Query timed out at ns2.twisted4life.com (194.152.92.62)`
- `Server failure (SERVFAIL) at casper.ln1x.ablesky.com (173.255.217.216)`
- `Refused at ns1.afdns.net (190.183.61.2)`
- `NODATA (for this type) at ns1.iranfirewall.in (148.251.110.146)`
- `Lame referral received from f.nic.es (130.206.1.2) to dns2.namecheaphosting.com (69.160.33.71)` — web adds "received"; CLI says `Lame referral from …` [SRC referral.rb:506]
- `recvfrom failed from 185.208.174.92; No route to host - recvfrom(2) at ns1.dadzi.ir (185.208.174.92)` (exception text verbatim from Ruby)
- Failures inside a resolve append `
While querying ns1.twisted4life.com/IN/A
` (CLI: `While querying #{qname}/#{qclass}/#{qtype}`). Then links: **"Traversal detail"** → `/detail`; **"Server location and version information"** → `/servers`; while running: "Please wait while your traversal is completed, or alternatively watch the traversal as it progresses." ### 4.2 Web detail page `/traverses//detail` [WB streams; shell confirmed LIVE] Adds table rows **Initial Root** (`f.root-servers.net, 192.5.5.241` + `(1 roots returned)`) and **Query Key** — one coloured dotted-border chip per query, text like `A careerhosts.net`; colours cycle `#fefecc, #ccfecc, #ccfefe, #ccccfe, #feccfe, #fee5cc`. Banner node: `Traversing for careerhosts.net type A starting at the root(s)`. Tree rows are `div.node_line` tables: indentation drawn with 32×23 px spacer images (`spacer_gap/line/tee/end.png`); node text is `#{server} (#{ip}) <#{bailiwick}>` (root renders `<>`; glueless renders `( )` with a placeholder span later filled, truncated by the UI, e.g. `95.130.252.149,Loop encounter...`). Node extras: progress spinner → status icon linking `info_url('/traverses//info?packet=N')` (`referral.png` / `success.png` / `warning.png`), `show resolve`/`hide resolve` toggle revealing the hidden `.0` resolve subtree, and italic `completed earlier` span for fast-mode hits. Colour lifecycle: inserted muted (`#ededdd`; resolve nodes `#ddeddd`) → active `border:1px solid black` + query-key colour → completed. Updates arrive as Prototype.js RJS from `/detail/fetch?count=N` (`Element.insert`, `visualEffect`, `setStyle`), each chunk ending `count = N; setTimeout("poll()", 1000);`. On completion: Results injected (same stats_line HTML as show page), then a **Fingerprinting** phase cycling every server name, then the "further" (servers) link appears. ### 4.3 Web packet popup `/info?packet=N` [WB 2021] `

What is arudns1.aruba.it type A?

` + `

Answer from 192.12.192.5 (dns.nic.it)

` + `
` dnsruby dump (`;; Answer received from 192.12.192.5 (189 bytes)`, `;; Security Level : UNCHECKED`, header/flags/sections, `OPT pseudo-record : payloadsize 4096, xrcode 0, version 0, flags 0`) + `

Status: referral

` "A referral occured. This means that the resolver did not know the answer, but indicated that results can be found elsewhere." (or `Status: answered` / "The server was able to answer the question successfully.") + `

The following records were considered worthy of caching:

` + `

These servers were chosen in bailiwick 'aruba.it' for the referral:

` (`name (ip)` lines) + `

Results after processing this node and all branches beneath:

` with subtree-scoped stats_lines. Fast-mode variant prepends blue `This was completed earlier (fast mode)`. ### 4.4 Web servers page `/traverses//servers` [WB 2016/2025; shell LIVE] Google map + `table#servers_table`, columns exactly: **Country | City | Area code | Postal code | Servers | Software guess |** (+Show on map). Servers cell: `38.71.66.4 (ns1.virtualempire.com)
…` grouped by geolocation; Software guess: ` ISC BIND 9.2.3rc1 -- 9.4.0a4 (9.6.1-P1)`, ` VeriSign ATLAS ` (2025 adds ` (ATLAS)` suffix), ` TIMEOUT`, ` No match found`. Fingerprint DB is fpdns-derived ("Portions Copyright (c) 2003,2004,2005 Roy Arends & Jakob Schlyter"). ### 4.5 CLI output [DOC home page sample + mcgill.org.za 2017 run + SRC] Header (unless -q): `# Using fast mode` / `# Limiting traverse to one root` / `# UDP size N (EDNS0 is on)` [always prints "on" due to source bug `options[:udpsize == 512]`] / `# Retries N, max depth N` / `# Allow TCP is true, always TCP is false`; then `Using E.ROOT-SERVERS.NET (192.203.230.10) as initial root` / `Running query www.google.com type a`. Progress, verbose (`refid [qname] server (ips) `) [DOC, verbatim]: ``` 1 [www.google.com] E.ROOT-SERVERS.NET (192.203.230.10) <> 1.1 [www.google.com] B.GTLD-SERVERS.NET (192.33.14.30) 1.1.1 [www.google.com] ns1.google.com (216.239.32.10) 1.1.1.1 [www.l.google.com] a.l.google.com (209.85.139.9) ``` Non-verbose omits `[qname]`/`` [mcgill 2017, verbatim]: ``` 1.2.2 ns1.coza.net.za -- resolving 1.2.2 ns1.coza.net.za (66.135.62.20,Loop encountered resolving ns.coza.net.za) 1.3.1 ns4.iafrica.com (196.7.142.131) -- completed earlier (1.2.3) ``` `Results:` — blocks with `printf "%5.1f%%: "` then per status [SRC referral.rb:503-532]: `Answer from ()` + RRs indented 12 spaces; `No glue at () for `; `Lame referral from () to ()`; `Loop encountered at `; `CNAME loop encountered at `; ` at ()`; `NODATA (for this type) at ()`; ` at …`; fallback `Stopped at ())` [trailing `)` is a source bug]; plus `While querying //` when the failing query differs. [DOC, verbatim]: ``` 14.3%: Answer from e.l.google.com (209.85.137.9) www.l.google.com. 300 IN A 74.125.77.99 ``` `Summary Results:` — same wording set as web (Section 4.1), prefix two spaces, e.g. ` 99.8% answered with co.za. 3600 IN NS ns0.is.co.za.` … ` 0.2% resulted in a loop` [mcgill 2017]. RR whitespace collapsed to single spaces; continuation RRs aligned under text start. `--show-servers`: `The following servers were encountered:` then `printf "%#{w}s: %-15s%s"` rows sorted by lowercased reversed name [DOC, verbatim]: ``` ns1.google.com: 216.239.32.10 ISC BIND 9.2.3rc1 -- 9.4.0a0 (9.4.2-P1) a.gtld-servers.net: 192.5.6.30 VeriSign ATLAS ``` ### 4.6 Legacy v1 (Perl dnscheck) — different engine, different wording [LIVE run 2026-07-07] Nested-table HTML; sections: root-server workings and SOA-serial check, then `Traversal of DNS for .` with units `Asking a.gtld-servers.net (192.5.6.30) for www.example.com (type A)` / `Referral: example.com is at hera.ns.cloudflare.com (108.162.192.162)` / `Response is:` with per-branch `16.7% () with `; dedupe `[see above for results]`; final `Results`: `16.1% of queries will be returned by 108.162.195.228 (elliott.ns.cloudflare.com)` + RRset, `3.5% of queries will end in failure at too many nested queries`, `0.0% of queries will end in failure at 192.5.6.30 (a.gtld-servers.net) - failed to resolve h.gtld-servers.net due to 192.5.6.30 - nameserver loop detected`. **Do not copy this wording into ExploreDNS comparisons against dns.squish.net** — only the aggregate math (probability multiplication/summation) transfers. --- ## 5. Confidence notes **Confirmed by primary sources (archived/live site output + Ruby source agree):** - Web form fields/defaults, routes, captcha behaviour, polling protocol (LIVE + WB, identical 2011–2026). - Single-initial-root default, equal-split probability model and exact aggregation formulas, bailiwick filtering, hierarchical per-branch cache, fast mode, refid scheme with `.0` resolve subtrees, CNAME restart-from-cache, depth 20 / retries 2 (SRC, corroborated by WB output and DOC). - Result/Summary wording and percent formatting for: answered, error (NXDOMAIN/SERVFAIL/Refused), exception (timeout/recvfrom), nodata, lame referral, "While querying" suffix (WB verbatim + SRC format strings, verified in the local clone: `summary_stats.rb:76-99,135-136`, `referral.rb:503-532`). - CLI output shapes (DOC's own annotated sample + one full independent 0.1.14 run from mcgill.org.za 2017 + SRC). **Confirmed by source only (never seen in captured output):** web wording for `noglue` ("found no glue" / "No glue at X (ip) for Y"), `loop` and `cname_loop` result/summary lines on the *web* (CLI loop lines are confirmed via mcgill); `Stopped at` fallback; `Formate error (FORMERR)` typo; fast-cache key details; lame-referral "strictly deeper zone" rule. These are near-certain — the site runs this gem — but flagged CONFIRMED-by-source, not by output. **Known divergences to be careful with when diffing:** web "Answered from␣␣" (double space) vs CLI "Answer from"; web "Lame referral received from" vs CLI without "received"; web EDNS payloadsize 4096 vs CLI default 2048 (archived output preferred for the web service); library-vs-CLI internal defaults (10/512/false vs 20/2048/true); source bugs worth deciding whether to replicate (`(9.4.2-P1)`-style CLI EDNS banner always "on", `Stopped at …)` stray paren, answered-merge prob discard in `stats_display`, "CNANE loop" typo in `DecodedQuery#to_s`). **Not recovered / open items:** - The Rails front-end (dnstraverseweb) source — closed; web-only wording is reconstructed from captures. - Exactly one engine version gap: site runs 0.1.14; the cloned source is 0.1.13 master (rubygems has 0.1.14; diff not fetched — format strings match 0.1.14 outputs observed, so risk is low). - No archived web sample of a *completed* SPF/TXT/SOA traversal, of the web progress-percent computation, or of web noglue/loop/cname_loop result lines. - A fresh end-to-end capture is achievable: the live site works behind one reCAPTCHA — solve it once in a browser and record `/traverses/`, `/detail` (streaming XHRs to `/fetch` and `/detail/fetch`), and `/servers`. The author's test domains `yellowtealpurple.net` / `testcname.yellowtealpurple.net` (seen Aug 2025) are candidate CNAME test vectors. The v1 CGI remains captcha-free for aggregate-math cross-checks. Where sources conflicted, archived site output was used (traverse IDs random not md5 — WB tests; EDNS 4096 on web — WB packet dumps; web "received"/double-space wordings — WB HTML), with the Ruby source as tie-breaker for everything unobserved.