Files
netwatch/TODO.md
T
sneak 02a503b9d7
check / check (push) Failing after 1s
feat(frontend): post collected samples to /api/v1/reports (closes #53)
A Reporter beside AppState POSTs a JSON delta report to the same-origin
/api/v1/reports every reportInterval (default 60s). buildReport is an
exported pure function of host state, emitting each host's unreported,
non-paused samples plus a per-browser clientId, geo null, and a UTC
timestamp; a per-host high-water mark advances only on a delivered POST,
so a failed send re-sends next interval within the history window.
Failure is quiet and never blocks probing.

The client id feature-detects crypto.randomUUID and otherwise builds a v4
id from crypto.getRandomValues, so insecure-context loads (plain HTTP to a
non-localhost host) work; reporter setup is isolated so it can never stop
probing. init() runs only when the #app page is present, so a test can
import buildReport.

vite.config.js proxies /api to 127.0.0.1:8080 for yarn dev.

Model: opus-4-8
2026-09-21 16:49:23 +00:00

5.2 KiB

Workflow

  • branch (from main)
  • 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)
  • merge to main if the branch is not protected, otherwise open a PR
  • push

Status

pre-1.0. No git tags. Backend work in flight on feat/reportbuf-storage (dirty: src/main.js). Frontend is functional; backend is new and unmerged.

Next Step

Land feat/reportbuf-storage: finish the in-progress src/main.js change, get make check green, and merge the branch to main. The branch adds the backend (buffered zstd-compressed report storage), the CI workflow, and backend repo standard files, so merging it also closes most compliance gaps.

Completed Steps

  • 2026-09-21: shutdown lifecycle correctness. The process now shuts down through fx instead of os.Exit, so every component's OnStop runs and buffered reports are flushed to disk on SIGTERM — previously a full flush window of telemetry was silently lost on every restart. The http.Server is now built before its serving goroutine starts, so shutdown can no longer race or nil-deref it; a listen failure exits non-zero via fx.Shutdowner; reportbuf OnStop is idempotent; and writeTimeout now exceeds the chi per-request budget so that budget is actually reachable. Dead startupTime, exitCode, and cancelFunc fields were removed
  • 2026-09-21: frontend reporting client — a Reporter class posts collected samples to /api/v1/reports every reportInterval (default 60s) as a per-host delta, with the report-building step a pure exported function of host state; the per-browser client id works in insecure (plain-HTTP) contexts; vite.config.js proxies /api to the local backend for yarn dev
  • 2026-09-21: backend HTTP hardening (issue #19): added ReadHeaderTimeout and IdleTimeout to the server, a SecurityHeaders middleware (HSTS, tight CSP, frame/sniff/referrer/permissions headers) registered before CORS, and trusted-proxy client IP resolution honouring X-Forwarded-For / X-Real-IP only from a TRUSTED_PROXIES allowlist (loopback plus RFC1918 by default)
  • 2026-08-10: every interactive control now meets the 44x44 CSS px minimum tap target (.pin-btn, #interval-select, the debug-log label and, on narrow viewports, #pause-btn). The pin button's hit area grows via matching negative margins, so its layout footprint and row density are unchanged
  • 2026-08-10: per-host status line wraps below the 768px breakpoint instead of forcing horizontal page scroll at 320px
  • 2026-08-09: Dockerfile.backend reworked to the mandated Go multistage lint-stage pattern: separate lint stage on the hash-pinned golangci/golangci-lint image, COPY --from=lint stage dependency, CGO_ENABLED=0 static build driven by ARG VERSION, and no more COPY .git
  • 2026-08-09: dotfile compliance — lifted backend/.editorconfig to the repo root so root = true covers the frontend too, and replaced .gitignore with the org model (OS, editor, node, and environment/secrets sections) plus this repo's dist/ and *.log. .env, .env.*, *.pem, and *.key are now ignored repo-wide, not just under backend/. Excluding .git from .dockerignore stays deferred: both images read git metadata at build time (COPY .git in Dockerfile.backend, git rev-parse in vite.config.js)
  • 2026-08-09: automated responsive-layout harness (make frontend-viewport-test): digest-pinned headless Chrome driven over CDP against the built dist/, viewport widths derived from the breakpoints in src/styles.css (#13). Every check carries a presence guard so none of them can pass against a page it is not actually measuring. Found two real layout defects, filed as #42 and #43
  • 2026-07-07 Adopted scripts-to-rule-them-all: script/ entrypoints, Makefile shims, README Entrypoints section
  • 2026-02-27: backend with buffered zstd-compressed report storage; CI workflow and backend repo standard files; backend Dockerfile fixed (Go 1.25, golangci-lint) and moved to repo root (feat/reportbuf-storage, unmerged)
  • 2026-02-26: host row layout redesigned with CSS grid; overflow and spacing fixes; nginx config extracted; port hardcoded to 8080
  • 2026-02-26: debug log panel, median stats, recovery probe, Docker build fix, S3 Singapore endpoint added
  • 2026-02-23: summary box redesign, host pinning, local and UTC clocks, checks counter
  • 2026-02-23: hosts sorted by latency; GET instead of HEAD for latency; timeout derived from interval; Hetzner regional endpoints; 3s interval
  • 2026-01-29: initial NetWatch network latency monitor

Future Steps

  • Wire script/frontend-viewport-test into CI as its own step (deliberately not part of make check today; the decision has real CI-runtime cost and is tracked separately)
  • Compliance top-up as one small commit: add .editorconfig and add the hooks target to the Makefile
  • After merge, confirm .gitea/workflows/check.yml is on main and CI is green (main always green policy)
  • Decide what to do with untracked resume.sh: commit it, gitignore it, or delete it