Milestone: repo standards and macOS support #6

Open
clawbot wants to merge 7 commits from next into main
Collaborator

Milestone branch next for merge into main. Every unit on it passed an independent review before being squash-merged.

On the branch

  • Repo standards adoption (#1): script/ entrypoints with the Makefile as thin shims, containerised lint and tests, CI workflow, vendored .golangci.yml, REPO_POLICIES.md, TODO.md; all lint findings fixed. Behavior unchanged.
  • macOS support and single-interface UI (#2): Linux with both bridge interfaces is unchanged; otherwise the default-route interface alone is monitored and the UI draws one pane. On macOS a connected VPN tunnel (utun) is the primary pane next to the physical default-route interface, or the physical interface alone. Anything outside that matrix exits with an error.
  • Starlink status lines (#3): two lines under the physical pane, red on dish disconnect or an active alert. Detection is a TCP probe to the dish endpoint bound to the physical interface, once a minute until a dish answers, then get_status every 5s; no dish means nothing drawn and no RPC. Minimal vendored proto bindings for get_status only; adds pinned grpc/protobuf. Not run against a real dish: fake-backed tests only.
  • Version stamp (#10): rtnetmon logs its version (the git tag or short commit) on the first startup line, from make build and from a plain docker build . alike; .git goes into the build context without its config.
  • CI runs (#12): script/bootstrap refreshes the apt package lists before its first install, so the CI job gets past the bootstrap on the runner image.
  • Your macOS VPN report (#8): a tunnel is the VPN pane only while it carries the default route (a default row, or 0/1 plus 128.0/1). Idle Tailscale or a tunnel left by a disconnected client no longer turns the display red.
  • TODO.md brought up to date (#13): who merges where, what is on next, and what waits on you.

What to know before merging or deploying

  • make lint, make test and make check need a Docker daemon.
  • The personal copy/run rsync deploy targets were removed from the Makefile; make run runs the binary locally.
  • Not verified on a real mac (no mac in the fleet): live netstat -rn parsing, the VPN rule above, IP_BOUND_IF socket binding, and whether Mullvad leak protection lets bound traffic leave the physical interface. A first run on your mac is the test.
  • On macOS --ifaceA/--ifaceB are ignored (interfaces come from detection); --labelA/--labelB still apply.

Waiting on the owner

  • The merge into main. The milestone is complete and nothing else is in flight.
  • A first run on your mac, as above.

Model: fable-5-1 (original); fable-5 (updates); opus-5-5 (version stamp, CI fix, VPN fix, current revision)

Milestone branch `next` for merge into `main`. Every unit on it passed an independent review before being squash-merged. **On the branch** - Repo standards adoption (https://git.eeqj.de/sneak/rtnetmon/issues/1): `script/` entrypoints with the Makefile as thin shims, containerised lint and tests, CI workflow, vendored `.golangci.yml`, `REPO_POLICIES.md`, `TODO.md`; all lint findings fixed. Behavior unchanged. - macOS support and single-interface UI (https://git.eeqj.de/sneak/rtnetmon/issues/2): Linux with both bridge interfaces is unchanged; otherwise the default-route interface alone is monitored and the UI draws one pane. On macOS a connected VPN tunnel (`utun`) is the primary pane next to the physical default-route interface, or the physical interface alone. Anything outside that matrix exits with an error. - Starlink status lines (https://git.eeqj.de/sneak/rtnetmon/issues/3): two lines under the physical pane, red on dish disconnect or an active alert. Detection is a TCP probe to the dish endpoint bound to the physical interface, once a minute until a dish answers, then `get_status` every 5s; no dish means nothing drawn and no RPC. Minimal vendored proto bindings for `get_status` only; adds pinned `grpc`/`protobuf`. Not run against a real dish: fake-backed tests only. - Version stamp (https://git.eeqj.de/sneak/rtnetmon/issues/10): rtnetmon logs its version (the git tag or short commit) on the first startup line, from `make build` and from a plain `docker build .` alike; `.git` goes into the build context without its `config`. - CI runs (https://git.eeqj.de/sneak/rtnetmon/issues/12): `script/bootstrap` refreshes the apt package lists before its first install, so the CI job gets past the bootstrap on the runner image. - Your macOS VPN report (https://git.eeqj.de/sneak/rtnetmon/issues/8): a tunnel is the VPN pane only while it carries the default route (a `default` row, or `0/1` plus `128.0/1`). Idle Tailscale or a tunnel left by a disconnected client no longer turns the display red. - `TODO.md` brought up to date (https://git.eeqj.de/sneak/rtnetmon/issues/13): who merges where, what is on `next`, and what waits on you. **What to know before merging or deploying** - `make lint`, `make test` and `make check` need a Docker daemon. - The personal copy/run rsync deploy targets were removed from the Makefile; `make run` runs the binary locally. - Not verified on a real mac (no mac in the fleet): live `netstat -rn` parsing, the VPN rule above, `IP_BOUND_IF` socket binding, and whether Mullvad leak protection lets bound traffic leave the physical interface. A first run on your mac is the test. - On macOS `--ifaceA`/`--ifaceB` are ignored (interfaces come from detection); `--labelA`/`--labelB` still apply. **Waiting on the owner** - The merge into `main`. The milestone is complete and nothing else is in flight. - A first run on your mac, as above. Model: fable-5-1 (original); fable-5 (updates); opus-5-5 (version stamp, CI fix, VPN fix, current revision)
clawbot self-assigned this 2026-09-21 09:22:47 +02:00
clawbot added 1 commit 2026-09-21 09:22:48 +02:00
Standard scaffold: script/ entrypoints with the Makefile as thin shims, a Dockerfile whose lint and test phases gate the build, a Gitea CI workflow running script/cibuild, REPO_POLICIES.md, TODO.md, .editorconfig, .dockerignore, LICENSE, wider .gitignore. .golangci.yml is byte-identical to the canonical copy in the prompts repo.

211 lint findings fixed in code: package globals became functions/fields and a cobra command constructor, magic numbers became named constants, ctx is threaded into the probes, monitor loops split. Tests moved to external _test packages with export_test.go. Behavior unchanged.

Readers will trip over: make lint/test/check now need a Docker daemon; the personal rsync copy/run targets are gone and make run runs locally.
Disclosure: four //nolint:gosec remain on the fixed-argv ping/curl calls and the operator-chosen log file, as the reference repo annotates the same class.
Disclosure: module path left as-is.

Model: opus-4-8 (implementation); fable-5-1 (merge)
clawbot added the needs-checks label 2026-09-21 09:22:48 +02:00
clawbot added 1 commit 2026-09-21 15:02:01 +02:00
Linux runs exactly as before when both bridge interfaces exist. When they do
not, the lone default-route interface is monitored, and a single interface
draws a single UI pane instead of an empty second one.

macOS is newly supported: a running VPN tunnel (utun) is monitored as the
primary pane alongside the physical default-route interface, or the physical
interface alone when no VPN is up.

Detection lives in internal/netdetect: interface/route data types, pure
selection logic keyed on OS name, and route parsers, all unit-tested on Linux
for both platforms. Only the real route query and the per-platform TCP dial
binding are build-tagged. NewMonitor now takes a list of interfaces.

Not verified on a real mac: live netstat parsing, IP_BOUND_IF dialing, Mullvad leak protection.

Model: opus-4-8 (implementation); fable-5-1 (landing commit)
clawbot removed their assignment 2026-09-21 15:02:29 +02:00
sneak was assigned by clawbot 2026-09-21 15:02:29 +02:00
clawbot added merge-ready and removed needs-checks labels 2026-09-21 15:02:30 +02:00
clawbot added 1 commit 2026-09-22 20:56:03 +02:00
Detection is a TCP connect to the dish endpoint bound to the physical
interface; once a dish answers, get_status is read every 5s and two
status lines render under the physical pane, red on disconnect or
alert. No dish: nothing drawn, no RPC. Minimal vendored proto bindings
for get_status only. Independent review passed (PR 7 comment 100012).

Model: opus-4-8 (implementation and review); model: claude-fable-5
(merge)
Author
Collaborator

make check on branch next at commit 769511d passed (lint: 0 issues; all tests pass with -race -cover).

model: claude-opus-4-8

`make check` on branch `next` at commit `769511d` **passed** (lint: 0 issues; all tests pass with -race -cover). model: claude-opus-4-8
clawbot added needs-checks and removed merge-ready labels 2026-09-23 01:56:29 +02:00
sneak was unassigned by clawbot 2026-09-23 01:56:30 +02:00
clawbot self-assigned this 2026-09-23 01:56:30 +02:00
Author
Collaborator

Not merge-ready: the CI check has never passed on next. All three runs of script/cibuild in CI failed within seconds: 7dd4ac7, 486a473, and the head 769511d (re-run 2026-09-22 23:47 UTC, the build step failed after 5 seconds). The same script passes locally on 769511d, so the CI run itself is broken for this repo, not the code. merge-ready and the assignment stay off until a CI run executes and passes. The fix is queued for when rtnetmon resumes from the priority pause.

Model: opus-5-5

Not merge-ready: the CI check has never passed on `next`. All three runs of `script/cibuild` in CI failed within seconds: `7dd4ac7`, `486a473`, and the head `769511d` (re-run 2026-09-22 23:47 UTC, the build step failed after 5 seconds). The same script passes locally on `769511d`, so the CI run itself is broken for this repo, not the code. `merge-ready` and the assignment stay off until a CI run executes and passes. The fix is queued for when rtnetmon resumes from the priority pause. Model: opus-5-5
clawbot added 1 commit 2026-10-02 10:21:26 +02:00
rtnetmon had no version. main.Version is now set at link time and logged
in the first startup line. `make build` and `make dev` set it from
`git describe --tags --always` unless VERSION is given. The Dockerfile
takes it from the VERSION build argument when one is given, otherwise
from `git describe --tags --always` of the .git the build context now
carries, and fails the build if the context carries .git and no version
comes out. .dockerignore follows the canonical copy: .git is sent,
.git/config, which can hold a credential, is not.

Model: opus-5-5
clawbot added 1 commit 2026-10-03 15:09:40 +02:00
The CI job image ships with empty apt package lists, so the bootstrap's
`apt-get install -y golang` could not find the package and every CI run
stopped there. On the apt path the bootstrap now runs `apt-get update`
once, before the first install, and not at all when nothing needs
installing.

Model: opus-5-5
clawbot added 1 commit 2026-10-03 15:26:41 +02:00
A utun tunnel counted as the VPN whenever it was up with a routable
IPv4 address, so idle Tailscale or a tunnel left behind by a
disconnected client became the VPN pane and its probes failed. A
tunnel is now the VPN only while it carries the IPv4 default route in
netstat: an unscoped default row, or both 0/1 and 128.0/1 rows on it.
A default row scoped to a tunnel (flag I) does not count; on the
physical interface it still does, since a VPN holding the default
leaves the physical default scoped. Tests feed netstat text in the
macOS layout through the parser into Select. Not run on a real Mac.

Model: opus-5-5
clawbot removed their assignment 2026-10-03 16:58:08 +02:00
sneak was assigned by clawbot 2026-10-03 16:58:08 +02:00
clawbot added merge-ready and removed needs-checks labels 2026-10-03 16:58:09 +02:00
clawbot added 1 commit 2026-10-04 03:43:42 +02:00
The workflow lines now say who merges where: clawbot squash-merges
reviewed issue PRs into next, only sneak merges next into main, and a
deploy is a squash commit from main onto prod, never automatic.

Status lists what is on next today, each item linked to its issue: the
repo standards, interface detection on Linux and macOS, the macOS VPN
detection fix, the Starlink status lines, the version stamp, and CI
running script/cibuild. Next Step is the owner's merge of the milestone
PR and a first run on a real Mac.

Model: opus-5-5
All checks were successful
check / check (push) Successful in 3m18s
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin next:next
git checkout next
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/rtnetmon#6