README accuracy sweep: architecture omissions, undocumented state field, overclaimed MAINTENANCE_MODE and /metrics #108
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A full claim-by-claim audit of
README.mdagainst the code atorigin/main(9347a28) found the document to be largely accurate — the HTTP route table, the environment-variable names and defaults, the state-file JSON field names, and most of the monitoring lifecycle all check out exactly. This issue collects the residual drift that is documentation-only.Substantive functional gaps found by the same audit are tracked separately in #104, #105, #106, and #107 and are explicitly not part of this issue.
Items to fix
1.
DNSWATCHER_MAINTENANCE_MODEis overclaimed. The README (README.md:251) says "Enable maintenance mode". The only thing it does is get copied into themaintenanceModefield of the healthcheck JSON response (internal/healthcheck/healthcheck.go:73). It does not pause the watcher, does not skip checks, does not suppress notifications, and does not change the healthcheckStatus, which is unconditionally"ok"(healthcheck.go:67). Reword to describe what it actually is: a flag surfaced in the healthcheck payload for external consumers to observe.2.
/metricsimplies application instrumentation that does not exist. The route servespromhttp.Handler()against the default registry (internal/server/routes.go:58-61), and there is not a singlepromauto-registered application metric anywhere in the codebase. So/metricsexposes generic Go runtime and process metrics only — no checks-performed counter, no notifications-sent counter, nothing dnswatcher-specific. The README's "Prometheus metrics (optional)" reads as though there is app-level instrumentation. Say plainly what is exposed.3. The Architecture tree omits real files.
README.md:189-208is missing:internal/config/classify.go— the Public Suffix List classification logic that the README's own domain-vs-hostname feature bullets (README.md:44-45,56-57) depend on.static/static.go— the//go:embed csspackage that implements the "all assets embedded in the binary" claim (README.md:168-170). The wholestatic/package is absent from the tree.internal/notify/history.go(the 100-entry alert ring buffer backing the dashboard's "Recent alerts"),internal/notify/retry.go(backoff/retry),internal/watcher/interfaces.go, and the individual handler filesdashboard.go/status.go/healthcheck.go.Nothing listed in the tree is fictional — every entry exists. This is purely about omissions.
4. The state-file
errorfield is undocumented. BothNameserverRecordState(internal/state/state.go:44-49) andCertificateState(:104-112) carryError string \json:"error,omitempty"`, and it is populated on certificate failures (internal/watcher/watcher.go:731`). It appears in the persisted JSON but appears nowhere in the README's State File Format example or field description.5. Notification delivery mechanics are undocumented. Neither the retry behaviour (
internal/notify/retry.go— up to 5 retries with 1s-60s exponential backoff and jitter, applied to all three backends) nor the 100-entry in-memory alert history (internal/notify/history.go) is mentioned in the Notifications section, though the latter is what the dashboard's "Recent alerts" panel reads from.6. Wildcard CORS on the public API is undocumented.
Middleware.CORS()(internal/middleware/middleware.go:172-187) setsAccess-Control-Allow-Origin: *across the API including/api/v1/status. That is a deliberate and policy-permitted choice for a public read-only API, but it is a fact about the HTTP surface that belongs in the README. Coordinate with #100, which changes the CORS configuration — document the end state, not the current one, and rebase if #100 lands first.7. Backward-compatible
PortStateloading is undocumented.internal/state/state.go:64-101special-cases loading old single-hostname state files into the current multi-hostname format. Worth a sentence in State File Format, since it is a compatibility guarantee operators may rely on.Definition of done
README.md.make fmtand include the result in the commit. Do not hand-wrap.make checkgreen;TODO.mdupdated in the same commit.The finishing commit's title must end with
(closes #N)referencing this issue.Sequencing note
This issue touches README sections that #100, #104, #105, and #106 also touch. Land it after those where they overlap, or expect to rebase. Do not preemptively document behaviour those issues have not implemented yet — the README must describe what the code does at the moment this merges.
Process note
This is a documentation-only change (
README.mdplusTODO.md, zero changes to code, config, scripts, CI, or build files). Per repo policy it therefore skips adversarial review and goes straight to the merge gate oncemake checkis green. If the implementation ends up touching any non-documentation file, that exemption is void and it goes through full review.