From 2a89d1dc7a931b2658ce27c31680ffe024202ccb Mon Sep 17 00:00:00 2001 From: sneak Date: Thu, 1 Oct 2026 22:23:05 +0000 Subject: [PATCH] docs: add the README sections policy requires (closes #173) REPO_POLICIES.md requires Getting Started, Rationale, Design and TODO sections in the README, and it had none of them. Getting Started clones the repository, builds the image and runs it watching example.com and www.example.com; DNSWATCHER_TARGETS is the only setting it requires. Rationale is drawn from what the README already says. The Architecture section moves below Entrypoints and is renamed Design, its text unchanged, so the required sections come in policy order. TODO points to TODO.md and the 1.0 milestone instead of copying the list. Model: opus-5-5 --- README.md | 127 ++++++++++++++++++++++++++++++++++++------------------ TODO.md | 4 +- 2 files changed, 87 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index c5461fb..e05c5f0 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,29 @@ Contributions that introduce mocked, faked, or stubbed DNS will be rejected. --- +## Getting Started + +You need git and Docker. This builds the image and runs dnswatcher watching +`example.com` and `www.example.com`: + +```sh +git clone https://git.eeqj.de/sneak/dnswatcher.git +cd dnswatcher +docker build -t dnswatcher . +docker run -d --name dnswatcher \ + -p 8080:8080 \ + -v dnswatcher-data:/var/lib/dnswatcher \ + -e DNSWATCHER_TARGETS=example.com,www.example.com \ + dnswatcher +``` + +The build also runs the linter and the test suite, which queries live DNS. Once +the container is running, the dashboard is at . With no +notification endpoint set, changes show only on the dashboard; see +[Configuration](#configuration) to add one. + +--- + ## Features ### DNS Domain Monitoring (Apex Domains) @@ -270,48 +293,6 @@ navigation needs, and its URL may name internal hosts. --- -## Architecture - -``` -cmd/dnswatcher/main.go Entry point (uber/fx bootstrap) - -internal/ - config/config.go Viper-based configuration - globals/globals.go Build-time variables (version) - logger/logger.go slog structured logging (TTY detection) - healthcheck/healthcheck.go Health check service - middleware/middleware.go HTTP middleware (logging, CORS, security - headers, metrics auth and rate limit) - handlers/handlers.go HTTP request handlers - server/ - server.go HTTP server lifecycle - routes.go Route definitions - state/state.go JSON file state persistence - resolver/resolver.go Iterative DNS resolution engine - portcheck/portcheck.go TCP port connectivity checker - tlscheck/tlscheck.go TLS certificate inspector - notify/notify.go Notification service (Slack, Mattermost, ntfy) - watcher/watcher.go Main monitoring orchestrator and scheduler - livednstest/livednstest.go Retry and concurrency limit for tests - against live DNS (imported only by tests) -``` - -### Design Principles - -- **No recursive resolvers**: All DNS resolution is performed iteratively, - tracing from root nameservers through the delegation chain to authoritative - servers. -- **No external database**: State is persisted as a single JSON file. -- **Dependency injection**: All components are wired via - [uber/fx](https://github.com/uber-go/fx). -- **Structured logging**: All logs use `log/slog` with JSON output in production - (TTY detection for development). -- **Graceful shutdown**: All background goroutines respect context cancellation - and the fx lifecycle. In-flight notification deliveries are drained on - shutdown, bounded by the shutdown timeout. - ---- - ## Configuration Configuration is loaded via [Viper](https://github.com/spf13/viper) with the @@ -665,6 +646,68 @@ configuration. --- +## Rationale + +dnswatcher exists to report every change to the DNS records, TCP port +availability and TLS certificates of its configured domains and hostnames, +failures and recoveries included: it is designed as a real-time change feed. It +queries the authoritative nameservers directly, tracing from the root, instead +of a recursive resolver, so no resolver's cache or filtering hides a change and +nameservers that disagree with each other are seen. Its state is a single JSON +file, so it survives a restart without an external database. + +--- + +## Design + +``` +cmd/dnswatcher/main.go Entry point (uber/fx bootstrap) + +internal/ + config/config.go Viper-based configuration + globals/globals.go Build-time variables (version) + logger/logger.go slog structured logging (TTY detection) + healthcheck/healthcheck.go Health check service + middleware/middleware.go HTTP middleware (logging, CORS, security + headers, metrics auth and rate limit) + handlers/handlers.go HTTP request handlers + server/ + server.go HTTP server lifecycle + routes.go Route definitions + state/state.go JSON file state persistence + resolver/resolver.go Iterative DNS resolution engine + portcheck/portcheck.go TCP port connectivity checker + tlscheck/tlscheck.go TLS certificate inspector + notify/notify.go Notification service (Slack, Mattermost, ntfy) + watcher/watcher.go Main monitoring orchestrator and scheduler + livednstest/livednstest.go Retry and concurrency limit for tests + against live DNS (imported only by tests) +``` + +### Design Principles + +- **No recursive resolvers**: All DNS resolution is performed iteratively, + tracing from root nameservers through the delegation chain to authoritative + servers. +- **No external database**: State is persisted as a single JSON file. +- **Dependency injection**: All components are wired via + [uber/fx](https://github.com/uber-go/fx). +- **Structured logging**: All logs use `log/slog` with JSON output in production + (TTY detection for development). +- **Graceful shutdown**: All background goroutines respect context cancellation + and the fx lifecycle. In-flight notification deliveries are drained on + shutdown, bounded by the shutdown timeout. + +--- + +## TODO + +[`TODO.md`](./TODO.md) names the next step and the steps planned after it. The +work for 1.0 is tracked as issues on the +[1.0 milestone](https://git.eeqj.de/sneak/dnswatcher/milestone/7). + +--- + ## License dnswatcher is released under the MIT License, Copyright (c) 2026 diff --git a/TODO.md b/TODO.md index a7e12ce..eaf87fe 100644 --- a/TODO.md +++ b/TODO.md @@ -19,6 +19,8 @@ trial run of the finished image: https://git.eeqj.de/sneak/dnswatcher/issues/149 # Completed Steps +- 2026-10-01: README has Getting Started, Rationale and TODO sections, and its + Architecture section is now Design, in the order policy sets (closes #173). - 2026-10-01: `make fmt` and `make fmt-check` cover Markdown with prettier, run in Docker at the version pinned by `yarn.lock` (closes #119). - 2026-10-01: `make fmt-check` fails on a file `goimports` would change; both @@ -116,7 +118,5 @@ trial run of the finished image: https://git.eeqj.de/sneak/dnswatcher/issues/149 - 1.0 readiness: run it with a real config and read the logs: https://git.eeqj.de/sneak/dnswatcher/issues/66 - README accuracy sweep: https://git.eeqj.de/sneak/dnswatcher/issues/108 -- README sections required by policy: - https://git.eeqj.de/sneak/dnswatcher/issues/173 - fixed root server order: https://git.eeqj.de/sneak/dnswatcher/issues/138 - review toward 1.0: https://git.eeqj.de/sneak/dnswatcher/issues/144