README.md describes an earlier version of NetWatch. Fourteen concrete claims contradict the code on main at fbfe1df, and TODO.md describes a branch state that no longer exists. All eight REPO_POLICIES-required README sections are present, so this is purely about content accuracy.
Factually wrong
#
README says
Code actually does
1
line 92: "HEAD requests"
src/main.js:365method: "GET". Gateway detector likewise src/main.js:176. The app's own footer (src/main.js:663) correctly says GET, so the running UI contradicts the README. Line 151 repeats the error.
2
lines 52-54: "zero-dependency SPA ... no backend required"
A Go backend exists: 15 files under backend/, chi server, zstd report storage, its own Dockerfile.backend and CI step.
3
line 119: "2s update interval"
src/main.js:11updateInterval: 3000. UI default is also 3s (src/main.js:610).
4
lines 93-94: "1-second timeout; anything over 1000ms is unreachable"
src/main.js:16-21: requestTimeout = 2900ms, maxLatency = 2900ms. The 1000ms figure is graphMaxLatency — the chart Y-axis ceiling, a different constant. The README conflates the two.
5
line 77: "22 WAN hosts"
26. Count src/main.js:34-104.
6
lines 78-80: "7 S3 regional endpoints"
8 — Singapore (src/main.js:63-66) is omitted from the list.
These do not exist. No storage.googleapis.com entry anywhere in src/main.js. Entirely phantom.
8
—
6 Hetzner endpoints (src/main.js:79-103) and plain Google (:44) are undocumented.
9
line 61: "CONFIG: Frozen configuration object"
No Object.freeze anywhere; src/main.js:1202 mutates CONFIG.updateInterval at runtime.
10
line 120: "green (HEALTHY) or red (DEGRADED)" — two states
src/main.js:326-338 returns four: healthy, slow, degraded, offline. DEGRADED renders orange, not red; OFFLINE is red.
11
line 121: "reachable count, min/max/avg"
Also renders median, a history-window min/max pair, and a checks counter.
12
line 138: "Listens on port 8080 by default (override with PORT env var)"
nginx.conf:2 is a hardcoded listen 8080;. No envsubst, no template, no entrypoint script. The override does not exist.
13
lines 154-155: "Local gateway: The 192.168.100.1 endpoint"
192.168.100.1 is LOCAL_CPE, the cable modem (src/main.js:126-127), explicitly upstream of the gateway. The real gateway is auto-detected from GATEWAY_CANDIDATES (:136-141). Lines 81-84 get this right and contradict lines 154-155.
14
—
Shipped features absent from the README entirely: user-selectable interval dropdown (1s-60s), debug log panel with 5 severity levels, host pinning, latency-based auto-sorting, the recovery probe, local + UTC clocks, first-tick discard for DNS/TLS warmup, and the commit-hash footer link. All are recorded as done in TODO.md.
Structural problems
Getting Started documents raw tools, not make.README.md:8-24 lists yarn install, yarn dev, yarn build, docker build. Zero make commands. This contradicts "Always use Makefile targets instead of invoking the underlying tools directly. The Makefile is the single source of truth." The README's own Entrypoints section documents the script layer correctly — Getting Started just ignores it.
The backend is invisible in the root README. Not one mention, despite being half the repo.
Two TODO lists that disagree.README.md:159-165 has five items; root TODO.md has a different structure and different content. TODO.md:42-43 claims .editorconfig and a hooks Makefile target are both missing — hooks has existed at Makefile:34-35 for some time, so that line is stale.
TODO.md Status is wrong. It says "Backend work in flight on feat/reportbuf-storage (dirty: src/main.js) ... backend is new and unmerged." The backend is merged (commit add5f1f), the working tree is clean, and TODO.md:46-47 asks what to do about an untracked resume.sh that no longer exists.
Definition of done
Every one of the 14 items above is corrected against the actual code. Verify each against the source rather than trusting this list — it was compiled by audit and should itself be checked.
Getting Started leads with make targets (make setup, make dev, make check, make docker), with the underlying yarn commands mentioned only as context if at all.
The backend is documented in the root README: what it is, how to build and run it, and its API surface.
The two TODO lists are reconciled into a single source of truth. Policy puts the TODO in README.md; TODO.md additionally carries the Workflow/Status/Next Step/Completed/Future structure this repo uses. Keep both files but make them non-contradictory, and state in the PR how you divided responsibility between them.
TODO.md Status and Next Step reflect reality: backend merged, tree clean, no resume.sh, hooks target exists.
make fmt has been run and the result is included in the commit. No unformatted markdown.
make check passes.
Commit title ends with (closes #N).
Implementation requirements
This is a documentation-only change. Do not modify any code, config, script, CI, or build file. If you find yourself wanting to fix the code to match the docs, stop — file it or leave it to the issue that owns it. In particular, do not implement the PORT override for nginx here (item 12); correct the README to describe current behaviour, and note that the missing override is tracked separately.
Markdown must be formatted with the repo's own tooling (make fmt) before committing.
Verbatim identifiers (filenames, env vars, branch names, commands) go in backticks.
Dates in ISO 8601 (YYYY-MM-DD).
No attribution trailers in the commit message.
## Problem
`README.md` describes an earlier version of NetWatch. Fourteen concrete claims contradict the code on `main` at `fbfe1df`, and `TODO.md` describes a branch state that no longer exists. All eight REPO_POLICIES-required README sections are present, so this is purely about content accuracy.
### Factually wrong
| # | README says | Code actually does |
| --- | --- | --- |
| 1 | line 92: "**HEAD requests**" | `src/main.js:365` `method: "GET"`. Gateway detector likewise `src/main.js:176`. The app's own footer (`src/main.js:663`) correctly says GET, so the running UI contradicts the README. Line 151 repeats the error. |
| 2 | lines 52-54: "zero-dependency SPA ... **no backend required**" | A Go backend exists: 15 files under `backend/`, chi server, zstd report storage, its own `Dockerfile.backend` and CI step. |
| 3 | line 119: "**2s** update interval" | `src/main.js:11` `updateInterval: 3000`. UI default is also 3s (`src/main.js:610`). |
| 4 | lines 93-94: "**1-second timeout**; anything over **1000ms** is unreachable" | `src/main.js:16-21`: `requestTimeout` = 2900ms, `maxLatency` = 2900ms. The 1000ms figure is `graphMaxLatency` — the chart Y-axis ceiling, a different constant. The README conflates the two. |
| 5 | line 77: "**22** WAN hosts" | 26. Count `src/main.js:34-104`. |
| 6 | lines 78-80: "**7** S3 regional endpoints" | 8 — Singapore (`src/main.js:63-66`) is omitted from the list. |
| 7 | lines 79-80: "4 GCS locational endpoints (Iowa, Belgium, Singapore, Sydney)" | **These do not exist.** No `storage.googleapis.com` entry anywhere in `src/main.js`. Entirely phantom. |
| 8 | — | 6 Hetzner endpoints (`src/main.js:79-103`) and plain `Google` (`:44`) are undocumented. |
| 9 | line 61: "`CONFIG`: **Frozen** configuration object" | No `Object.freeze` anywhere; `src/main.js:1202` mutates `CONFIG.updateInterval` at runtime. |
| 10 | line 120: "green (HEALTHY) or red (DEGRADED)" — two states | `src/main.js:326-338` returns **four**: `healthy`, `slow`, `degraded`, `offline`. DEGRADED renders orange, not red; OFFLINE is red. |
| 11 | line 121: "reachable count, min/max/avg" | Also renders median, a history-window min/max pair, and a checks counter. |
| 12 | line 138: "Listens on port 8080 by default (**override with `PORT` env var**)" | `nginx.conf:2` is a hardcoded `listen 8080;`. No `envsubst`, no template, no entrypoint script. The override does not exist. |
| 13 | lines 154-155: "**Local gateway**: The 192.168.100.1 endpoint" | `192.168.100.1` is `LOCAL_CPE`, the cable modem (`src/main.js:126-127`), explicitly upstream of the gateway. The real gateway is auto-detected from `GATEWAY_CANDIDATES` (`:136-141`). Lines 81-84 get this right and contradict lines 154-155. |
| 14 | — | Shipped features absent from the README entirely: user-selectable interval dropdown (1s-60s), debug log panel with 5 severity levels, host pinning, latency-based auto-sorting, the recovery probe, local + UTC clocks, first-tick discard for DNS/TLS warmup, and the commit-hash footer link. All are recorded as done in `TODO.md`. |
### Structural problems
- **Getting Started documents raw tools, not `make`.** `README.md:8-24` lists `yarn install`, `yarn dev`, `yarn build`, `docker build`. Zero `make` commands. This contradicts "Always use Makefile targets instead of invoking the underlying tools directly. The Makefile is the single source of truth." The README's own **Entrypoints** section documents the script layer correctly — Getting Started just ignores it.
- **The backend is invisible in the root README.** Not one mention, despite being half the repo.
- **Two TODO lists that disagree.** `README.md:159-165` has five items; root `TODO.md` has a different structure and different content. `TODO.md:42-43` claims `.editorconfig` and a `hooks` Makefile target are both missing — `hooks` has existed at `Makefile:34-35` for some time, so that line is stale.
- **`TODO.md` Status is wrong.** It says "Backend work in flight on feat/reportbuf-storage (dirty: src/main.js) ... backend is new and unmerged." The backend **is** merged (commit `add5f1f`), the working tree is clean, and `TODO.md:46-47` asks what to do about an untracked `resume.sh` that no longer exists.
## Definition of done
- [ ] Every one of the 14 items above is corrected against the actual code. Verify each against the source rather than trusting this list — it was compiled by audit and should itself be checked.
- [ ] Getting Started leads with `make` targets (`make setup`, `make dev`, `make check`, `make docker`), with the underlying `yarn` commands mentioned only as context if at all.
- [ ] The backend is documented in the root README: what it is, how to build and run it, and its API surface.
- [ ] The two TODO lists are reconciled into a single source of truth. Policy puts the TODO in `README.md`; `TODO.md` additionally carries the Workflow/Status/Next Step/Completed/Future structure this repo uses. Keep both files but make them non-contradictory, and state in the PR how you divided responsibility between them.
- [ ] `TODO.md` Status and Next Step reflect reality: backend merged, tree clean, no `resume.sh`, `hooks` target exists.
- [ ] `make fmt` has been run and the result is included in the commit. No unformatted markdown.
- [ ] `make check` passes.
- [ ] Commit title ends with ` (closes #N)`.
## Implementation requirements
- **This is a documentation-only change.** Do not modify any code, config, script, CI, or build file. If you find yourself wanting to fix the code to match the docs, stop — file it or leave it to the issue that owns it. In particular, do **not** implement the `PORT` override for nginx here (item 12); correct the README to describe current behaviour, and note that the missing override is tracked separately.
- Markdown must be formatted with the repo's own tooling (`make fmt`) before committing.
- Verbatim identifiers (filenames, env vars, branch names, commands) go in backticks.
- Dates in ISO 8601 (YYYY-MM-DD).
- No attribution trailers in the commit message.
clawbot
added this to the 1.0.0 milestone 2026-08-09 03:43:24 +02:00
.editorconfig — done by PR #35, which moved the org-model file to the repo root.
hooks target — was already wrong before any of this work. The root Makefile has had hooks: @script/install-precommit since the scripts-to-rule-them-all commit (e45bc57). The bullet has been describing non-existent work for some time.
PR #35 deliberately left it alone to avoid manufacturing a conflict with PR #31, which rewrites Status and Next Step. That reasoning was sound for those two sections but does not extend to Future Steps, which #31 does not touch — so the bullet survived, and it lands here.
Add to this issue's definition of done
The stale Future Steps compliance bullet is deleted (not amended — both halves are complete or were never real).
The remaining Future Steps bullets are checked against reality the same way. The existing DoD already covers the resume.sh bullet, which refers to a file that no longer exists. Verify each surviving bullet still describes work that is actually outstanding, rather than trusting the list.
Note on sequencing: by the time this issue is implemented, PRs #31 and #35 should both have landed and TODO.md will have moved. Re-read the file as it exists then rather than working from the line numbers quoted in this issue's original description.
## Additional item: `TODO.md`'s first `Future Steps` bullet is stale in both halves
Surfaced during the review of PR #35. Adding it here because this issue owns `TODO.md` accuracy.
`TODO.md` `Future Steps` bullet 1:
> Compliance top-up as one small commit: add .editorconfig and add the hooks target to the Makefile
Both halves are wrong as of PR #35:
- **`.editorconfig`** — done by PR #35, which moved the org-model file to the repo root.
- **`hooks` target** — was **already** wrong before any of this work. The root `Makefile` has had `hooks: @script/install-precommit` since the scripts-to-rule-them-all commit (`e45bc57`). The bullet has been describing non-existent work for some time.
PR #35 deliberately left it alone to avoid manufacturing a conflict with PR #31, which rewrites Status and Next Step. That reasoning was sound for those two sections but does not extend to `Future Steps`, which #31 does not touch — so the bullet survived, and it lands here.
### Add to this issue's definition of done
- [ ] The stale `Future Steps` compliance bullet is deleted (not amended — both halves are complete or were never real).
- [ ] The remaining `Future Steps` bullets are checked against reality the same way. The existing DoD already covers the `resume.sh` bullet, which refers to a file that no longer exists. Verify each surviving bullet still describes work that is actually outstanding, rather than trusting the list.
Note on sequencing: by the time this issue is implemented, PRs #31 and #35 should both have landed and `TODO.md` will have moved. Re-read the file as it exists then rather than working from the line numbers quoted in this issue's original description.
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.
Problem
README.mddescribes an earlier version of NetWatch. Fourteen concrete claims contradict the code onmainatfbfe1df, andTODO.mddescribes a branch state that no longer exists. All eight REPO_POLICIES-required README sections are present, so this is purely about content accuracy.Factually wrong
src/main.js:365method: "GET". Gateway detector likewisesrc/main.js:176. The app's own footer (src/main.js:663) correctly says GET, so the running UI contradicts the README. Line 151 repeats the error.backend/, chi server, zstd report storage, its ownDockerfile.backendand CI step.src/main.js:11updateInterval: 3000. UI default is also 3s (src/main.js:610).src/main.js:16-21:requestTimeout= 2900ms,maxLatency= 2900ms. The 1000ms figure isgraphMaxLatency— the chart Y-axis ceiling, a different constant. The README conflates the two.src/main.js:34-104.src/main.js:63-66) is omitted from the list.storage.googleapis.comentry anywhere insrc/main.js. Entirely phantom.src/main.js:79-103) and plainGoogle(:44) are undocumented.CONFIG: Frozen configuration object"Object.freezeanywhere;src/main.js:1202mutatesCONFIG.updateIntervalat runtime.src/main.js:326-338returns four:healthy,slow,degraded,offline. DEGRADED renders orange, not red; OFFLINE is red.PORTenv var)"nginx.conf:2is a hardcodedlisten 8080;. Noenvsubst, no template, no entrypoint script. The override does not exist.192.168.100.1isLOCAL_CPE, the cable modem (src/main.js:126-127), explicitly upstream of the gateway. The real gateway is auto-detected fromGATEWAY_CANDIDATES(:136-141). Lines 81-84 get this right and contradict lines 154-155.TODO.md.Structural problems
make.README.md:8-24listsyarn install,yarn dev,yarn build,docker build. Zeromakecommands. This contradicts "Always use Makefile targets instead of invoking the underlying tools directly. The Makefile is the single source of truth." The README's own Entrypoints section documents the script layer correctly — Getting Started just ignores it.README.md:159-165has five items; rootTODO.mdhas a different structure and different content.TODO.md:42-43claims.editorconfigand ahooksMakefile target are both missing —hookshas existed atMakefile:34-35for some time, so that line is stale.TODO.mdStatus is wrong. It says "Backend work in flight on feat/reportbuf-storage (dirty: src/main.js) ... backend is new and unmerged." The backend is merged (commitadd5f1f), the working tree is clean, andTODO.md:46-47asks what to do about an untrackedresume.shthat no longer exists.Definition of done
maketargets (make setup,make dev,make check,make docker), with the underlyingyarncommands mentioned only as context if at all.README.md;TODO.mdadditionally carries the Workflow/Status/Next Step/Completed/Future structure this repo uses. Keep both files but make them non-contradictory, and state in the PR how you divided responsibility between them.TODO.mdStatus and Next Step reflect reality: backend merged, tree clean, noresume.sh,hookstarget exists.make fmthas been run and the result is included in the commit. No unformatted markdown.make checkpasses.(closes #N).Implementation requirements
PORToverride for nginx here (item 12); correct the README to describe current behaviour, and note that the missing override is tracked separately.make fmt) before committing.Additional item:
TODO.md's firstFuture Stepsbullet is stale in both halvesSurfaced during the review of PR #35. Adding it here because this issue owns
TODO.mdaccuracy.TODO.mdFuture Stepsbullet 1:> Compliance top-up as one small commit: add .editorconfig and add the hooks target to the Makefile
Both halves are wrong as of PR #35:
.editorconfig— done by PR #35, which moved the org-model file to the repo root.hookstarget — was already wrong before any of this work. The rootMakefilehas hadhooks: @script/install-precommitsince the scripts-to-rule-them-all commit (e45bc57). The bullet has been describing non-existent work for some time.PR #35 deliberately left it alone to avoid manufacturing a conflict with PR #31, which rewrites Status and Next Step. That reasoning was sound for those two sections but does not extend to
Future Steps, which #31 does not touch — so the bullet survived, and it lands here.Add to this issue's definition of done
Future Stepscompliance bullet is deleted (not amended — both halves are complete or were never real).Future Stepsbullets are checked against reality the same way. The existing DoD already covers theresume.shbullet, which refers to a file that no longer exists. Verify each surviving bullet still describes work that is actually outstanding, rather than trusting the list.Note on sequencing: by the time this issue is implemented, PRs #31 and #35 should both have landed and
TODO.mdwill have moved. Re-read the file as it exists then rather than working from the line numbers quoted in this issue's original description.