fix(waybar): #51 doctor glyph renders + #52 V2 bake asserts
All checks were successful
Check / eval (push) Successful in 3m6s
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:
@@ -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
|
the real `class`, then append rules. Also revisit whether blueman/s-c-p
|
||||||
actually float once seen (regex tolerance for the `.…-wrapped` form).
|
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
|
### 54. Installer safety + polish — V2 scenarios pending
|
||||||
Four guards shipped 2026-07-09 (V0/V1: bash -n, flake check, nomarchy-install
|
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
|
builds): offline `compose-lock` failure now fail-closes instead of a network
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ the failure as a NOW bug in BACKLOG.md. Machines: the **AMD dev box**
|
|||||||
QA machine), the **T14s** (webcam case).
|
QA machine), the **T14s** (webcam case).
|
||||||
|
|
||||||
## Any machine (dev box is fine)
|
## 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
|
- [ ] **Battery charge limit re-apply on unplug** — `sudo nixos-rebuild
|
||||||
switch` with `power.batteryChargeLimit = 80`, physically unplug/replug
|
switch` with `power.batteryChargeLimit = 80`, physically unplug/replug
|
||||||
AC, confirm `charge_control_end_threshold` re-reads 80. (udev trigger
|
AC, confirm `charge_control_end_threshold` re-reads 80. (udev trigger
|
||||||
|
|||||||
@@ -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
|
## 2026-07-09 — #43 V2: System ▸ Firmware menu render
|
||||||
- **Task:** V2 the shipped Firmware menu (#43). theme-shot render of
|
- **Task:** V2 the shipped Firmware menu (#43). theme-shot render of
|
||||||
`nomarchy-menu system`.
|
`nomarchy-menu system`.
|
||||||
|
|||||||
@@ -7,6 +7,16 @@ here the moment a debugging session teaches you something a future
|
|||||||
iteration would otherwise rediscover.
|
iteration would otherwise rediscover.
|
||||||
|
|
||||||
## Testing & VM recipes
|
## 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
|
- **tuigreet dies silently under runNixOSTest** (even bare, no theme
|
||||||
flag: greetd sits as "(greetd)" with no child, nothing in the
|
flag: greetd sits as "(greetd)" with no child, nothing in the
|
||||||
journal — its stderr goes to the VT) — nixpkgs' own greetd test uses
|
journal — its stderr goes to the VT) — nixpkgs' own greetd test uses
|
||||||
|
|||||||
@@ -115,12 +115,19 @@ let
|
|||||||
# exits 0, so the module only appears when the sheet has a ✖ (the
|
# exits 0, so the module only appears when the sheet has a ✖ (the
|
||||||
# same self-hide discipline as vpn/nightlight/updates). The tooltip
|
# same self-hide discipline as vpn/nightlight/updates). The tooltip
|
||||||
# carries the first failing lines; click opens the full sheet.
|
# 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" ''
|
doctorStatus = pkgs.writeShellScriptBin "nomarchy-doctor-status" ''
|
||||||
command -v nomarchy-doctor >/dev/null 2>&1 || exit 0
|
out=$(${pkgs.nomarchy-doctor}/bin/nomarchy-doctor 2>/dev/null) && exit 0
|
||||||
out=$(nomarchy-doctor 2>/dev/null) && exit 0
|
# Strip ANSI so the tooltip is plain text (and waybar never chokes on
|
||||||
tip=$(printf '%s\n' "$out" | grep '✖' | head -5 \
|
# 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)"')
|
| ${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.
|
# Per-theme override probe.
|
||||||
@@ -247,7 +254,11 @@ let
|
|||||||
"custom/doctor" = {
|
"custom/doctor" = {
|
||||||
exec = "nomarchy-doctor-status";
|
exec = "nomarchy-doctor-status";
|
||||||
return-type = "json";
|
return-type = "json";
|
||||||
|
format = "{}";
|
||||||
interval = 300;
|
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";
|
on-click = "nomarchy-menu doctor";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,9 @@
|
|||||||
},
|
},
|
||||||
"custom/doctor": {
|
"custom/doctor": {
|
||||||
"return-type": "json",
|
"return-type": "json",
|
||||||
|
"format": "{}",
|
||||||
"interval": 300,
|
"interval": 300,
|
||||||
|
"signal": 10,
|
||||||
"exec": "nomarchy-doctor-status",
|
"exec": "nomarchy-doctor-status",
|
||||||
"on-click": "nomarchy-menu doctor"
|
"on-click": "nomarchy-menu doctor"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -141,7 +141,9 @@
|
|||||||
},
|
},
|
||||||
"custom/doctor": {
|
"custom/doctor": {
|
||||||
"return-type": "json",
|
"return-type": "json",
|
||||||
|
"format": "{}",
|
||||||
"interval": 300,
|
"interval": 300,
|
||||||
|
"signal": 10,
|
||||||
"exec": "nomarchy-doctor-status",
|
"exec": "nomarchy-doctor-status",
|
||||||
"on-click": "nomarchy-menu doctor"
|
"on-click": "nomarchy-menu doctor"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -99,7 +99,9 @@
|
|||||||
|
|
||||||
"custom/doctor": {
|
"custom/doctor": {
|
||||||
"return-type": "json",
|
"return-type": "json",
|
||||||
|
"format": "{}",
|
||||||
"interval": 300,
|
"interval": 300,
|
||||||
|
"signal": 10,
|
||||||
"exec": "nomarchy-doctor-status",
|
"exec": "nomarchy-doctor-status",
|
||||||
"on-click": "nomarchy-menu doctor"
|
"on-click": "nomarchy-menu doctor"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -98,7 +98,9 @@
|
|||||||
|
|
||||||
"custom/doctor": {
|
"custom/doctor": {
|
||||||
"return-type": "json",
|
"return-type": "json",
|
||||||
|
"format": "{}",
|
||||||
"interval": 300,
|
"interval": 300,
|
||||||
|
"signal": 10,
|
||||||
"exec": "nomarchy-doctor-status",
|
"exec": "nomarchy-doctor-status",
|
||||||
"on-click": "nomarchy-menu doctor"
|
"on-click": "nomarchy-menu doctor"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
# Themed-desktop capture harness (item 28 slice c) — boots the full
|
# Themed-desktop capture harness (item 28 slice c) — boots the full
|
||||||
# desktop headlessly (software-GL Hyprland) at 1920x1080 and QMP-dumps
|
# 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
|
# Maintainer tool, NOT a checks.* gate (a full-desktop VM is far too
|
||||||
# heavy for CI). Impure: THEME env picks the theme slug.
|
# 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
|
# 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
|
# The session exec-once paints the wallpaper (softGL first paint at
|
||||||
# 1920x1080 is slow) — give it a generous settle.
|
# 1920x1080 is slow) — give it a generous settle.
|
||||||
machine.sleep(30)
|
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
|
# 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
|
# middle of the desktop shot (that frame doubles as the theme-picker
|
||||||
# preview.png source).
|
# preview.png source).
|
||||||
@@ -76,5 +91,15 @@ pkgs.testers.runNixOSTest {
|
|||||||
machine.execute(hy + " exec nomarchy-menu' >/dev/null 2>&1")
|
machine.execute(hy + " exec nomarchy-menu' >/dev/null 2>&1")
|
||||||
machine.sleep(8)
|
machine.sleep(8)
|
||||||
machine.screenshot("menu")
|
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")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user