# Workflow * branch (from `next`) * do the work in Next Step * move Next Step to the top of Completed Steps * move the top item of Future Steps into Next Step * commit (`TODO.md` changes in the same commit as the work) * push * open a PR against `next` # Status pre-1.0. No git tags. Work lands on `next` by PR. Open work for 1.0 is tracked on the 1.0 milestone: https://git.eeqj.de/sneak/dnswatcher/milestone/7 # Next Step nameserver IP address changes: https://git.eeqj.de/sneak/dnswatcher/issues/105 # Completed Steps - 2026-10-01: a hostname is queried at the servers of the zone it is in, found by following delegations for the name, not its last two labels (closes #189). - 2026-10-01: `DNSWATCHER_SENTRY_DSN` reports panics in HTTP handlers to Sentry, and a DSN Sentry cannot parse stops startup (closes #107). - 2026-10-01: a port or TLS check that shutdown cuts short saves nothing and sends no notification, as a cut-short DNS lookup already did (closes #185). - 2026-10-01: the client address from `X-Forwarded-For` is the last entry that is not a trusted proxy, not the first, which the client sets (closes #181). - 2026-10-01: a nameserver that does not answer is saved as `error` with the reason, and NS failure and NS recovery are notified (closes #104). - 2026-10-01: a `DNSWATCHER_DNS_INTERVAL` or `DNSWATCHER_TLS_INTERVAL` that is not a positive duration stops startup; empty means the default (closes #177). - 2026-10-01: `/metrics` allows each client address 30 requests a minute, counted before Basic Auth, and answers 429 beyond that (closes #101). - 2026-10-01: the image built by `make docker` reports the `git describe` version, not `dev`, and the startup log now shows it (closes #109). - 2026-10-01: two notify shutdown tests always release the delivery they hold, so a drain that returns early fails them instead of hanging (closes #176). - 2026-10-01: `script/install-precommit` asks git for the repository's git directory, so `make hooks` also works where `.git` is a file (closes #129). - 2026-10-01: `TODO.md` brought up to date: open issues listed by URL, every Completed Steps entry cut to at most two lines (closes #146). - 2026-10-01: wildcard CORS now applies only to the public routes, not to `/metrics`, and allows only the methods they serve (closes #100). - 2026-10-01: `internal/state` and `internal/watcher` no longer export test-only constructors: two moved to `export_test.go`, one is deleted (closes #111). - 2026-10-01: notify shutdown tests use one timing constant per meaning, name the bound they check, and require the drain's debug line (closes #116). - 2026-09-29: the entrypoint chowns the data directory to `dnswatcher` and runs dnswatcher as that user, so a host bind mount needs no chown (closes #166). - 2026-09-29: the live-DNS test package is renamed `internal/livednstest`; `make lint` fails when program code imports it (closes #164). - 2026-09-29: `.golangci.yml` re-fetched from `sneak/prompts`, with `gomodguard_v2` and the org `depguard` `test-support` rule (closes #123). - 2026-09-29: watcher and resolver tests that look something up in DNS use the real resolver against live DNS servers (closes #159). - 2026-09-28: the inconsistency alert is sent once, when two nameservers start to disagree; every pair of nameservers is compared (closes #158). - 2026-09-28: DNS names in record values (CNAME, MX, SRV and NS targets) are lower-cased, so letter case alone is not a change (closes #157). - 2026-09-28: lint and tests run on every build: `script/cibuild` and `script/docker` pass `--no-cache-filter=lint,builder` (closes #115). - 2026-09-28: the server timeout test drives `Run` and checks the timeouts on the `http.Server` it serves (closes #120). - 2026-09-28: upaas deploy readiness: the image runs as user `dnswatcher` with a `HEALTHCHECK`; README "Running under upaas" (closes #147). - 2026-09-21: added behavioural tests for `internal/globals`, `internal/healthcheck`, and `internal/logger` (closes #110). - 2026-09-21: `go mod tidy` dropped the redundant `golang.org/x/sync` `// indirect` line so `script/bootstrap` leaves a clean tree (#132) - 2026-08-10: comment-only corrections to `script/bootstrap`, `script/cibuild` and `Dockerfile.lint`; no behaviour changed. - 2026-08-10: MIT `LICENSE` added at the repository root; the README's first line and License section name the licence. - 2026-08-10: policy scaffold present: `REPO_POLICIES.md`, `.editorconfig`, `.dockerignore`, CI workflow, `make fmt-check`, `make docker`, `make hooks`. - 2026-08-10: Go's test cache disabled in `script/test` (`-count=1`), so every run queries live DNS; a failed run is rerun with `-v`. - 2026-08-10: live-DNS tests made robust rather than gated (#93): a limit on concurrent lookups, retries, and a quorum across nameservers. - 2026-08-10: all linting moved into Docker: `script/lint` builds `Dockerfile.lint`, and the root `Dockerfile` has its own lint stage. - 2026-08-09: in-flight notification deliveries are drained at shutdown, bounded by the shutdown deadline (#106). - 2026-08-09: `http.Server` sets all four socket timeouts; `WriteTimeout` stays above the 60s handler timeout (#99). - 2026-08-09: `SecurityHeaders()` middleware sets HSTS, CSP and the other security headers `REPO_POLICIES.md` requires on every response. - 2026-08-07: golangci-lint bumped to v2.12.2 and `.golangci.yml` set to the org config; fixed the resulting `goconst`, `dupl` and `lll` findings. - 2026-07-07 Adopted scripts-to-rule-them-all: `script/` entrypoints, Makefile shims, README Entrypoints section - 2026-02-20: iterative DNS resolver implemented - 2026-02-20: CI actions and go install refs pinned to commit SHAs; Gitea Actions workflow added - 2026-02-20: watcher monitoring orchestrator merged to main (#8) - 2026-02-20: DOMAINS/HOSTNAMES unified into single TARGETS config (#11) - 2026-02-19: TCP port connectivity checker, made concurrent with port validation; gosec G704 SSRF findings fixed without suppression - 2026-02-19: TLS certificate inspector with no-peer-certificates error path and IP SANs - 2026-02-19: gosec SSRF and formatting fixes on main - 2026-02-19: initial scaffold with per-nameserver DNS monitoring model # Future Steps - 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 - `goimports` in `make fmt-check`, Markdown formatting: https://git.eeqj.de/sneak/dnswatcher/issues/119 - final state save at shutdown: https://git.eeqj.de/sneak/dnswatcher/issues/114 - 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