diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-02 15:21:13 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-02 15:21:13 -0400 |
| commit | bfadf6a602cfd593d7c43515056a6cc637dceb94 (patch) | |
| tree | 8def2a00b5cf6dcb57cbd17fa238d184dd30d8d5 | |
| parent | d8d8c532798cb8be59ca84407022233afa2b79bb (diff) | |
| download | archsetup-bfadf6a602cfd593d7c43515056a6cc637dceb94.tar.gz archsetup-bfadf6a602cfd593d7c43515056a6cc637dceb94.zip | |
feat(bluetooth): prove the fresh-install panel wiring in VM assertions
Phase 5 needed no new install code: the waybar module, keybind, and shared panel css ride the dotfiles hyprland tier the installer already stows, and sudoers is covered by the existing grant. I added hyprland-gated assertions instead: bt bins stowed executable, custom/bluetooth in the waybar config, the bt-panel bind in hyprland.conf, panel.css present. This closes the bluetooth-panel task and flips the spec to implemented.
| -rw-r--r-- | docs/design/2026-07-02-bluetooth-panel-spec.org | 25 | ||||
| -rw-r--r-- | scripts/testing/tests/test_desktop.py | 29 | ||||
| -rw-r--r-- | todo.org | 13 |
3 files changed, 59 insertions, 8 deletions
diff --git a/docs/design/2026-07-02-bluetooth-panel-spec.org b/docs/design/2026-07-02-bluetooth-panel-spec.org index 89872f5..121197a 100644 --- a/docs/design/2026-07-02-bluetooth-panel-spec.org +++ b/docs/design/2026-07-02-bluetooth-panel-spec.org @@ -4,10 +4,16 @@ #+TODO: TODO | DONE #+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED -* DOING Status +* IMPLEMENTED Status :PROPERTIES: :ID: 1271a845-4463-4831-9902-990eda6b2265 :END: +- [2026-07-02 Thu] IMPLEMENTED — all five phases shipped the same day + (dotfiles eb2230f / 76b2c05 / e372de3 / 2a026b1; archsetup d8d8c53): + engine, panel, bar module + blueman retirement, bt-priv + package swap, + install wiring proven by VM assertions. 43 dotfiles suites green, both + AT-SPI smokes green, panels verified live; the phase 4-5 VM assertions + run on the next VM pass. - [2026-07-02 Thu] DOING — spec-response decomposed the five phases into build sub-tasks under the todo.org parent (:SPEC_ID: bound); build started same day per Craig ("4 first, then 1" — bugs then bluetooth). @@ -23,7 +29,7 @@ | Field | Value | |--------+---------------------------------------------------------------------------------| -| Status | doing | +| Status | implemented | |--------+---------------------------------------------------------------------------------| | Owner | Craig Jennings | |--------+---------------------------------------------------------------------------------| @@ -363,6 +369,21 @@ Non-blocking; it's the donor default made explicit. * Review and iteration history +** 2026-07-02 Thu @ 15:19:58 -0400 — Claude Code (archsetup) — phase 5 builder, spec closed +- *What changed or was recommended:* Phase 5 shipped and the spec flipped + to IMPLEMENTED. No new install code was needed — the waybar module, the + =Super+Shift+B= bind, and the shared panel css all ride the dotfiles + hyprland tier that a fresh install already clones and stows, and sudoers + is covered by the blanket grant. The phase's substance is proof: + =test_desktop.py= gained hyprland-gated assertions for the four stowed + bt bins, the =custom/bluetooth= waybar entry, the =bt-panel= keybind, + and the stowed =panel.css=. +- *Why:* Final phase of the DOING decomposition; with it the todo parent + closed and the lifecycle keyword flipped with a history line. +- *Artifacts:* archsetup =scripts/testing/tests/test_desktop.py=; todo.org + parent DONE + dated phase 5 / test-surface entries; this spec's Status + heading. + ** 2026-07-02 Thu @ 15:16:51 -0400 — Claude Code (archsetup) — phase 4 builder - *What changed or was recommended:* Phase 4 shipped. Dotfiles =2a026b1=: the stowed =bt-priv= shim (one verb, verified against the fake-systemctl) diff --git a/scripts/testing/tests/test_desktop.py b/scripts/testing/tests/test_desktop.py index c02d2b6..6f79bfd 100644 --- a/scripts/testing/tests/test_desktop.py +++ b/scripts/testing/tests/test_desktop.py @@ -109,3 +109,32 @@ def test_autologin_configured(host): if not conf.exists: pytest.skip("autologin not configured (AUTOLOGIN=no, may be intentional)") assert conf.exists + + +BT_PANEL_BINS = ["bt", "bt-panel", "bt-priv", "waybar-bt"] + + +@pytest.mark.attribution("archsetup") +@pytest.mark.parametrize("name", BT_PANEL_BINS) +def test_bt_panel_bin_stowed(host, hyprland_installed, home, name): + # Executable via either stow shape (per-file symlink or folded dir). + if not hyprland_installed: + pytest.skip("Hyprland not installed (DESKTOP_ENV != hyprland)") + path = "%s/.local/bin/%s" % (home, name) + assert host.file(path).exists, "%s missing from ~/.local/bin" % name + assert host.run("test -x %s" % path).rc == 0, "%s not executable" % name + + +@pytest.mark.attribution("archsetup") +def test_bt_panel_wired(host, hyprland_installed, home): + # A fresh install lands the panel reachable: bar module, keybind, css. + if not hyprland_installed: + pytest.skip("Hyprland not installed (DESKTOP_ENV != hyprland)") + waybar = host.file("%s/.config/waybar/config" % home) + assert "custom/bluetooth" in waybar.content_string, \ + "waybar config lacks the custom/bluetooth module" + hyprconf = host.file("%s/.config/hypr/hyprland.conf" % home) + assert "bt-panel" in hyprconf.content_string, \ + "hyprland.conf lacks the bt-panel keybind" + assert host.file("%s/.config/themes/dupre/panel.css" % home).exists, \ + "shared panel css missing from the stowed theme" @@ -537,11 +537,12 @@ Design / open questions (propose before building): Implementation notes: a small GTK layer-shell app (mirror pocketbook's structure: src-layout Python package, pytest, Makefile) talking to brightnessctl / hyprctl / the touchpad + airplane helpers. Lives in the dotfiles repo or in-tree like pocketbook. TDD the backing toggle/slider logic. Sizable — worth a design doc first. -** DOING [#B] Bluetooth panel + bar module :feature:waybar:bluetooth: +** DONE [#B] Bluetooth panel + bar module :feature:waybar:bluetooth: +CLOSED: [2026-07-02 Thu] :PROPERTIES: :SPEC_ID: 1271a845-4463-4831-9902-990eda6b2265 :END: -Spec: [[file:docs/design/2026-07-02-bluetooth-panel-spec.org]] (DOING — reviewed READY and decomposed 2026-07-02; all four decisions resolved, two non-blocking findings dispositioned in the fused review pass). +Spec: [[file:docs/design/2026-07-02-bluetooth-panel-spec.org]] (IMPLEMENTED 2026-07-02 — all five phases shipped same day: engine eb2230f, panel 76b2c05, bar module e372de3, bt-priv + blueman retirement 2a026b1/d8d8c53, install wiring proven by VM assertions). Residual: the phase 4-5 VM assertions run on the next VM pass; ratio picks up the package removal + hand-links on its trip list. A bluetooth panel driving a CLI underneath (bluetoothctl one-shot verbs), consistent in look and feel with the net panel (GTK4 + layer-shell + Blueprint, humble-object presenter, verify-everything). Minimalistic interface, full functionality, plus a diagnostics/troubleshooting section mirroring the net panel's Diagnostics tab. Bar module glyph opens it. Craig's ask (2026-07-02): follow UX/UI best practices; where the net panel's patterns conflict with best practices, file a net-panel bug task rather than clone the flaw. @@ -557,11 +558,11 @@ Cloned the net panel's shape over the phase 1 engine: GTK-free PanelModel + view *** 2026-07-02 Thu @ 15:16:51 -0400 Shipped phase 4 — bt-priv shim, blueman out, VM assertions Dotfiles =2a026b1=: the stowed =bt-priv= shim over the phase-2 =bt.priv= module (one verb, =restart-bluetooth=; verified end-to-end against the symlinked fake-systemctl — rc 0 with =BT_SUDO= empty, rc 2 on bad verb/usage; hand-linked into =~/.local/bin=), and the sxhkd =Super+Shift+B= bind repointed from the retired blueman-manager to =st -e bluetoothctl= (the decided terminal fallback — the GTK panel is Wayland-only, and the bt CLI is hyprland-tier so dwm never gets it). 43 dotfiles suites green. archsetup: blueman dropped from the =desktop_environment= bluetooth loop (bluez + bluez-utils stay, solaar untouched); VM assertions added to =test_packages.py= (bluez/bluez-utils installed, blueman NOT installed as the retirement regression guard — collected 15, exercised on the next VM run since VM tests run committed code); =bash -n= + =py_compile= + =make test-unit= green. SUDOERS: no new rule needed, same conclusion as net-priv (2026-07-01 entry) — archsetup:1089 grants the primary user blanket =NOPASSWD: ALL=, which covers =systemctl restart bluetooth=; a narrow bt-priv rule would be dead config under the blanket grant, so phase 5's "sudoers placed" item is satisfied by the existing grant. LIVE: blueman package removed from velox (=pacman -Rns=, decision "drop it outright, both machines"); ratio needs the same + the bt-priv hand-link on its trip list. -*** TODO Phase 5 — install defaults (archsetup) :feature: -Keybind/config defaults so a fresh install lands the panel wired: waybar module present, bind set, sudoers placed. +*** 2026-07-02 Thu @ 15:19:58 -0400 Shipped phase 5 — install-default wiring proven by VM assertions +No new install code was needed: the waybar =custom/bluetooth= module, the =Super+Shift+B= → =bt-panel= bind (hyprland.conf), and the shared =themes/dupre/panel.css= all live in the dotfiles hyprland tier, so the existing clone + =make stow hyprland= step lands them on a fresh install; sudoers is covered by the blanket grant (phase 4 conclusion). The phase's substance is the proof: =test_desktop.py= gained hyprland-gated assertions that the four bt bins (=bt=, =bt-panel=, =bt-priv=, =waybar-bt=) are stowed executable in =~/.local/bin= (either stow shape — per-file symlink or folded dir), the waybar config carries =custom/bluetooth=, hyprland.conf carries the =bt-panel= bind, and the stowed theme has =panel.css=. Collected 30 in =test_desktop.py=; exercised on the next VM run (VM tests run committed code). -*** TODO Test surface :test: -Engine suites over fake binaries (bluetoothctl show/devices/info/scan parse, doctor chain verdicts, A2DP repair verify), PanelModel presenter suite, pairing state-machine suite (passkey confirm / NoInputNoOutput / timeout), bar-module suite, gated AT-SPI smoke, VM assertions for phases 4-5. +*** 2026-07-02 Thu @ 15:19:58 -0400 Test surface complete across all phases +Everything the surface named exists and is green: engine suites over fake binaries (phase 1, 101 tests — btctl parse, doctor chain, A2DP repair verify), PanelModel presenter suite (phase 2, 69 tests), pairing state-machine suite (passkey confirm / NoInputNoOutput / timeout, over the fake's interactive mode), bar-module suite (phase 3), gated AT-SPI smoke (=make test-panel-bt=, run green live), and the phase 4-5 VM assertions (=test_packages.py= bluetooth stack + blueman-absent guard; =test_desktop.py= panel wiring). 43 dotfiles suites green; VM assertions await the next VM run. ** TODO [#B] Local offline LLM runtime + per-host model cache :tooling:llm: :PROPERTIES: |
