aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/2026-07-02-net-panel-other-interfaces-spec.org
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-04 12:38:10 -0500
committerCraig Jennings <c@cjennings.net>2026-07-04 12:38:10 -0500
commit22101e1f1bc846885798b5815318a41110110a1c (patch)
treeab0b0656a990bbb14475fa3954102a4bec87f1df /docs/specs/2026-07-02-net-panel-other-interfaces-spec.org
parent16a53cdff389e2059fa2e3c20de98e8c0a18dcb6 (diff)
downloadarchsetup-22101e1f1bc846885798b5815318a41110110a1c.tar.gz
archsetup-22101e1f1bc846885798b5815318a41110110a1c.zip
docs(spec): sort formal specs into docs/specs/ with lifecycle status
Moved the seven formal specs from docs/design/ into docs/specs/, each stamped with a lifecycle status heading: four IMPLEMENTED (bluetooth, net-other-interfaces, audio, instrument-console), one CANCELLED (file-manager-swallow), two DRAFT (desktop-settings, timer). Rewrote the seven todo.org links to the new paths. The two -spec.org files without the spec spine (waybar-network-module, waybar-timer-module) stayed in docs/design/ as notes.
Diffstat (limited to 'docs/specs/2026-07-02-net-panel-other-interfaces-spec.org')
-rw-r--r--docs/specs/2026-07-02-net-panel-other-interfaces-spec.org195
1 files changed, 195 insertions, 0 deletions
diff --git a/docs/specs/2026-07-02-net-panel-other-interfaces-spec.org b/docs/specs/2026-07-02-net-panel-other-interfaces-spec.org
new file mode 100644
index 0000000..0d63feb
--- /dev/null
+++ b/docs/specs/2026-07-02-net-panel-other-interfaces-spec.org
@@ -0,0 +1,195 @@
+#+TITLE: Net Panel — Tailscale, VPN, and WireGuard Interfaces
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-07-02
+#+TODO: TODO | DONE
+#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED
+
+* IMPLEMENTED Net Panel — Tailscale, VPN, and WireGuard Interfaces
+:PROPERTIES:
+:ID: 09f4cd40-f391-4eba-a4ff-c22bad00ad7f
+:END:
+- 2026-07-04 Sat @ 12:36:56 -0500 — retrofitted by spec-sort; status set to IMPLEMENTED (reason: Tunnels track shipped detection, diagnose, and panel bring-up; build task DONE.)
+
+* IMPLEMENTED Status
+:PROPERTIES:
+:ID: 79a1075a-4b56-4f25-a861-b69f120a636a
+:END:
+- [2026-07-02 Thu] IMPLEMENTED — all six phases shipped (dotfiles 2d9d060,
+ 21db05a, 31ba056, b4010bf, b5c8442; archsetup 0389790 + the wireguard
+ import script): probes, panel Tunnels view, diagnose/doctor route
+ awareness, bar badge, installer swap + operator, velox config migration.
+ Residual human steps filed under todo.org "Manual testing and
+ validation": proton CLI sign-in (per machine) and the first live
+ badge/tunnel round-trip. Ratio picks up the import + package swap on its
+ trip.
+- [2026-07-02 Thu] DOING — decomposed into six build phases under the
+ todo.org parent (:SPEC_ID: bound); build started same evening per Craig
+ ("tunnels build now + audio-panel spec alongside").
+- [2026-07-02 Thu] READY — fused review passed the gate: 4/4 decisions
+ resolved, phases decomposable, claims re-verified live (proton-vpn-cli
+ 1.0.1 in extra, binary =/usr/bin/protonvpn=, no package conflict with the
+ GTK app; =tailscale status --json= shape confirmed on velox — Self/Peer/
+ CurrentTailnet.Name/MagicDNSSuffix; zero NM wireguard connections yet,
+ seven configs in assets awaiting the phase 6 import).
+- [2026-07-02 Thu] DRAFT — initial spec from the roam capture "other network
+ interfaces (tailscale, VPNs, wireguard)" filed in todo.org 2026-07-02.
+
+* Metadata
+
+| Field | Value |
+|--------+---------------------------------------------------|
+| Status | implemented |
+|--------+---------------------------------------------------|
+| Owner | Craig Jennings |
+|--------+---------------------------------------------------|
+| Repo | dotfiles (net module); archsetup (packages) |
+|--------+---------------------------------------------------|
+| Parent | Waybar network module spec (2026-06-29), V2 panel |
+|--------+---------------------------------------------------|
+
+* Problem
+
+The net panel's Connections tab shows what NetworkManager knows: WiFi networks
+and wired links. The machines also run overlay and tunnel interfaces the panel
+is blind to:
+
+- Tailscale (tailscaled, both daily drivers; the tailnet is how the machines
+ reach each other; not an NM device)
+- WireGuard configs (assets/wireguard-config/ carries Proton VPN configs;
+ importable as NM connections of type wireguard or run via wg-quick)
+- Commercial VPN clients (Proton VPN GTK app is installed on velox; owns its
+ own tunnel device)
+
+When one of these is up it changes routing, DNS, and reachability — exactly
+the things the Diagnostics tab reasons about — yet the panel neither shows nor
+controls them, and the doctor can misattribute a VPN-caused failure to the
+underlying link.
+
+* Goals
+
+1. Visibility: the Connections tab shows overlay/tunnel interfaces with live
+ state (up/down, address, and for tailscale the tailnet peers summary).
+2. Control: bring each up or down from the panel row, same interaction shape
+ as Join/Disconnect on WiFi rows (no terminals — V2 contract).
+3. Diagnostics awareness: diagnose/doctor know when a tunnel owns the default
+ route or DNS, name it in evidence rows, and stop misattributing its
+ failures to the physical link.
+
+Non-goals (this iteration): installing or configuring VPN providers, tailnet
+ACL management, exit-node selection UI (a "use exit node" affordance can ride
+a later pass), kill-switch management (tracked separately in the spec's
+failure catalog).
+
+* Design sketch
+
+** Data sources — one probe per backend, engine-side
+
+New GTK-free module net/src/net/overlays.py with one probe per backend,
+each returning the same small dict shape ({kind, name, state, addr, detail,
+can_toggle}):
+
+- tailscale: =tailscale status --json= (rich: self, peers, exit node, health
+ messages). Daemon down → state "stopped". Binary absent → backend absent.
+- wireguard-nm: =nmcli -t connection show= filtered to type wireguard —
+ up/down via the existing nmcli wrapper (activate/deactivate connection).
+ The seven Proton configs in assets/wireguard-config/ import cleanly
+ (=nmcli connection import type wireguard file <conf>=, then
+ =connection.autoconnect no= immediately — imports default to autoconnect
+ yes). They use only PrivateKey/Address/DNS + PublicKey/AllowedIPs/Endpoint,
+ no PostUp/PostDown anywhere, so no wg-quick path is needed at all
+ (Craig, 2026-07-02). All are full-tunnel (AllowedIPs 0.0.0.0/0) — the
+ panel should treat them as mutually exclusive.
+- proton: drive the official proton-vpn-cli (Arch extra repo, v1.0.x,
+ stable since 2026-04) — connect/disconnect/status verbs. It drives NM
+ underneath (python-proton-vpn-network-manager), so the panel still sees
+ connection events through NM. Runtime-exclusive with the GTK app, which
+ gets dropped from the install. The imported NM wireguard configs remain
+ a raw fallback when the CLI/API path is down; the CLI stays primary
+ because the raw configs lack kill switch, port forwarding, and server
+ rotation.
+
+** Panel
+
+A fourth Connections group "Tunnels" (after Saved / Available now / Wired)
+using the existing group-header + row machinery. Row: glyph per kind, name,
+state caption; primary action Up/Down where can_toggle, else Open app.
+Tailscale row detail (subtitle or tooltip): tailnet name, peer count online,
+exit node if any.
+
+** Privileged path
+
+- tailscale up/down: needs root or operator — =tailscale set --operator= at
+ install time (archsetup) makes the user an operator, so no sudo needed at
+ runtime. Fallback: the V2 net-priv helper gains tailscale-up/down verbs.
+- NM wireguard connections: no privilege needed (NM polkit default for the
+ active user).
+
+** Diagnostics awareness
+
+- diag gains an "overlay owns default route/DNS" detection step: when the
+ default route or resolv.conf points at a tunnel interface, evidence names
+ it ("default route via tailscale0") and failure classification runs the
+ physical-link checks against the underlying device instead.
+- doctor: a tunnel-caused egress failure (VPN up but its endpoint dead)
+ classifies fixable with next_action "bring the tunnel down / reconnect",
+ not a WiFi reset.
+
+** Bar indicator
+
+Part of v1 (Craig, 2026-07-02 — "shouldn't be optional"): a small overlay
+badge on the net glyph when a tunnel owns the default route. Rides the same
+route/DNS-ownership detection the diagnostics step adds.
+
+* Decisions (Craig)
+
+** DONE Which backends ship in the first pass?
+CLOSED: [2026-07-02 Thu]
+Approved (Craig, 2026-07-02): tailscale + NM-managed wireguard. Craig asked
+whether the wireguard configs can be ported to NM so wg-quick drops out
+entirely — yes: all seven configs in assets/wireguard-config/ use only the
+six directives NM imports cleanly (verified 2026-07-02; import command and
+autoconnect caveat now in the design sketch). wg-quick is out of the spec,
+not deferred. Proton control is CLI-driven per the Proton decision below,
+superseding the detection-only recommendation here.
+
+** DONE Tailscale control path: operator flag at install vs net-priv verbs?
+CLOSED: [2026-07-02 Thu]
+Approved (Craig, 2026-07-02): =tailscale set --operator=$USER= in archsetup's
+tailscale step (declarative, no sudo at runtime); net-priv verbs only if
+operator mode proves insufficient (e.g. up with flags).
+** DONE Does "Tunnels" belong in Connections or its own tab?
+CLOSED: [2026-07-02 Thu]
+Approved (Craig, 2026-07-02): a Connections group. A fourth top tab dilutes
+the V2 nav for three rows.
+
+** DONE Proton VPN: detect-only or drive its CLI?
+CLOSED: [2026-07-02 Thu]
+Decided (Craig, 2026-07-02): drive it through a CLI. Research (2026-07-02):
+Proton shipped an official Linux CLI — first release 2025-11, stable v1.0.0
+2026-04, packaged in Arch extra as proton-vpn-cli (1.0.1 at check time),
+with kill switch, port forwarding, NetShield, server selection, and a
+status command. It drives NM underneath, so the panel sees its connections
+through the existing NM event path. Spec changes: the proton backend calls
+protonvpn connect/disconnect/status instead of device-detection
+(can_toggle true); archsetup installs proton-vpn-cli and drops
+proton-vpn-gtk-app (the two can't run concurrently per the project README —
+untested locally); the imported NM wireguard configs stay as a raw fallback.
+Sources: [[https://protonvpn.com/support/linux-cli][Proton Linux CLI guide]],
+[[https://protonvpn.com/support/release-notes-linux-cli][CLI release notes]],
+[[https://github.com/ProtonVPN/proton-vpn-cli][proton-vpn-cli repo]].
+* Implementation phases
+
+1. overlays.py probes (tailscale JSON, nmcli wireguard filter, proton-vpn-cli
+ status) — pure engine, TDD with fake binaries; =net status= grows an
+ overlays section.
+2. Panel Tunnels group + Up/Down wiring through the worker thread; AT-SPI
+ smoke extension.
+3. Diagnose/doctor overlay awareness (route/DNS ownership step, classifier
+ rows, evidence text) — TDD against the diag harness.
+4. waybar-net tunnel badge on the net glyph (v1 per the bar-indicator
+ decision), riding phase 3's route-ownership detection; suite coverage.
+5. archsetup: tailscale operator flag in the tailscale install step;
+ proton-vpn-cli replaces proton-vpn-gtk-app in the package list; VM test
+ assertions.
+6. One-time per-machine migration: import the seven assets/wireguard-config
+ configs into NM with autoconnect off (scriptable; both daily drivers).