From 5fedecbd7a25e6357ccfa1b9fa587d36752492a4 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Wed, 22 Jul 2026 17:13:09 -0500 Subject: feat(installer): enable the desktop-settings tick timer; close the panel build The desktop-settings panel shipped in dotfiles (backings engine, presenters, GTK port of prototype 37, phase-4 integration, and a 17-point end-to-end suite). This repo's share: the installer now links desktop-settings-tick.timer alongside the maint timers so a fresh install gets the wallpaper tick, the spec flips to IMPLEMENTED naming the shipping commits, and the build tasks close with the drag-gesture and locked-path night-watch checks filed for manual validation. --- archsetup | 1 + .../2026-07-02-desktop-settings-panel-spec.org | 7 +- todo.org | 111 ++++++++++++++------- 3 files changed, 81 insertions(+), 38 deletions(-) diff --git a/archsetup b/archsetup index c14bd9c..9d2c946 100755 --- a/archsetup +++ b/archsetup @@ -1502,6 +1502,7 @@ enable_maint_timers() { (mkdir -p "$unit_dir/timers.target.wants" "$unit_dir/default.target.wants" && \ ln -sf "$unit_dir/maint-scan.timer" "$unit_dir/timers.target.wants/maint-scan.timer" && \ ln -sf "$unit_dir/maint-net-scan.timer" "$unit_dir/timers.target.wants/maint-net-scan.timer" && \ + ln -sf "$unit_dir/desktop-settings-tick.timer" "$unit_dir/timers.target.wants/desktop-settings-tick.timer" && \ ln -sf "$unit_dir/maint-epp-restore.service" "$unit_dir/default.target.wants/maint-epp-restore.service" && \ chown -R "$username:$username" "/home/$username/.config/systemd") \ >> "$logfile" 2>&1 || error_warn "$action" "$?" diff --git a/docs/specs/2026-07-02-desktop-settings-panel-spec.org b/docs/specs/2026-07-02-desktop-settings-panel-spec.org index f2ac773..4618e75 100644 --- a/docs/specs/2026-07-02-desktop-settings-panel-spec.org +++ b/docs/specs/2026-07-02-desktop-settings-panel-spec.org @@ -4,16 +4,17 @@ #+TODO: TODO | DONE #+TODO: DRAFT READY DOING | IMPLEMENTED SUPERSEDED CANCELLED -* DOING Desktop-Settings Dropdown Panel +* IMPLEMENTED Desktop-Settings Dropdown Panel :PROPERTIES: :ID: d6bb1e73-ec90-4327-85ee-bfa762da5bce :END: - 2026-07-04 Sat @ 12:36:56 -0500 — retrofitted by spec-sort; status set to DRAFT (evidence-based, human-confirmed) -* DOING Status +* IMPLEMENTED Status :PROPERTIES: :ID: fb7eec22-a214-4568-82c4-903612f4832f :END: +- [2026-07-22 Wed] IMPLEMENTED — all four phases shipped in dotfiles: 7a15237 (phase 1, backings engine), 74f723e (bar slice, landed early), 5172289 (phase 2, presenters), 33d82eb (phase 3, GTK port of prototype 37), 680b50d (phase 4, projected faces / night watch / location / tick), 9038eee (the 17-point end-to-end pass re-derived from prototype 37's suite). Full dotfiles suite green (85 suites), AT-SPI smoke 13/13, e2e 17/17 on the live compositor. The Cairo drag gestures and the locked-path night-watch swap are on todo.org's "Manual testing and validation" checklist — human-eye checks, not blockers. Build adaptations from the phase logs: five-stage idle dial (WATCH ran as its own stage), held-to-unpause DND, no-backlight drums dim out, kiosk profile wiped per start, reveal gating pid-matched. - [2026-07-22 Wed] DOING — spec-response: the four rewritten implementation phases decomposed into build tasks in todo.org under a :SPEC_ID:-stamped parent, with the test surface and the final flip-to-IMPLEMENTED task emitted. The build proceeds in dotfiles settings/ per the location decision; archsetup drives. - [2026-07-22 Wed] READY — spec-review passed (rubric: Ready with caveats; see Review findings — two findings fixed in-run, two non-blocking build-time picks recorded). The prototyping gate closed at prototype 37, sealed by Craig's "Build it. Anything more would be bit fiddling." The FOCUS headphones glyph stands confirmed by the same words. Normative reference: prototype 37. - [2026-07-22 Wed] DRAFT — UI PROTOTYPING COMPLETE. Thirty-five prototypes ended at [[file:../prototypes/2026-07-02-desktop-settings-panel-prototype-35.html][Prototype 35, the final candidate]] (linked as the normative reference under Design sketch), sealed by Craig's "I think that's it" after his annotation batch applied clean. The design evolved far past the original controls table — programmable-presets matrix, instrument bench, wallpaper channels — with every turn recorded under Prototype iterations. The gate before READY is satisfied: research cited, ~5 directions grew to 35 with the winner iterated to final, every UI decision made against working prototypes. Next: spec-review (reconcile the Design sketch's aging architecture prose against what the prototypes actually settled), then spec-response into build phases. @@ -556,7 +557,7 @@ projects. | Field | Value | |--------+----------------------------------------------| -| Status | doing | +| Status | implemented | |--------+----------------------------------------------| | Owner | Craig Jennings | |--------+----------------------------------------------| diff --git a/todo.org b/todo.org index 717d8f4..bfe9e2e 100644 --- a/todo.org +++ b/todo.org @@ -45,24 +45,6 @@ below): input-side-spec.org (DRAFT, four decisions open). * Archsetup Open Work -** DOING [#B] Build: desktop-settings panel :feature:hyprland:dotfiles: -:PROPERTIES: -:SPEC_ID: d6bb1e73-ec90-4327-85ee-bfa762da5bce -:END: -The GTK build of the desktop-settings panel per the spec (docs/specs/2026-07-02-desktop-settings-panel-spec.org, DOING; normative reference: prototype 37). Work happens in dotfiles settings/ — archsetup drives the lifecycle. Two non-blocking build-time picks live in the spec's Review findings (wallpaper setter tool; store location/format) — decide in phase 1 and record there. -*** 2026-07-22 Wed @ 13:14:01 -0500 Built the backings engine (phase 1) — dotfiles 7a15237 -Landed as dotfiles settings/src/settings (10 modules) + tests/settings (118 tests against fake binaries, auto-discovered by make test — 81 suites green). Covers brightness/kbd (5% floor, x10 drum), toggles (dim, pointer cycle via toggle-touchpad, caffeine), DND class-split (dunst pause level 60, close-all before unpause, alarms punch through live), powerprofilesctl, nightlight (resident gammastep), hypridle.conf renderer + symlink-safe write + caffeine-respecting reload + hyprlock grace, suntimes (pure NOAA math), and the wallpaper engine (awww/mpvpaper/projector adapters, galleries, random draw, atomic JSON store). All three build-time picks recorded as DONE findings in the spec (setter=awww, store=state.json, nightlight=gammastep). Handoff note in ~/.dotfiles/inbox/. -*** TODO Phase 2 — presenters :solo: -GTK-free models at 100% unit coverage: program matrix (complete definitions, active-is-live surviving member writes, pin/letter/radio rows, slots 1-4), bench (drums, pointers, idle clamping/parking/bypass), wallpaper channels (mint/edit/delete/sort for pairs/sets/colors, per-mode sources, previews). -*** TODO Phase 3 — GTK4/Blueprint UI -Port prototype 37's instruments to GTK in family chrome: console keys, programmable matrix, drum roller, tripper dial (bottom legend, exact drag counter, bypass stamp), encircled groups, iconic channel cards, themed gallery wells, the three presses. Self-clocked instruments own their widget lifetime. Layer-shell chassis, sub-view navigation, AT-SPI smoke. -*** TODO Phase 4 — integration and bar -Bar consolidation LANDED EARLY (2026-07-22, live): gear module + Super+Shift+G wired; dim AND caffeine modules dropped (Craig amended decision A during the first drive — bar keeps only touchpad; dim/caffeine are panel-owned, keybinds stay). Remaining: watch/clock/world projected renderers (night watch as the hyprlock face); live hypridle rewrite; dunst pause-level config (alarm rules with override_pause_level 100); refresh-signal rewiring; end-to-end verify-everything. -Backing tools: mpvpaper (AUR) + power-profiles-daemon installed on ratio 2026-07-22 and added to the installer (ppd service enable gated on no-battery, since TLP owns power on laptops). Remaining: velox wants mpvpaper (and optionally the ppd package, service off) by hand — one-time AUR install the sync doesn't carry. -*** TODO Test surface — end-to-end pass -A scripted end-to-end pass mirroring prototype 37's 17-point suite against the real panel, plus the per-phase suites called out above. -*** TODO Flip the spec to IMPLEMENTED -When the phases land: flip docs/specs/2026-07-02-desktop-settings-panel-spec.org DOING → IMPLEMENTED with a dated history line naming the shipping commits. ** TODO [#C] Timer module hero hierarchy :feature:waybar:timer: From the roam inbox (Craig, claimed 2026-07-22). Which display ("hero") wins the waybar timer module when several timer modes run simultaneously: pomodoro wins over everything (the user is actively working; it's likely their main focus). The rest rank in chronological order of when they would ring. Worked example: with a just-started 15-min timer, a 1-hr timer at 10 minutes left, a pomodoro, and an alarm ringing in 12 minutes — show the pomodoro; when it completes, the 1-hr timer (rings first), then the alarm, then the 15-min timer. Feeds the timer-panel spec (docs/specs/2026-07-02-timer-panel-spec.org). ** TODO [#C] Timer module: drop RING message, persistent notifications :bug:waybar:timer: @@ -101,13 +83,6 @@ Post-mortem for the 2026-07-15 velox no-kernel boot failure, from the archsetup/ - Sanoid-vs-actual dataset drift: configure_zfs_snapshots configures zroot/var/log + zroot/var/lib/pacman as separate datasets; velox's actual layout has neither separate (/var/log sits inside zroot/var). Reconcile. - CONFIRMED (2026-07-21): the pre-pacman snapshot hook fired on velox — the 2026-07-15 no-kernel boot was recovered via the pre-pacman ZFS snapshot rollback, and velox is back on the tailnet running linux-lts 6.18.38 with initramfs present (2026-07-19 session). Root-cause hook-ordering fix shipped separately. Still open: the post-upgrade /boot assertion in guard.py and the sanoid-vs-actual dataset drift reconcile (the two bullets above). -** CANCELLED [#B] Hyprland layoutmsg crash — bad_variant_access (upstream) :bug:hyprland: -CLOSED: [2026-07-21 Tue] -Dropped 2026-07-21 (Craig's call) — not tracking the upstream report. The crash evidence (both reports + tmpfs log excerpts) and the voice-passed issue draft stay preserved in [[file:working/hyprland-layoutmsg-crash/][working/hyprland-layoutmsg-crash/]] if it recurs and is worth reviving. -Grading: Critical severity (SIGSEGV kills the whole desktop session; every GUI app's unsaved state lost) x rare edge case (twice in ~4.5 months: 2026-03-07 on v0.54.1, 2026-07-20 on v0.55.4) = P2 = [#B]. Upstream Hyprland bug, not this repo's code — the task tracks reporting it and picking up the fix. -A layoutmsg mfact dispatch (layout-resize, mod+H/L) throws std::bad_variant_access inside Layout::CAlgorithm::layoutMsg, uncaught, SIGSEGV. Both crashes fired from the layout-resize mfact path (keycode 104 shrink today, 108 grow in March). Layout at crash was master and the identical mfact had worked seconds earlier; the pre-crash window held monocle<->master toggles, two window closes dropping focus to "[Window nullptr]", and togglefloating x2. Monocle is a registered v0.55 layout (log shows graceful "Unknown monocle layoutmsg" rejects), so the config is not at fault; related edges are guarded ("mfact -> no window") while this path misses its variant guard. Repo has no newer build (0.55.4-1 installed and repo). -Evidence preserved in [[file:working/hyprland-layoutmsg-crash/][working/hyprland-layoutmsg-crash/]] (both crash reports + excerpts from the tmpfs session log, extracted before reboot loses it). -Next: Craig posts the issue himself (2026-07-20 decision) — the voice-passed draft is [[file:working/hyprland-layoutmsg-crash/issue-draft.md][issue-draft.md]], with both crash reports and the log excerpts beside it for attaching. Watch the repo for a fixed release and close on confirmation. The layout-resize script guard was declined (a script can't observe the internal desync). ** TODO [#B] Assess a Hyprland left-drag window gesture :feature:hyprland: :PROPERTIES: :LAST_REVIEWED: 2026-07-21 @@ -884,6 +859,47 @@ Craig's standing checklist of everything that isn't agent-verifiable. Each child Priority and type tag added by that audit: the task carried neither, which kept the project's largest live container out of the agenda entirely. +*** Settings panel: brightness drum drags +What we're verifying: the paper drums' drag gesture (a Cairo hit-test the e2e suite can't drive) maps drag distance to backing percent with the floor rules. On ratio (no backlight) the drums render dimmed and refuse the drag — that's expected, so the drag half of this test needs velox. +- Open the settings panel (Super+Shift+G). +- Drag the SCREEN drum downward well past the bottom. +- Drag the KBD drum the same way. +#+begin_src sh :results output +brightnessctl -m info; brightnessctl -m -c kbd_backlight info +#+end_src +Expected: the screen backing floors at 5% (drum never shows 0); the kbd backing reaches 0. On ratio both drums are dimmed and undraggable instead. + +*** Settings panel: tripper dial tab drags +What we're verifying: the dial's drag gestures — clamping between enabled neighbors, the exact-minutes counter during a drag, the OFF-notch park, and unparking (the e2e suite covers this commit path only at the backing layer). +- Open the settings panel. +- Drag the LOCK tab counterclockwise toward 0; watch the minutes counter during the drag. +- Drag the SUSPEND tab out of the OFF notch onto the scale. +- Drag SUSPEND back down into the bottom OFF notch. +#+begin_src sh :results output +cat ~/.config/hypr/hypridle.conf +#+end_src +Expected: LOCK refuses to land below DIM's minutes (clamps, doesn't cross); the counter shows exact minutes while dragging; SUSPEND leaves/rejoins the conf as it unparks/parks. Finish by restoring the rail to DIM 5 / LOCK 7 / WATCH 8 / SCREEN OFF 10 / SUSPEND parked. + +*** Settings panel: matrix pin clicks and letter wheels +What we're verifying: the program matrix's pin and wheel hit-tests (Cairo; the e2e suite drives only the backing calls) — seat/unseat pins, cycle a CPU POWER letter, and the active-is-live rule. +- Open the settings panel. +- Activate FOCUS (its head key). +- Click FOCUS's NIGHT LIGHT pin to seat it. +- Click the pin again to unseat it. +- Click FOCUS's CPU POWER letter wheel a few times. +- Move a control that belongs to no program (e.g. flip TOUCHPAD). +Expected: seating the pin starts the night light immediately (screen warms) and FOCUS stays active; unseating stops it; each wheel click steps P→B→S and applies live; the manual TOUCHPAD change deactivates the scene (no head stays lit). + +*** Settings panel: locked-path night-watch swap +What we're verifying: the WATCH stage under a locked session — the kiosk face reveals only after its window maps (no desktop flash), and first input restores hyprlock. The e2e/live checks so far only exercised the unlocked lifecycle. Note: caffeine was found engaged on 2026-07-22 (hypridle deliberately left stopped); release caffeine first or this never fires. +- Release caffeine so hypridle runs with the five-stage conf. +- In the panel, temporarily drag the rail tight: DIM 1 / LOCK 2 / WATCH 3. +- Lock the session (Super+Shift+Q → lock, or wait for the LOCK stage). +- Leave the machine untouched past the WATCH minute mark. +- Watch the transition carefully for any flash of the desktop between hyprlock and the night-watch face. +- Press a key or move the mouse. +Expected: the night-watch board replaces the lock face with no desktop flash between them; first input drops the face and hyprlock is back (password prompt, not the desktop). If the face fails to start, the plain hyprlock stays — never a bare desktop. Restore the rail to DIM 5 / LOCK 7 / WATCH 8 afterward. + *** Net panel: sticky error toast dismisses on the next click What we're verifying: the stuck enterprise-error banner (dotfiles a157bed) now clears when you click anywhere else in the panel — the fix is a pointer-level gesture that AT-SPI can't drive. - Open the net panel from the bar. @@ -1521,10 +1537,6 @@ Specced 2026-07-10 after discussion with Craig, and the design grew past the ori Parent spec: [[file:docs/specs/2026-07-09-audio-doctor-spec.org][docs/specs/2026-07-09-audio-doctor-spec.org]] (IMPLEMENTED). This is a v1 gap found after the fact, not a phase of it. -** DONE [#C] WireGuard import is now config-less — decide feature fate :feature:network: -CLOSED: [2026-07-21 Tue] -Decided 2026-07-21 (Craig): KEEP the import feature. The out-of-band flow is already in place — =assets/wireguard-config/= carries a README documenting "drop plaintext =*.conf= locally at install time (gitignored); ship encrypted =*.conf.gpg= to track", and its =.gitignore= enforces it (=*.conf= blocked, =!*.conf.gpg= allowed). The script also already no-ops gracefully on an empty dir (=shopt -s nullglob= + a =found= flag), so nothing ships and nothing errors when no configs are present. Nothing to build; the fate decision was the whole task. -scripts/import-wireguard-configs.sh reads assets/wireguard-config/*.conf, but no configs ship in the repo anymore (removed as a public-leak fix; .gitignore blocks plaintext). ** TODO [#C] Waybar modules run together — need subtle separators :bug:dotfiles:waybar: Craig misreads where one module ends and the next begins — the wind (weather) value runs straight into the date with no visual stop, so he reads the wind figure as the start of the date. Add a light, subtle separator or spacing between adjacent Waybar modules. Grading: Minor severity (legibility, nothing broken) x frequent (every glance at the bar) = P3 = [#C]. @@ -1539,12 +1551,6 @@ From the roam inbox (2026-07-20): the shipped Waybar weather chip's comfort colo - Bad conditions — red number: temp over 90 → the temp number is red; wind over a comfort level → the wind glyph displays and its number is red. Open design question (Craig): which other conditions/combinations to signal, and how a forecasted severe event (e.g. an upcoming hurricane) should display. Grading: Minor severity (legibility on a shipped chip, nothing broken) × frequent (every glance at the bar) = P3 = [#C]. Mostly buildable from the rules above; the severe-event display needs Craig's call. Waybar is archsetup-owned per the dotfiles standing rule. -** DONE [#C] Dupre theme waybar.css drifted from live style.css :bug:dotfiles:waybar: -CLOSED: [2026-07-21 Tue] -Fixed in dotfiles 3e4e7ff (2026-07-20, "fix(theme): sync dupre waybar.css with the live weather rules") — dupre/waybar.css is byte-identical to live again, restoring the =#custom-weather= selectors/hover/gold divider, so =tests/theme-css= is green. -Grading: Minor severity (cosmetic, reverts only on a theme switch) × rare edge case (dupre is already the active theme) = P4 = [#D] on user impact, bumped to [#C] because the dotfiles =make test= stays RED until synced, poisoning the green baseline for every future commit. -The weather-kit work added =#custom-weather= selectors to =hyprland/.config/waybar/style.css= but never mirrored them into =hyprland/.config/themes/dupre/waybar.css=. =tests/theme-css= asserts the two files are identical (set-theme copies the theme file over the live one), so switching to dupre would silently revert the weather chip styling. Fix: sync the theme file to live. Pre-existing; found 2026-07-19 during an unrelated commit's green-baseline run. - ** TODO [#C] Add a time selector to the timer panel :feature:timer: Offer a period-appropriate selector for timer duration, likely drawing on the tape-counter idiom, while preserving the existing direct-entry path. @@ -2008,3 +2014,38 @@ archsetup:3054 rewrites the whole GRUB_CMDLINE_LINUX_DEFAULT line with a fixed s CLOSED: [2026-07-21 Tue] Shipped in dotfiles 8bc79ba per Craig's calls (one global button, rendered text): COPY on the doctor row serializes every category band via the same card_spec the GUI renders, through panelkit clipboard. TDD tests/maint/test_status_copy.py, full dotfiles make test green, inbox note sent. Live check pending: open the maint panel, press COPY, paste. Craig's roam capture 2026-07-20, routed via .emacs.d sentry inbox-zero as archsetup-owned UI work. Dotfiles maint panel work; archsetup drives it end-to-end per the standing rule. +** DONE [#B] Build: desktop-settings panel :feature:hyprland:dotfiles: +CLOSED: [2026-07-22 Wed] +:PROPERTIES: +:SPEC_ID: d6bb1e73-ec90-4327-85ee-bfa762da5bce +:END: +The GTK build of the desktop-settings panel per the spec (docs/specs/2026-07-02-desktop-settings-panel-spec.org, DOING; normative reference: prototype 37). Work happens in dotfiles settings/ — archsetup drives the lifecycle. Two non-blocking build-time picks live in the spec's Review findings (wallpaper setter tool; store location/format) — decide in phase 1 and record there. +*** 2026-07-22 Wed @ 13:14:01 -0500 Built the backings engine (phase 1) — dotfiles 7a15237 +Landed as dotfiles settings/src/settings (10 modules) + tests/settings (118 tests against fake binaries, auto-discovered by make test — 81 suites green). Covers brightness/kbd (5% floor, x10 drum), toggles (dim, pointer cycle via toggle-touchpad, caffeine), DND class-split (dunst pause level 60, close-all before unpause, alarms punch through live), powerprofilesctl, nightlight (resident gammastep), hypridle.conf renderer + symlink-safe write + caffeine-respecting reload + hyprlock grace, suntimes (pure NOAA math), and the wallpaper engine (awww/mpvpaper/projector adapters, galleries, random draw, atomic JSON store). All three build-time picks recorded as DONE findings in the spec (setter=awww, store=state.json, nightlight=gammastep). Handoff note in ~/.dotfiles/inbox/. +*** 2026-07-22 Wed @ 15:26:44 -0500 Built the presenters (phase 2) — dotfiles 5172289 +Three GTK-free models per prototype 37, all at 100% line coverage (tests/settings/test_presenters.py, 100 tests; full repo suite green before and after). programs.py: the matrix — eight complete programs (Craig's four factory scenes drafted here per the pre-flight pick, slots 1-4 first-class), pin rows + power radio row, activate returns the full sets, member writes return apply/updated with active-is-live surviving. bench.py: drum mapping (screen never reads 0, floor 5%; kbd floors at 0), idle rail order clamping between enabled neighbors, park/unpark with re-clamp, caffeine bypass, view-state builder tolerant of no-backlight None. channels.py: the eight-channel bank, per-mode sources visibility, alpha/recency sort (unlabeled last), the shared mint/edit/delete grammar for pairs/sets/colors (press arm-cycle, two-picture set minimum, dup rejection, selection clamping), sources guardrails, interval wheel, previews. Handoff note in ~/.dotfiles/inbox/. +*** 2026-07-22 Wed @ 16:03:52 -0500 Ported prototype 37's instruments to GTK (phase 3) — dotfiles 33d82eb +The panel renders P37 end to end. New instruments.py carries the three Cairo instruments as clock-free humble objects: ProgramMatrix (glyph/numbered heads over jewel pins + CPU POWER paper letter wheels), DrumRoller (paper drums, drag-to-set, dimmed n/a on no-backlight machines), TripDial (sqrt 300° scale, colored stage tabs, OFF-notch parking, exact-minutes drag counter, BYPASSED · CAFFEINE stamp, bottom legend). gui.py rebuilt to P37's layout with the wallpaper sub-view: channel bank with drawn faces, minted pair/color/set trays (alpha/time sort, edit/delete chip feet), the three presses (pair arm-cycle, color picker, set press + interval wheel), sources with a folder picker. New GTK-free glue all unit-tested (test_panel_glue.py, 33 tests): dial geometry in bench, matrix/idle/wallpaper wiring in panel, presenter-vocabulary channels (pair/solid/random-from-set) in wallpaper.apply. AT-SPI smoke (make test-panel-settings) drives the real wiring against faked backings + a sandboxed store, pinned to its own child pid so it can never fire a live panel's backings. Visually verified on a headless output against P37 captures (main + pair/single/solid/random). Adaptations recorded in the handoff: five-stage dial (WATCH gets its own green — the engine runs watch separately, P37 merged the label), DESKTOP_SETTINGS_START_VIEW test seam. Full suite 84 suites green; window rule widened for the 540px panel. Handoff note in ~/.dotfiles/inbox/. +*** 2026-07-22 Wed @ 16:47:54 -0500 Integrated phase 4 — dotfiles 680b50d +Bar consolidation had landed early (74f723e); this pass shipped the rest. settings-project hosts the watch/clock/world channels as HTML faces (settings/faces/) on a gtk-layer-shell background window over WebKit2 — all three visually verified on a headless output, world reading the waybar worldclock roster via query param. settings-watch is the hypridle watch-stage host: throwaway-profile chrome kiosk that reveals only after its window maps behind the lock and relocks before teardown — a failed face degrades to the plain lock, never a bare desktop (unlocked lifecycle verified live; the locked swap goes to the manual checklist). Sun-pair location reads whereami live per transition with last-good cache in state.json (verified live: 9.5s first beat, New Orleans coords, Gogh day side applied); desktop-settings-tick.timer (2 min, enabled on ratio, added to the installer) drives flips and random draws — 23ms no-op beats. dunstrc history_length 100 protects held alarms (full DND cycle verified against live dunst; wtimer alarms already CRITICAL via the notify wrapper, no promotion rule needed). Live hypridle rewrite verified — five-stage regime rendered through the stow symlink, caffeine respected (found engaged, daemon correctly left stopped). Refresh signals needed no rewiring (touchpad signals itself via toggle-touchpad). 45 new tests; suite 84 suites green; smoke 13/13. Handoff note in ~/.dotfiles/inbox/. +Velox one-time steps (sync doesn't carry): mpvpaper (AUR), optionally power-profiles-daemon (service off), and systemctl --user enable --now desktop-settings-tick.timer. +*** 2026-07-22 Wed @ 17:05:58 -0500 Landed the 17-point end-to-end pass — dotfiles 9038eee +Prototype 37's 17-point suite re-derived against the real panel (the original Playwright script wasn't preserved; the functional surface in the spec's Final prototype section is the source). tests/settings/panel_e2e.py + run-panel-e2e.sh + =make test-panel-e2e=: points 1-14 drive the running panel over AT-SPI (program recall with per-backing verification across FOCUS/BATTERY/slot1, pointer console keys, all eight wallpaper channels including projected watch/world stop/start ordering, close); points 15-17 cover the Cairo instruments (drums, tripper dial clamp/park/render/reload, matrix pins + letter wheels with active-is-live) at the backing layer, since AT-SPI can't reach a DrawingArea's hit-tests. Same safety posture as the smoke: sandboxed store, faked backings, pid-pinned a11y node. 17/17 green on ratio's live compositor; full suite 85 green; smoke 13/13; ruff clean. The drag gestures go to the manual checklist below. Handoff note in ~/.dotfiles/inbox/. +*** 2026-07-22 Wed @ 17:05:58 -0500 Flipped the spec to IMPLEMENTED +docs/specs/2026-07-02-desktop-settings-panel-spec.org DOING → IMPLEMENTED with a dated history line naming the shipping commits (dotfiles 7a15237 / 74f723e / 5172289 / 33d82eb / 680b50d / 9038eee) and the verification evidence (85 suites, smoke 13/13, e2e 17/17). The four panel drag-gesture checks and the locked-path night-watch swap live under "Manual testing and validation" — human-eye checks, not implementation blockers. +** CANCELLED [#B] Hyprland layoutmsg crash — bad_variant_access (upstream) :bug:hyprland: +CLOSED: [2026-07-21 Tue] +Dropped 2026-07-21 (Craig's call) — not tracking the upstream report. The crash evidence (both reports + tmpfs log excerpts) and the voice-passed issue draft stay preserved in [[file:working/hyprland-layoutmsg-crash/][working/hyprland-layoutmsg-crash/]] if it recurs and is worth reviving. +Grading: Critical severity (SIGSEGV kills the whole desktop session; every GUI app's unsaved state lost) x rare edge case (twice in ~4.5 months: 2026-03-07 on v0.54.1, 2026-07-20 on v0.55.4) = P2 = [#B]. Upstream Hyprland bug, not this repo's code — the task tracks reporting it and picking up the fix. +A layoutmsg mfact dispatch (layout-resize, mod+H/L) throws std::bad_variant_access inside Layout::CAlgorithm::layoutMsg, uncaught, SIGSEGV. Both crashes fired from the layout-resize mfact path (keycode 104 shrink today, 108 grow in March). Layout at crash was master and the identical mfact had worked seconds earlier; the pre-crash window held monocle<->master toggles, two window closes dropping focus to "[Window nullptr]", and togglefloating x2. Monocle is a registered v0.55 layout (log shows graceful "Unknown monocle layoutmsg" rejects), so the config is not at fault; related edges are guarded ("mfact -> no window") while this path misses its variant guard. Repo has no newer build (0.55.4-1 installed and repo). +Evidence preserved in [[file:working/hyprland-layoutmsg-crash/][working/hyprland-layoutmsg-crash/]] (both crash reports + excerpts from the tmpfs session log, extracted before reboot loses it). +Next: Craig posts the issue himself (2026-07-20 decision) — the voice-passed draft is [[file:working/hyprland-layoutmsg-crash/issue-draft.md][issue-draft.md]], with both crash reports and the log excerpts beside it for attaching. Watch the repo for a fixed release and close on confirmation. The layout-resize script guard was declined (a script can't observe the internal desync). +** DONE [#C] WireGuard import is now config-less — decide feature fate :feature:network: +CLOSED: [2026-07-21 Tue] +Decided 2026-07-21 (Craig): KEEP the import feature. The out-of-band flow is already in place — =assets/wireguard-config/= carries a README documenting "drop plaintext =*.conf= locally at install time (gitignored); ship encrypted =*.conf.gpg= to track", and its =.gitignore= enforces it (=*.conf= blocked, =!*.conf.gpg= allowed). The script also already no-ops gracefully on an empty dir (=shopt -s nullglob= + a =found= flag), so nothing ships and nothing errors when no configs are present. Nothing to build; the fate decision was the whole task. +scripts/import-wireguard-configs.sh reads assets/wireguard-config/*.conf, but no configs ship in the repo anymore (removed as a public-leak fix; .gitignore blocks plaintext). +** DONE [#C] Dupre theme waybar.css drifted from live style.css :bug:dotfiles:waybar: +CLOSED: [2026-07-21 Tue] +Fixed in dotfiles 3e4e7ff (2026-07-20, "fix(theme): sync dupre waybar.css with the live weather rules") — dupre/waybar.css is byte-identical to live again, restoring the =#custom-weather= selectors/hover/gold divider, so =tests/theme-css= is green. +Grading: Minor severity (cosmetic, reverts only on a theme switch) × rare edge case (dupre is already the active theme) = P4 = [#D] on user impact, bumped to [#C] because the dotfiles =make test= stays RED until synced, poisoning the green baseline for every future commit. +The weather-kit work added =#custom-weather= selectors to =hyprland/.config/waybar/style.css= but never mirrored them into =hyprland/.config/themes/dupre/waybar.css=. =tests/theme-css= asserts the two files are identical (set-theme copies the theme file over the live one), so switching to dupre would silently revert the weather chip styling. Fix: sync the theme file to live. Pre-existing; found 2026-07-19 during an unrelated commit's green-baseline run. -- cgit v1.2.3