1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#+TITLE: Instrument-console rebuild — net + bluetooth panels
#+DATE: 2026-07-03
#+TODO: TODO | DONE
#+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED
* IMPLEMENTED Status
:PROPERTIES:
:ID: e73877f5-4f5b-4f81-b946-dbaa6145e0d5
:END:
- 2026-07-03 Fri @ 06:49 -0400 :: DOING → IMPLEMENTED: all six phases shipped
(net GTK-free layer 81ec9c3, net view 800ef60; bt GTK-free layer 5318b34, bt
view 66f03d9; phase-6 dead-code removal f4e688e). Both panels are single-screen
instrument consoles, verified live on velox — 46 suites + full make test green,
both AT-SPI smokes green end to end, render matching the approved prototype. The
three folded tasks (network panel redesign, bt switch placement + title, bt
rename devices) closed with the build.
- 2026-07-03 Fri @ 02:07 -0400 :: DRAFT → READY → DOING in one stroke: Craig
approved the design through five interactive prototype iterations and
authorized the no-approvals speedrun ("let's build them now... go"). The
review gate was the live prototype session itself.
- 2026-07-03 Fri @ 02:07 -0400 :: Created (DRAFT) from the prototype session.
* Metadata
| Field | Value |
|---------------------+------------------------------------------------------------|
| Status | implemented |
|---------------------+------------------------------------------------------------|
| Owner | Craig Jennings |
|---------------------+------------------------------------------------------------|
| Repos | dotfiles (net/, bluetooth/, themes), archsetup |
|---------------------+------------------------------------------------------------|
| Normative reference | [[file:../../assets/2026-07-03-instrument-console-panels-prototype.html][assets/2026-07-03-instrument-console-panels-prototype.html]] |
|---------------------+------------------------------------------------------------|
* Summary
Rebuild both GTK layer-shell panels (net, bluetooth) from the tabbed layout
to the instrument-console design: one screen, no tabs, a faceplate with a
state word + badges + radio switch + close, engraved section labels, lamp
rows that act on click, dial meters under the console keys, and a doctor
that does it all. The interactive prototype =panel-console-v3.html= is the
normative design reference — when this spec and the prototype disagree on a
visual or interaction, the prototype wins.
* Decisions (all resolved — Craig, prototype session 2026-07-02/03)
- Replace the tabbed panels outright. No fallback flag; git history is the
rollback. Net panel first, bluetooth second.
- Advanced repair tiers leave the panel entirely. DOCTOR runs the full
diagnose → classify → lightest-repair → re-verify escalation (the engine
already does this). The surgical tiers stay CLI-only (=net repair ...=).
- Faceplate (both panels): state lamp + state word, badges, unit label
(NET·01 / BT·01), radio switch (wifi radio / bt adapter power), close ✕.
Badges: TUNNEL (gold, net), AIRPLANE (gold, both), LOW BATT (red, bt).
- Sections in order — net: CHANNEL, NETWORKS (+ hidden action), TUNNELS,
CONSOLE (DOCTOR / SPEED TEST keys), meters, output. bt: ADAPTER (with
clickable =discoverable= chip), PAIRED, NEARBY (+ scanning note), CONSOLE
(DOCTOR / SCAN), battery gauges, output.
- Section row budgets, half-row peek, internal scroll (thin slate
scrollbar): NETWORKS 5.5 rows, TUNNELS 4.5, PAIRED 5.5, NEARBY 4.5.
In-range networks sort active-first then strongest-signal-first. Counts on
the engraved headers ("networks · 12 in range", "tunnels · 1 up of 9",
"paired · 3", "nearby · 12"). The panel silhouette never grows with list
length; only the output well is variable and it caps at ~170px.
- Lamp-row grammar: green = live/connected, gold = available/actionable,
off = down/stored, red = failed; busy = pulsing gold during transitions.
Rows act on click (tunnels toggle, networks join, paired devices
connect/disconnect toggle, nearby devices pair).
- Arm-first for anything disruptive or destructive, 3s auto-disarm:
- forget (network or bt device): hover reveals ✕; first click arms the
row terracotta ("forget? click ✕ again"), second fires. No dialog.
- disconnect (active network): click the active row; first click arms in
GOLD ("disconnect? click again") — disruptive, not destructive — second
fires.
- Meters (net): two dials, RX·DOWN / TX·UP, gold needles, mode tag top-left
(LIVE green / TEST gold), HOLD tag top-right. Idle: live link throughput.
Speed test: cards flash gold, needles sweep the measured rate, then PIN
the final value with HOLD; clicking a held meter releases it to LIVE.
Scale 0–100 Mbps, auto-relabel to 0–1000 when a reading exceeds 100.
Dial top inset ~13px so the corner tags never touch the arc.
- Speed test output well gets ONLY: location line ("location: <city> by
<sponsor>"), ping (+jitter), final line, conditioned tip(s). The rates
live in the meters, not the text.
- Battery gauges (bt): same dial chrome; one per connected device (two
slots; empty slot dim "NO DEVICE"/"ADAPTER OFF"); needle+value red under
15% and the LOW BATT faceplate badge lights.
- Output well: doctor streams the checks with their narration lines
(viewmodel.STEP_NARRATION) and repair steps in gold; verdict line closes
(olive for pass/fixed). A dismiss ✕ appears in the well's corner whenever
it has content. Both panels.
- WiFi radio switch: =nmcli radio wifi on|off=. Off empties NETWORKS to one
dim "wifi radio off" row, drops the connection, kills tailscale rows'
reachability; on rejoins the last network (NM autoconnect does this for
real). Airplane mode is system-level (Super+Shift+A owns it): both panels
reflect it (state word AIRPLANE, gold badge, switches down); a switch
flipped under airplane refuses with a toast naming the exit. A routed
ethernet link keeps the net panel ONLINE through airplane mode.
- Ethernet: presence-based row pinned atop NETWORKS when a cable is up
("enp… · active · wired · 1.0 Gbps" / "wired · standby"); CHANNEL swaps
the signal ladder for "wired · <speed> full-duplex" when routed; clicking
the row toggles route ownership via device disconnect/connect.
- Pairing (bt): nearby row click → busy → passkey-confirm dialog (large
gold digits) → device moves to PAIRED and connects. SCAN key refreshes
with a "scanning…" note on the header.
- Rename (bt): hover ✎ on a paired row → dialog prefilled → bluez
=set-alias= (closes the filed rename task).
- Tooltips: any ellipsized row label carries its full text as the tooltip.
- Dialogs (join / hidden SSID / passkey / rename) keep the in-panel dupre
dialog style (gold border, dark well inputs, gold caret).
- Close: ✕ on the faceplate + Esc (already shipped; keep).
- Folded tasks: "Network panel redesign", "Bluetooth panel: switch placement
+ panel title", "Bluetooth panel: rename devices" — all close with this
build's phases.
* Engine gaps (small, close during phases)
- radio verb: =nmcli radio wifi on|off= helper (manage or sysio) + tests.
- hidden-SSID join: =manage.add= grows a hidden flag
(=802-11-wireless.hidden yes=).
- ethernet: device rows from =nmcli dev= (type ethernet) + disconnect/
connect verbs (device-level; =net down --iface= already disconnects).
- bt rename: btctl =set-alias= one-shot verb + verify-after read.
- bt battery: already exposed (indicator uses it).
- speedtest meters: =run_speedtest_stream= on_update already ticks (pty).
- link speed for wired channel line: =ethtool=-free read from
=/sys/class/net/<dev>/speed=.
* Implementation phases
1. [X] Spec + task wiring (this file; todo.org parent task with :SPEC_ID:).
2. [X] Net GTK-free layer (TDD): viewmodel row composers for the console
sections (network rows sorted+counted, tunnel rows, channel facts,
faceplate state word derivation, meter scale logic, arm state machines
for forget/disconnect), PanelModel restructure (sections, no tabs).
Engine gaps: radio verb, hidden join, ethernet rows, wired link speed.
3. [X] Net view rebuild: gui.py single-page console built in Python
(faceplate, engraved scrolled sections, console keys, cairo dial meters
with mode/hold tags, output well + dismiss), panel.css additions
(engrave, lamps, dial, badges, arm tints). AT-SPI smoke + driver
rewritten for the console layout. Shipped with phase 4 (dotfiles
800ef60): a view-only intermediate is a broken panel (rows and switches
that do nothing), so view + interactions landed together.
4. [X] Net interactions: join/hidden/forget (arm terracotta)/disconnect
(arm gold)/radio switch/ethernet toggle/doctor stream/speed-test-drives-
meters, toasts. Verified live on velox (DOCTOR streams, SPEED TEST sweeps
both dials then HOLD). Shipped in dotfiles 800ef60 with phase 3.
5. [X] Bluetooth panel: same treatment end to end (faceplate + power
switch, adapter chip, paired/nearby lamp rows, pair passkey flow,
rename via set-alias, forget arm, battery gauges + LOW BATT, DOCTOR /
SCAN keys, output). bt smoke rewritten. Shipped in two commits mirroring
net: dotfiles 5318b34 (GTK-free layer + engine gaps) and 66f03d9 (view +
interactions + smoke). rename lands on the bluez Alias via busctl
(set-alias has no MAC-addressed one-shot); verified live on velox (smoke
green end to end, screenshot matches the prototype).
6. [X] Live verification both panels on velox + all suites + smokes green;
summary of findings written to file; folded tasks closed; dead code
removed; session context finalized.
|