fix(waybar): #51 doctor glyph renders + #52 V2 bake asserts
All checks were successful
Check / eval (push) Successful in 3m6s

Doctor tripwire was self-hiding under waybar (PATH miss / weak glyph).
Call nomarchy-doctor by store path, strip ANSI tooltips, use 󰀨 + format
+ signal 10 (generated and whole-swap). theme-shot asserts class:bad,
guest btop.theme, and pokes RTMIN+10 before desktop shots.

V2: theme-shot green for rose-pine, summer-night, catppuccin, everforest,
vantablack; bar crops show the red alert-circle. btop TUI visual is
softGL-blocked (Ghostty) → HARDWARE-QUEUE. Closes #51 and #52.
This commit is contained in:
Bernardo Magri
2026-07-09 20:56:51 +01:00
parent d8a796b6ee
commit be4efd38ea
10 changed files with 85 additions and 23 deletions

View File

@@ -94,24 +94,6 @@ Next slice: on hardware, run `hyprctl clients` while each is open, read
the real `class`, then append rules. Also revisit whether blueman/s-c-p
actually float once seen (regex tolerance for the `.…-wrapped` form).
### 51. Waybar/menu behaviour bugs — V2 render pending
Fixes shipped V1 (2026-07-09): doctor indicator emits `󰒡` + `class:bad`
when unhealthy (was empty text → self-hidden); CC appearance toggles print
"(requires rebuild)"; summer-day scroll `e±1``r±1`. **Remaining V2:** a
theme-shot render with an induced doctor failure to see the glyph (fold into
#44's `checks.doctor` extension); CC message + scroll are behavioural (V1
+ self-evident).
### 52. Theme fidelity bugs — btop V2 render pending
Six per-theme defects fixed 2026-07-09 (rose-pine btop→Dawn; everforest +
summer-night btop `inactive_fg`; vantablack role inversion; osaka-jade
text/subtext + warn; catppuccin-latte mantle/accentAlt/ANSI; catppuccin
Mocha btop). JSON fixes **V0-verified** (`check-theme-contrast` 24×7 all
pass — accentAlt retuned to Latte mauve `#8839ef`, not the audit's pink
`#ea76cb` which fails the 3.0 floor). **Remaining V2:** a theme-shot render
of the btop-changed themes (rose-pine, everforest, summer-night, vantablack,
catppuccin) — btop.theme isn't contrast-checked.
### 54. Installer safety + polish — V2 scenarios pending
Four guards shipped 2026-07-09 (V0/V1: bash -n, flake check, nomarchy-install
builds): offline `compose-lock` failure now fail-closes instead of a network

View File

