From c89cace1491af1bc642888910e5bc659b6640d80 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Thu, 9 Jul 2026 18:43:46 +0100 Subject: [PATCH] =?UTF-8?q?feat(menu):=20System=20=E2=96=B8=20Firmware=20?= =?UTF-8?q?=E2=80=94=20fwupd/LVFS=20update=20surface=20(#43)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a self-gated Firmware row to the System submenu (present whenever fwupdmgr is on PATH, i.e. services.fwupd.enable — default-on), its dispatch, and a `firmware` handler that opens a terminal and runs fwupdmgr refresh → get-updates → y/N confirm → fwupdmgr update. Never auto-flashes: fwupdmgr update confirms each device and prompts for the reboot a capsule needs (pillar 1 — no silent BIOS writes). HARDWARE.md §4 updated to "shipped". Verified V0 (nix flake check --no-build) + V1 (HM generation builds; generated nomarchy-menu passes bash -n; firmware handler emitted correctly). V2 (menu render in a session) queued in #43 and V3 (real LVFS flash) in HARDWARE-QUEUE — the VM was held by the #46 install test. Co-Authored-By: Claude Opus 4.8 --- agent/BACKLOG.md | 23 ++++++++++++++--------- agent/HARDWARE-QUEUE.md | 8 ++++++++ agent/JOURNAL.md | 18 ++++++++++++++++++ docs/HARDWARE.md | 18 +++++++++++------- modules/home/rofi.nix | 30 ++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 16 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index cfc59d7..1391049 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -28,15 +28,20 @@ in [`docs/ROADMAP.md`](../docs/ROADMAP.md); map in ## NEXT -### 43. System › Firmware — fwupd product surface (`VISION § A`) -`services.fwupd.enable` is already default-on and never auto-flashes, -but users only learn about `fwupdmgr` from a README sentence. Add a -self-gated menu entry (System submenu) and/or Control Center row that: -refreshes metadata, lists updatable devices, confirms, runs -`fwupdmgr update`, then prints a reboot note when needed. Never -silent-flash (pillar 1). Optional: first-boot / MOTD one-liner when -the daemon is active. Spec: docs/HARDWARE.md §4. Cost: menu script + -optional MOTD; V2 menu, V3 on real LVFS hardware. +### 43. System › Firmware — fwupd menu (V2 render + optional extensions) +Core shipped 2026-07-09: self-gated **System ▸ Firmware** rofi row +(`nomarchy-menu firmware`) — refresh → get-updates → y/N confirm → +`fwupdmgr update` in a terminal; never silent-flash. Verified V0+V1 +(flake check, HM build, generated `bash -n`). **Remaining:** +1. **V2** — render the System submenu in a session (VM/live ISO) and + confirm the Firmware row shows when fwupd is present and the flow + launches. Was blocked on VM contention (a parallel install test held + KVM); do it on the next VM pass. +2. **V3** — real LVFS flash + reboot note on hardware → HARDWARE-QUEUE + (entry added). +3. Optional (own slices): first-boot/MOTD one-liner when fwupd is active; + Waybar/updates-panel integration. (The doctor "updates available" + check is item #44.) Spec: docs/HARDWARE.md §4. ### 44. Doctor hardware section — read-only (`VISION § A`) Extend `nomarchy-doctor` with the same pass/fail + one-fix-command diff --git a/agent/HARDWARE-QUEUE.md b/agent/HARDWARE-QUEUE.md index fb2649c..0d64f37 100644 --- a/agent/HARDWARE-QUEUE.md +++ b/agent/HARDWARE-QUEUE.md @@ -324,6 +324,14 @@ QA machine), the **T14s** (webcam case). active and PPD switching governors; opt-ins: ROCm (`rocminfo`, a GPU PyTorch/Ollama smoke) and the XDNA NPU driver loading. - [ ] **Fingerprint** — `fprintd-enroll` + (opt-in PAM) login/sudo. +- [ ] **System ▸ Firmware menu on real LVFS hardware** (item #43, + `nomarchy-menu firmware`) — on a machine whose firmware/SSD/dock is + on LVFS: open Menu ▸ System ▸ **Firmware**; confirm the terminal runs + `fwupdmgr refresh` → lists real `get-updates` → the y/N confirm gates + correctly → `fwupdmgr update` applies and prints the reboot note when a + capsule needs one. Verify **no** flash happens on "N"/cancel. (VM only + proves the menu row + flow renders; a real capsule write is + hardware-only.) ## Latitude 5410 only - [x] **Waybar theme-switch resilience** (finding #1 re-test, needs main ≥ diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index 337454c..8419910 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,24 @@ Template: --- +## 2026-07-09 — #43 System ▸ Firmware fwupd menu (core shipped, V2 pending) +- **Task:** NEXT #43 — surface fwupd/LVFS updates in the menu (VISION § A). + Done while the VM was busy with #46, so V0/V1 only by design. +- **Did:** Added a self-gated **Firmware** row to the System submenu + (`command -v fwupdmgr`, like Printers) + dispatch + a `firmware)` handler + that opens a terminal and runs `fwupdmgr refresh` → `get-updates` → y/N + confirm → `fwupdmgr update` (never silent-flash; fwupd confirms each + device + prompts reboot). Updated docs/HARDWARE.md §4 to "shipped". +- **Verified:** V0 `nix flake check --no-build` green; V1 HM generation + builds; extracted the generated `nomarchy-menu` and confirmed `bash -n` + clean + the firmware handler emitted correctly (`exec ghostty -e sh -c`, + quoting intact). +- **Pending:** V2 render (System submenu shows the row + flow launches) — + queued in slimmed #43, do on next VM pass (KVM was held by #46). V3 real + LVFS flash → HARDWARE-QUEUE. Optional MOTD/Waybar extensions noted. +- **Next suggestion:** land the #44 doctor-hw agent branch; V2-verify #43+#46 + together once KVM frees. + ## 2026-07-09 — #45 V2 verify Boreal default + capture preview.png (theme-shot) - **Task:** NEXT #45 — close the honesty gap on Boreal-as-default (shipped V0 only at #42) and capture the picker preview. VM-capable environment (KVM). diff --git a/docs/HARDWARE.md b/docs/HARDWARE.md index f7a1404..191a742 100644 --- a/docs/HARDWARE.md +++ b/docs/HARDWARE.md @@ -120,16 +120,20 @@ Disable on VMs/headless: `services.fwupd.enable = false;` in `system.nix`. | Present | Missing | |---------|---------| -| Daemon + package | Menu entry / Control Center | -| README one-liner | First-boot / MOTD hint | -| | Doctor check (“updates available”) | -| | Waybar / updates panel integration | +| Daemon + package | First-boot / MOTD hint | +| README one-liner | Doctor check (“updates available”) | +| **System ▸ Firmware menu** (`nomarchy-menu firmware`) | Waybar / updates panel integration | -**Product direction (queued):** System › Firmware (or a Doctor section) -that runs refresh → list → confirm → `fwupdmgr update`, plus a short -post-install note when `fwupd` is enabled. Never auto-flash; pillar 1 +**System ▸ Firmware** (shipped): a self-gated System-submenu row (present +whenever `fwupdmgr` is on PATH, i.e. `services.fwupd.enable`, default-on) +that opens a terminal and runs `fwupdmgr refresh` → `get-updates` → +confirm → `fwupdmgr update`. It never auto-flashes — `fwupdmgr update` +confirms each device and prompts for the reboot a capsule needs; pillar 1 (rock-stable) forbids silent BIOS writes. +**Still queued:** a post-install / MOTD one-liner when `fwupd` is active, +a Doctor “updates available” check, and Waybar/updates-panel integration. + ### Thunderbolt Firmware for TB devices may appear via LVFS. There is **no** first-class diff --git a/modules/home/rofi.nix b/modules/home/rofi.nix index efc079c..21e75db 100644 --- a/modules/home/rofi.nix +++ b/modules/home/rofi.nix @@ -651,6 +651,32 @@ ${themeRows} exec ${cfg.terminal} -e sh -c "nomarchy-doctor printf '\nEnter to close.'; read -r _" ;; + firmware) + # System ▸ Firmware — fwupd/LVFS update surface (HARDWARE.md §4). + # Never auto-flashes: refresh metadata, list what LVFS offers, then + # hand to `fwupdmgr update`, which confirms each device and prompts + # for the reboot a capsule needs (pillar 1 — no silent BIOS writes). + # Self-gated on fwupdmgr in System; guard here too. + command -v fwupdmgr >/dev/null 2>&1 \ + || { notify-send "Firmware" "fwupd not available (services.fwupd.enable off?)."; exit 0; } + exec ${cfg.terminal} -e sh -c ' + echo "== Refreshing firmware metadata (LVFS) ==" + fwupdmgr refresh || true + echo + echo "== Firmware updates available ==" + if fwupdmgr get-updates; then + echo + printf "Apply these updates? fwupd confirms each device. [y/N] " + read -r ans + case "$ans" in + [yY]*) fwupdmgr update ;; + *) echo "Cancelled — no firmware written." ;; + esac + else + echo "Nothing to apply on this machine." + fi + printf "\nEnter to close."; read -r _' ;; + controlcenter) # Nomarchy TUI Control Center. exec ${cfg.terminal} -e nomarchy-control-center ;; @@ -748,6 +774,9 @@ ${themeRows} command -v nomarchy-snapshots >/dev/null 2>&1 && row "Snapshots" timeshift row "Rollback" edit-undo command -v nomarchy-doctor >/dev/null 2>&1 && row "Doctor" utilities-system-monitor + # Firmware/LVFS updates — self-gated on fwupd (default-on, but off + # on VMs/headless via services.fwupd.enable=false), like Printers. + command -v fwupdmgr >/dev/null 2>&1 && row "Firmware" firmware-manager command -v nomarchy-control-center >/dev/null 2>&1 && row "Control Center" preferences-desktop if [ -e "''${bats[0]}" ] && command -v powerprofilesctl >/dev/null 2>&1; then row "Power profile" preferences-system-power @@ -772,6 +801,7 @@ ${themeRows} *Snapshots*) exec "$0" snapshot ;; *Rollback*) exec "$0" rollback ;; *Doctor*) exec "$0" doctor ;; + *Firmware*) exec "$0" firmware ;; *"Control Center"*) exec "$0" controlcenter ;; *"Power profile"*) exec "$0" power-profile ;; *"Battery limit"*) exec "$0" batterylimit ;;