A trial run of the image against live DNS reported eeqj.de as inconsistent on every DNS cycle. The nameservers agree: y.ns.joker.com. answers with upper-case names (ASPMX.L.GOOGLE.COM., x.ns.joker.COM.) while x.ns.joker.com. and z.ns.joker.com. answer in lower case, and DNS names are case-insensitive (RFC 4343).
The watcher compares record values as plain strings (recordsEqual in internal/watcher/watcher.go). The inconsistency check therefore fires on letter case alone, and a nameserver that changes the case it answers in would also raise a record-change alert.
Definition of done
Record sets that differ only in the letter case of DNS names (NS, MX, CNAME and SRV targets and the like) count as equal, for both the inconsistency check and the record-change check. TXT and CAA values keep exact comparison.
A test covers record sets that differ only in letter case.
No DNS mocking. make check green.
Model: opus-5-5
A trial run of the image against live DNS reported `eeqj.de` as inconsistent on every DNS cycle. The nameservers agree: `y.ns.joker.com.` answers with upper-case names (`ASPMX.L.GOOGLE.COM.`, `x.ns.joker.COM.`) while `x.ns.joker.com.` and `z.ns.joker.com.` answer in lower case, and DNS names are case-insensitive (RFC 4343).
The watcher compares record values as plain strings (`recordsEqual` in `internal/watcher/watcher.go`). The inconsistency check therefore fires on letter case alone, and a nameserver that changes the case it answers in would also raise a record-change alert.
## Definition of done
- Record sets that differ only in the letter case of DNS names (NS, MX, CNAME and SRV targets and the like) count as equal, for both the inconsistency check and the record-change check. TXT and CAA values keep exact comparison.
- A test covers record sets that differ only in letter case.
- No DNS mocking. `make check` green.
Model: opus-5-5
Plan. Record values are built in one place, extractRecordValue in internal/resolver/iterative.go. Lower-case the DNS names there (the CNAME, MX, SRV and NS targets) and leave A, AAAA, TXT and CAA values as they are. The inconsistency check and the record-change check then both compare lower-case names without any change to recordsEqual, and the dashboard and alerts show one spelling. extractNSSet in the same file already lower-cases nameserver names the same way.
Test: a table test of extractRecordValue, with records built in the test: mixed-case MX, NS, CNAME and SRV targets come out lower case, TXT and CAA values keep their case. It calls a formatting function with no resolver, server or response involved, so it is not a DNS mock. The live-DNS tests stay as they are.
Disclosure for the PR: saved state from before this change can hold upper-case names, so the first check after upgrading reports a one-time record change for those records. dnswatcher is not deployed anywhere yet.
Model: opus-5-5
Plan. Record values are built in one place, `extractRecordValue` in `internal/resolver/iterative.go`. Lower-case the DNS names there (the CNAME, MX, SRV and NS targets) and leave A, AAAA, TXT and CAA values as they are. The inconsistency check and the record-change check then both compare lower-case names without any change to `recordsEqual`, and the dashboard and alerts show one spelling. `extractNSSet` in the same file already lower-cases nameserver names the same way.
Test: a table test of `extractRecordValue`, with records built in the test: mixed-case MX, NS, CNAME and SRV targets come out lower case, TXT and CAA values keep their case. It calls a formatting function with no resolver, server or response involved, so it is not a DNS mock. The live-DNS tests stay as they are.
Disclosure for the PR: saved state from before this change can hold upper-case names, so the first check after upgrading reports a one-time record change for those records. dnswatcher is not deployed anywhere yet.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
A trial run of the image against live DNS reported
eeqj.deas inconsistent on every DNS cycle. The nameservers agree:y.ns.joker.com.answers with upper-case names (ASPMX.L.GOOGLE.COM.,x.ns.joker.COM.) whilex.ns.joker.com.andz.ns.joker.com.answer in lower case, and DNS names are case-insensitive (RFC 4343).The watcher compares record values as plain strings (
recordsEqualininternal/watcher/watcher.go). The inconsistency check therefore fires on letter case alone, and a nameserver that changes the case it answers in would also raise a record-change alert.Definition of done
make checkgreen.Model: opus-5-5
clawbot referenced this issue2026-09-28 20:14:21 +02:00
Plan. Record values are built in one place,
extractRecordValueininternal/resolver/iterative.go. Lower-case the DNS names there (the CNAME, MX, SRV and NS targets) and leave A, AAAA, TXT and CAA values as they are. The inconsistency check and the record-change check then both compare lower-case names without any change torecordsEqual, and the dashboard and alerts show one spelling.extractNSSetin the same file already lower-cases nameserver names the same way.Test: a table test of
extractRecordValue, with records built in the test: mixed-case MX, NS, CNAME and SRV targets come out lower case, TXT and CAA values keep their case. It calls a formatting function with no resolver, server or response involved, so it is not a DNS mock. The live-DNS tests stay as they are.Disclosure for the PR: saved state from before this change can hold upper-case names, so the first check after upgrading reports a one-time record change for those records. dnswatcher is not deployed anywhere yet.
Model: opus-5-5