@@ -8,6 +8,14 @@ the failure as a NOW bug in BACKLOG.md. Machines: the **AMD dev box**
QA machine), the **T14s** (webcam case).
## Any machine (dev box is fine)
- [ ] **btop theme fidelity (#52 residual)** — softGL theme-shot cannot
open Ghostty, so the hand `btop.theme` assets were only guest-file
asserted (main_bg / inactive_fg keys) + desktop/bar rendered for
rose-pine, everforest, summer-night, vantablack, catppuccin. On a
real session: `nomarchy-theme-sync apply <slug>` then `btop` and
confirm backgrounds/text match the theme (esp. rose-pine Dawn light
bg `#faf4ed`, vantablack near-black `#0d0d0d`, catppuccin Mocha
`#1E1E2E`). One pass cycling those five is enough.
- [ ] **Battery charge limit re-apply on unplug** — `sudo nixos-rebuild
switch` with `power.batteryChargeLimit = 80`, physically unplug/replug
AC, confirm `charge_control_end_threshold` re-reads 80. (udev trigger

View File

@@ -17,6 +17,24 @@ Template:
---
## 2026-07-09 — #51+#52 V2 batch: doctor glyph + btop bake
- **Task:** NEXT #51 (doctor Waybar glyph) + #52 (btop fidelity render).
- **Did:** theme-shot harness now asserts `nomarchy-doctor-status`
(`class:bad` + glyph), guest `btop/themes/nomarchy.theme`, pokes
waybar RTMIN+10, best-effort Ghostty+btop shot. Fixed the doctor
tripwire so it actually *shows*: absolute path to `nomarchy-doctor`
(PATH self-hide), ANSI-stripped tooltip, `󰀨` glyph, `format = "{}"`,
signal 10 on generated + whole-swap bars.
- **Verified:** **V2**`THEME=<slug> nix build --impure -f tools/theme-shot.nix`
green for rose-pine, summer-night, catppuccin, everforest, vantablack;
viewed bar crops: red alert-circle before the bell on generated
(rose-pine) and whole-swap (summer-night). Scripted btop.theme key
checks (Dawn/inactive_fg/Mocha/vantablack) all OK. V0 flake check +
contrast 24×7 pass. Ghostty under softGL never opened → btop TUI
visual queued V3.
- **Pending:** HARDWARE-QUEUE btop TUI spot-check (five slugs).
- **Next suggestion:** #54 installer V2 scenarios, or #33 rofi scrollbar.
## 2026-07-09 — #43 V2: System ▸ Firmware menu render
- **Task:** V2 the shipped Firmware menu (#43). theme-shot render of
`nomarchy-menu system`.

View File

@@ -7,6 +7,16 @@ here the moment a debugging session teaches you something a future
iteration would otherwise rediscover.
## Testing & VM recipes
- **theme-shot softGL cannot start Ghostty** — `btop.png` is best-effort
(usually identical to desktop). Guest asserts on
`~/.config/btop/themes/nomarchy.theme` prove baking; the TUI look is
hardware/GL tier (HARDWARE-QUEUE).
- **Waybar `custom/doctor` tripwire:** status helper must invoke
`nomarchy-doctor` by **absolute store path** (waybar's env can miss
system PATH → `command -v … || exit 0` self-hides forever); empty
`"text"` also self-hides; strip ANSI before packing the tooltip; use
signal 10 + `format = "{}"`. theme-shot asserts class:bad + glyph and
pokes RTMIN+10 before the desktop shot.
- **tuigreet dies silently under runNixOSTest** (even bare, no theme
flag: greetd sits as "(greetd)" with no child, nothing in the
journal — its stderr goes to the VT) — nixpkgs' own greetd test uses

View File

@@ -115,12 +115,19 @@ let
# exits 0, so the module only appears when the sheet has a ✖ (the
# same self-hide discipline as vpn/nightlight/updates). The tooltip
# carries the first failing lines; click opens the full sheet.
# Absolute path to the doctor binary: waybar's custom-module env can
# miss system PATH, and `command -v … || exit 0` then self-hides forever.
doctorStatus = pkgs.writeShellScriptBin "nomarchy-doctor-status" ''
command -v nomarchy-doctor >/dev/null 2>&1 || exit 0
out=$(nomarchy-doctor 2>/dev/null) && exit 0
tip=$(printf '%s\n' "$out" | grep '' | head -5 \
out=$(${pkgs.nomarchy-doctor}/bin/nomarchy-doctor 2>/dev/null) && exit 0
# Strip ANSI so the tooltip is plain text (and waybar never chokes on
# control chars); keep only the lines.
tip=$(printf '%s\n' "$out" \
| ${pkgs.gnused}/bin/sed 's/\x1b\[[0-9;]*m//g' \
| grep '' | head -5 \
| ${pkgs.jq}/bin/jq -Rs 'rtrimstr("\n") + "\n(click for the full sheet)"')
printf '{"text":"󰒡","tooltip":%s,"class":"bad"}\n' "$tip"
# 󰀨 (md-alert-circle): alert shape that survives incomplete Nerd Font
# cuts better than 󰒡; class:bad still paints it @bad.
printf '{"text":"󰀨","tooltip":%s,"class":"bad"}\n' "$tip"
'';
# Per-theme override probe.
@@ -247,7 +254,11 @@ let
"custom/doctor" = {
exec = "nomarchy-doctor-status";
return-type = "json";
format = "{}";
interval = 300;
# signal 10: poke after a fix (or from theme-shot) so the tripwire
# doesn't wait a full interval after a first-poll miss.
signal = 10;
on-click = "nomarchy-menu doctor";
};

View File

@@ -70,7 +70,9 @@
},
"custom/doctor": {
"return-type": "json",
"format": "{}",
"interval": 300,
"signal": 10,
"exec": "nomarchy-doctor-status",
"on-click": "nomarchy-menu doctor"
},

View File

@@ -141,7 +141,9 @@
},
"custom/doctor": {
"return-type": "json",
"format": "{}",
"interval": 300,
"signal": 10,
"exec": "nomarchy-doctor-status",
"on-click": "nomarchy-menu doctor"
},

View File

@@ -99,7 +99,9 @@
"custom/doctor": {
"return-type": "json",
"format": "{}",
"interval": 300,
"signal": 10,
"exec": "nomarchy-doctor-status",
"on-click": "nomarchy-menu doctor"
},

View File

@@ -98,7 +98,9 @@
"custom/doctor": {
"return-type": "json",
"format": "{}",
"interval": 300,
"signal": 10,
"exec": "nomarchy-doctor-status",
"on-click": "nomarchy-menu doctor"
},

View File

@@ -1,6 +1,9 @@
# Themed-desktop capture harness (item 28 slice c) — boots the full
# desktop headlessly (software-GL Hyprland) at 1920x1080 and QMP-dumps
# two screenshots into $out: desktop.png and menu.png (rofi root open).
# screenshots into $out: desktop.png, menu.png (rofi root open), and
# btop.png (Ghostty running btop, when the terminal starts under softGL).
# Also asserts nomarchy-doctor-status JSON (class:bad) — the harness
# seeds an untracked theme-state.json, so doctor always reports ✖.
# Maintainer tool, NOT a checks.* gate (a full-desktop VM is far too
# heavy for CI). Impure: THEME env picks the theme slug.
# THEME=<slug> nix build --impure -f tools/theme-shot.nix --no-link --print-out-paths
@@ -66,6 +69,18 @@ pkgs.testers.runNixOSTest {
# The session exec-once paints the wallpaper (softGL first paint at
# 1920x1080 is slow) give it a generous settle.
machine.sleep(30)
# Doctor indicator contract: untracked theme-state status JSON
# with class:bad and the 󰒡 glyph (Waybar self-shows the module).
status = machine.succeed("su - nomarchy -c 'nomarchy-doctor-status'")
assert '"class":"bad"' in status, f"doctor-status not bad: {status!r}"
assert ("󰀨" in status or "󰒡" in status), f"doctor glyph missing: {status!r}"
# Baked btop theme must be present (asset or generated) for the slug.
machine.succeed("test -f /home/nomarchy/.config/btop/themes/nomarchy.theme")
machine.succeed("grep -q 'theme\\[main_bg\\]' /home/nomarchy/.config/btop/themes/nomarchy.theme")
# Poke custom/doctor (signal 10) so a first-poll miss at session start
# doesn't leave the tripwire blank for the full 300s interval.
machine.execute("su - nomarchy -c 'pkill -RTMIN+10 waybar' >/dev/null 2>&1 || true")
machine.sleep(3)
# Park the cursor in the bottom-right corner so it doesn't sit in the
# middle of the desktop shot (that frame doubles as the theme-picker
# preview.png source).
@@ -76,5 +91,15 @@ pkgs.testers.runNixOSTest {
machine.execute(hy + " exec nomarchy-menu' >/dev/null 2>&1")
machine.sleep(8)
machine.screenshot("menu")
# Close menu, launch btop in Ghostty for the per-theme btop.theme shot.
# softGL may fail to start Ghostty btop.png is best-effort then; the
# file assertions above still prove the theme is baked into the guest.
machine.execute("su - nomarchy -c 'pkill -x rofi' >/dev/null 2>&1 || true")
machine.sleep(1)
machine.execute(
hy + " exec ghostty --gtk-single-instance=false -e btop' >/dev/null 2>&1"
)
machine.sleep(12)
machine.screenshot("btop")
'';
}