From 86724cb0aefd93585241eeb93563e9c7779cdad3 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Mon, 29 Jun 2026 18:36:47 -0400 Subject: docs(todo): break the waybar network module into implementation phases The network spec is Ready, so I decomposed it into one parent task with Phase 1-5 children (indicator + console recovery, panel + connection management, diagnostics + speed test, docs + rollout, VPN vNext), each naming its deliverable, tests, and verification. I consolidated the two source tasks into that parent: the wifi-no-internet task is cancelled (folded in, now Phase 1 + Phase 3), and the network-manager task became the parent. I seeded the Phase 1 live checks under Manual testing and validation, since the live network and visual states need real conditions. --- todo.org | 127 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 30 deletions(-) (limited to 'todo.org') diff --git a/todo.org b/todo.org index 44b6591..ea8864f 100644 --- a/todo.org +++ b/todo.org @@ -80,30 +80,73 @@ Builds on the just-shipped =custom/sysmon= collapse (dotfiles be7469b). Right-cl Implementation notes: =waybar-sysmon= needs a persisted selection (a state file in =$XDG_RUNTIME_DIR/waybar/=, absent = host default) that it reads to pick the visible metric. A new =sysmon-cycle= helper bumps the index and signals the module to refresh (add a =signal= to =custom/sysmon=, like the other custom modules; wire =sysmon-cycle= to =on-click-right=). TDD both — extend =tests/waybar-sysmon= for selection-driven output, add a =tests/sysmon-cycle= for the index advance/wrap and the signal. -** TODO [#B] Network-manager dropdown, nmcli-backed with GPG-stored secrets :waybar:network: +** TODO [#B] Waybar network module — custom/net :feature:waybar:network: :PROPERTIES: -:LAST_REVIEWED: 2026-06-09 +:LAST_REVIEWED: 2026-06-29 :END: -Replace the current wifi/network waybar component with a self-contained network manager driving nmcli directly (no =nmtui= dependency). Same look as the existing indicator; clicking it drops down the management interface (design open, keep it minimalistic). - -Core functionality: -- Add / edit / remove connections. -- List saved connections by SSID, ordered by recency (most-recently-used first); select one to switch to it. -- Recognize a wired/ethernet connection even when plugged in after the session started, and allow selecting it at any time. Switch freely: ethernet↔wifi, wifi↔wifi. -- Match all current functionality of the existing wifi/network component (status icon, signal strength, tooltip). - -Credential storage: -- Store connection definitions + passwords in a GPG-encrypted file under =~/.config= (appropriate XDG location), encrypted to Craig's private key. -- Passphrase cadence configurable: decrypt once per session, once per hour (via gpg-agent cache TTL), or never (plaintext / stays decrypted). *Default is unencrypted* — encryption is opt-in. - -Design / open questions (propose before building): -- Dropdown UI tech: a GTK layer-shell panel (like pocketbook), a fuzzel/rofi-style menu, or a waybar-native expanding group. -- Relationship to NetworkManager's own store (=/etc/NetworkManager/system-connections=, root-only): does the GPG store supplement or replace it, and how do they stay in sync. -- Whether to keep the existing =custom/netspeed= throughput readout alongside the new SSID/status indicator. - -Implementation notes: backing scripts in the dotfiles repo (hyprland tier); nmcli for every NM op (device status, con up/down, add/modify/delete, wifi rescan/list). TDD the nmcli-wrapper logic with a fake nmcli on PATH. Sizable — worth a =docs/design/= doc before implementation. +Unifies the old wifi-no-internet indicator (was =[#C]=) and the network-manager +dropdown (was =[#B]=) into one =custom/net= module: a tested Python =net= engine +(nmcli + diagnostics), a thin bar indicator, and a GTK4 layer-shell panel. Code +lives in the dotfiles repo (hyprland tier + a =net/= package like pocketbook); +archsetup only installs deps. Secrets stay in NetworkManager's own store (no +separate credential store). The =captive= script becomes the diagnostics engine. +Full design, acceptance criteria, and the failure-mode coverage table: +[[file:docs/design/2026-06-29-waybar-network-module-spec.org][2026-06-29-waybar-network-module-spec.org]]. -Design doc: [[file:docs/design/2026-06-29-waybar-network-module-spec.org][2026-06-29-waybar-network-module-spec.org]] — unified with the =[#C]= wifi-state + diagnostics task into one =custom/net= module (engine + indicator + GTK4 layer-shell panel). This is Phase 2 (panel + connection management). Secrets stay in NetworkManager's own store (no separate GPG store). The =captive= script becomes the diagnostics engine. +Phases below, dependency order. Engine/unit work is agent-verifiable (=unittest= ++ fakes on PATH, coverage via venv); the live-network and visual states need real +conditions, filed under "Manual testing and validation". + +*** TODO Phase 1 — indicator + console recovery :network: +Deliverable: =net status= + =net probe= (native cheap captive probe) + the +=captive= =--json= probe refactor; =waybar-net= replacing =custom/netspeed=; +split-cadence cache (single-flight flock, atomic write, fresh/stale/expired/unknown +classes, iface/SSID/UUID invalidation); CSS states (captive/no-internet/degraded/ +rfkill); =net repair= tiers (rfkill/reset/bounce); =net doctor [--fix]= with the +four terminal classifications; Makefile console-recovery targets (=make online= +etc.); absorb the airplane state and delete the standalone airplane module +(=waybar-airplane=, =airplane-mode=, their tests, =custom/airplane= + css). +Tests: =tests/net/= + =tests/waybar-net/= unittest with fake nmcli/curl/rfkill/ +resolvectl on a temp PATH; doctor-classification fixtures; degraded-under-slow-nmcli +benchmark; branch coverage ≥90% on pure modules via a throwaway venv; coverage-gap +pass. +Verify (manual, live): see Manual testing and validation. + +*** TODO Phase 2 — panel shell + connection management :network: +Deliverable: GTK4 + gtk4-layer-shell panel (pocketbook scaffold); =net list/up/ +down/add/edit/remove/rescan= (open + WPA-PSK; enterprise activate-only); MRU list +with live signal; mutation safety + rollback (keep prior link until target +activates, no stranding); panel state machines; the panel UX flow (default focus, +primary buttons, disabled rules, confirmation wording, keyboard nav). +Tests: fake-nmcli command-sequence assertions (UUID-keyed, escaped parsing: +colon/backslash/newline/duplicate/hidden/non-ASCII); rollback keeps prior link on +failed switch; NM-secret write + no-secret-leak; panel state-machine transitions. +Verify (manual, live): see Manual testing and validation. + +*** TODO Phase 3 — diagnostics + speed test in the panel :network: +Deliverable: wire =net diagnose= / =net repair= / =net doctor= / =net portal= / +=net speedtest= into the Diagnose (read-only) vs Repair (mutating, confirmed) +sections; "Get me online" with live escalation reporting; portal Open button; +speedtest (=speedtest-go --json=) progress + cancel; failure-mode → exact-string +rendering across surfaces. +Tests: diagnose read-only; each repair tier confirms + verifies cleanup (DNS +override reverts → cleanup_verified, else cleanup-unverified); speedtest parse from +fixture JSON + fixture stderr failure messages. +Verify (manual, live): see Manual testing and validation. + +*** TODO Phase 4 — docs + rollout :network: +Deliverable: in-app help (=net --help= + per-command, panel help affordance); +README/user-guide (commands, indicator states, panel, config keys, make targets, +troubleshooting from the failure table, rollback); archsetup Hyprland dep install +(=gtk4-layer-shell=, =python-gobject=, =speedtest-go-bin=); ratio manual dep + +stow step. +Verify: =net --help= and each subcommand complete; user-guide covers every command ++ the recovery targets. + +*** TODO Phase 5 — VPN / WireGuard (vNext) :network: +Fold the existing archsetup wireguard tooling into the panel + CLI (=net vpn ...=). +Out of the v1 milestone; spec separately when picked up. (v1 only detects + +classifies a VPN-routed failure, it doesn't repair it.) ** DONE [#B] Network module: enterprise WiFi add/edit deferred to vNext :waybar:network: CLOSED: [2026-06-29 Mon] @@ -580,15 +623,13 @@ The goal is a single place to edit each config, not two. :END: Once-yearly systematic inventory of known deficiencies and friction points in current toolset -** TODO [#C] archsetup Waybar Wi-Fi module should show no-internet state :feature:waybar: -:PROPERTIES: -:LAST_REVIEWED: 2026-06-13 -:END: -From the roam inbox: the Waybar Wi-Fi module should distinguish "connected to an access point" from "connected and has internet." Add a no-internet state or indicator to the archsetup Waybar configuration. Not marked quick/solo because it needs the archsetup environment and live network-state verification. - -A 2026-06-22 roam capture expands the scope past a passive indicator: the wifi module should also bounce the network, run basic diagnostics, and optionally run a speed test with results — surfaced through modifier clicks (ctrl/super/meta) on the module. The no-internet state is the indicator; this adds active remediation off the same component. - -Design doc: [[file:docs/design/2026-06-29-waybar-network-module-spec.org][2026-06-29-waybar-network-module-spec.org]] — unified with the =[#B]= network-manager dropdown into one =custom/net= module. This is Phase 1 (indicator + cheap captive probe). Note: waybar can't qualify clicks by keyboard modifier, so the rich actions live in the dropdown panel, not ctrl/super/meta-clicks. +** CANCELLED [#C] archsetup Waybar Wi-Fi module should show no-internet state :feature:waybar: +CLOSED: [2026-06-29 Mon] +Consolidated, not dropped: the no-internet/captive indicator + the diagnostics/ +bounce/speed-test scope are now Phase 1 + Phase 3 of the unified +[[*Waybar network module — custom/net][Waybar network module — custom/net]] parent. The work continues there; +this separate entry is retired so it's tracked in one place. Spec: +[[file:docs/design/2026-06-29-waybar-network-module-spec.org][2026-06-29-waybar-network-module-spec.org]]. ** TODO [#C] Waybar emacs-service status + control :feature:waybar: :PROPERTIES: @@ -727,6 +768,32 @@ What we're verifying: the physical keychord opens a floating Dirvish popup; open - Expected: still exactly one popup — the second press focuses the existing one, no second frame, no stray buffer (for several independent file managers, use C-x d) - Press Super+Shift+F - Expected: GUI nautilus opens (the binding nautilus moved to) +*** Network module Phase 1 — indicator states on the live bar +What we're verifying: =custom/net= shows the right state for each real network condition. The engine logic is unit-tested; this is the live-bar + visual check (states can't be faked on the running bar). Phase 2-3 tests get added under this task as those phases land. +- Reload waybar to pick up =custom/net= (Super+B, or =pkill waybar; waybar &=). +- On a normal connected network, read the module. +- Expected: wifi glyph + signal + SSID; tooltip shows IPv4, gateway, throughput, and a recent "online" probe result. +- Join the hotel/captive network (or any portal network). +- Expected: the module shows the captive state (distinct glyph + warning color), tooltip names the portal host. +- Unplug to a network with no internet (or block egress). +- Expected: the no-internet state (distinct from captive and from disconnected). +*** Network module Phase 1 — net doctor recovers rfkill from a TTY +What we're verifying: the console-recovery path works with no GUI, and recovers the framework's post-power-loss soft-block. +#+begin_src sh :results output +rfkill block wifi # simulate the soft-block +rfkill list wifi # confirm Soft blocked: yes +#+end_src +- Switch to a TTY (Ctrl+Alt+F3) and log in (no Hyprland). +#+begin_src sh :results output +make -C ~/.dotfiles online # or: net doctor --fix +#+end_src +- Expected: doctor reports the rfkill block, runs =rfkill unblock wifi= + =nmcli radio wifi on=, reconnects, and ends "online" — all from the TTY. +*** Network module Phase 1 — airplane state absorbed, old module gone +What we're verifying: the airplane toggle/state moved into =custom/net= and the standalone module is removed cleanly. +- Toggle airplane mode (the keybind / the net module's control). +- Expected: =custom/net= reflects the airplane state; wifi drops and restores. +- Check the bar has no separate =custom/airplane= module, and =waybar-airplane= / =airplane-mode= are gone from =~/.local/bin=. +- Expected: no duplicate airplane indicator; no stale scripts. ** DOING [#B] Prepare for GitHub open-source release :PROPERTIES: -- cgit v1.2.3