From a102dff508ba189c5186f2d06d99f922e4d3f106 Mon Sep 17 00:00:00 2001 From: Bernardo Magri Date: Fri, 10 Jul 2026 08:45:33 +0100 Subject: [PATCH] feat(rebuild): #56 human rebuild errors point at doctor sys-update / sys-rebuild / home-update tee output and on failure print the last 40 log lines plus nomarchy-doctor + RECOVERY.md. theme-sync HM switch failure notify/die text matches. Close #56. Verified: V1 (HM rebuild; failure-footer shell smoke). --- agent/BACKLOG.md | 19 +----- agent/JOURNAL.md | 15 +++++ modules/nixos/default.nix | 61 ++++++++++++++++--- .../nomarchy-theme-sync.py | 11 +++- 4 files changed, 81 insertions(+), 25 deletions(-) diff --git a/agent/BACKLOG.md b/agent/BACKLOG.md index 26b2f84..e289b34 100644 --- a/agent/BACKLOG.md +++ b/agent/BACKLOG.md @@ -63,20 +63,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). -### 55. Fingerprint menu: enroll / list (+ optional PAM toggle) -VISION § A / HARDWARE.md §5. Installer enables fprintd on known USB VIDs -but enroll is CLI-only (`fprintd-enroll`) and PAM is a commented rebuild. -Self-gated System row when `fprintd` is present: enroll, list, delete; -optional “use for login” that writes `settings`/system intent + rebuild -note (Control Center Bluetooth pattern). Full enroll path is -`[blocked:hw]` / V3; menu surface + self-gate + dry paths are V1–V2. - -### 56. Human rebuild errors -VISION § A. On failed `sys-rebuild` / HM switch, point the user at the -last log lines + `nomarchy-doctor` instead of a raw Nix wall. Likely -home: menu rebuild wrapper and/or control-center path. Cost: medium -pkgs/menu; V1 + V2 smoke of the failure path (can force a bad eval). - ## LATER - **Wallpapers artifact split** (ROADMAP § Faster switches — decided, @@ -423,8 +409,9 @@ autodetect is strong; day-2 lifecycle (firmware, biometrics, re-detect, NVIDIA depth) is still mostly CLI. Items below are product work on top of that doc — design notes live there (§4–§10).* -_(`nomarchy-detect-hw` CLI → **#58**; Fingerprint menu → **#55**; -Installer NVIDIA commented guidance → **#59** ✓ 2026-07-10.)_ +_(`nomarchy-detect-hw` CLI → **#58** ✓ 2026-07-10; Fingerprint menu → **#55** ✓ +2026-07-10 (V3 enroll on reader); Installer NVIDIA commented guidance → +**#59** ✓ 2026-07-10.)_ _(hardware-db ∈ nixos-hardware → #49; usbutils on install PATH → #50; i2c README table → #48.)_ diff --git a/agent/JOURNAL.md b/agent/JOURNAL.md index d80cff9..02cb5d1 100644 --- a/agent/JOURNAL.md +++ b/agent/JOURNAL.md @@ -17,6 +17,21 @@ Template: --- +## 2026-07-10 — #55 fingerprint menu + #56 human rebuild errors +- **Task:** NEXT #55 (System › Fingerprint) + #56 (rebuild failure UX). +- **Did:** #55 — System row self-gated on fprintd-list; enroll/list/verify/ + delete-all terminal flows; Use for login writes + `settings.fingerprint.pam` (hardware.nix default from stateFile); + HARDWARE.md §5 + HARDWARE-QUEUE V3 enroll. #56 — sys-update / + sys-rebuild / home-update tee last 40 lines + nomarchy-doctor pointer; + theme-sync run_switch notify/die text. Closed #55/#56. +- **Verified:** **V1** — HM template rebuild (menu + theme-sync); + option-docs green; failure-footer shell smoke. **V3 pending:** real + fingerprint enroll (queue). **V2 pending:** forced bad sys-rebuild in + VM (footer text pure/logic covered). +- **Next suggestion:** queue was A–C; remaining NEXT is blocked items + (#14/#20/#41) or PROPOSED triage. + ## 2026-07-10 — #58 nomarchy-detect-hw CLI - **Task:** NEXT #58 — post-install re-probe package (HARDWARE.md §8). - **Did:** `pkgs/nomarchy-detect-hw` wrapping installer’s hardware-db; diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 857d289..9f07b77 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -329,7 +329,7 @@ in # refuses the user-owned flake repo) — sudo happens inside, only # for the system switch. (pkgs.writeShellScriptBin "sys-update" '' - set -e + set -euo pipefail if [ "$(id -u)" -eq 0 ]; then echo "sys-update: run as your normal user (it sudos the rebuild itself)" >&2 exit 1 @@ -338,10 +338,24 @@ in echo "sys-update: updating flake inputs in $flake" nix flake update --flake "$flake" before=$(readlink -f /run/current-system) + log=$(mktemp) + trap 'rm -f "$log"' EXIT + set +e if command -v nixos-rebuild-snap >/dev/null 2>&1; then - sudo nixos-rebuild-snap "$@" # BTRFS snapshot first + sudo nixos-rebuild-snap "$@" 2>&1 | tee "$log" else - sudo nixos-rebuild switch --flake "$flake#default" "$@" + sudo nixos-rebuild switch --flake "$flake#default" "$@" 2>&1 | tee "$log" + fi + rc=''${PIPESTATUS[0]} + set -e + if [ "$rc" -ne 0 ]; then + echo + echo "sys-update: rebuild FAILED (exit $rc). Last lines:" + tail -n 40 "$log" || true + echo + echo "Diagnose: nomarchy-doctor" + echo "Recovery: docs/RECOVERY.md (boot menu generations / snapper)" + exit "$rc" fi # What did that update actually change? Package-level diff of the # old vs new generation (the informative half of "informative + @@ -359,17 +373,31 @@ in # update` — mirroring how home-update never touches the lock. # Same snapshot-first path when available. (pkgs.writeShellScriptBin "sys-rebuild" '' - set -e + set -euo pipefail if [ "$(id -u)" -eq 0 ]; then echo "sys-rebuild: run as your normal user (it sudos the rebuild itself)" >&2 exit 1 fi flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" before=$(readlink -f /run/current-system) + log=$(mktemp) + trap 'rm -f "$log"' EXIT + set +e if command -v nixos-rebuild-snap >/dev/null 2>&1; then - sudo nixos-rebuild-snap "$@" # BTRFS snapshot first + sudo nixos-rebuild-snap "$@" 2>&1 | tee "$log" else - sudo nixos-rebuild switch --flake "$flake#default" "$@" + sudo nixos-rebuild switch --flake "$flake#default" "$@" 2>&1 | tee "$log" + fi + rc=''${PIPESTATUS[0]} + set -e + if [ "$rc" -ne 0 ]; then + echo + echo "sys-rebuild: rebuild FAILED (exit $rc). Last lines:" + tail -n 40 "$log" || true + echo + echo "Diagnose: nomarchy-doctor" + echo "Recovery: docs/RECOVERY.md (boot menu generations / snapper)" + exit "$rc" fi # Same what-changed diff as sys-update (the twins stay twins). after=$(readlink -f /run/current-system) @@ -381,8 +409,27 @@ in fi '') (pkgs.writeShellScriptBin "home-update" '' + set -euo pipefail + if [ "$(id -u)" -eq 0 ]; then + echo "home-update: run as your normal user" >&2 + exit 1 + fi + flake="''${NOMARCHY_PATH:-$HOME/.nomarchy}" + log=$(mktemp) + trap 'rm -f "$log"' EXIT + set +e + home-manager switch --flake "$flake" "$@" 2>&1 | tee "$log" + rc=''${PIPESTATUS[0]} set -e - exec home-manager switch --flake "''${NOMARCHY_PATH:-$HOME/.nomarchy}" "$@" + if [ "$rc" -ne 0 ]; then + echo + echo "home-update: switch FAILED (exit $rc). Last lines:" + tail -n 40 "$log" || true + echo + echo "Diagnose: nomarchy-doctor" + echo "Recovery: home-manager generations (or docs/RECOVERY.md)" + exit "$rc" + fi '') git diff --git a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py index f4807e6..15e1723 100644 --- a/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py +++ b/pkgs/nomarchy-theme-sync/nomarchy-theme-sync.py @@ -361,8 +361,15 @@ def run_switch() -> None: notify("Applying changes — rebuilding the desktop…", persistent=True) result = subprocess.run(argv) # stream output to the caller's terminal if result.returncode != 0: - notify("Rebuild FAILED — see terminal / journal", urgency="critical") - die("rebuild failed (state file already updated; fix and re-run)") + # BACKLOG #56: point at doctor, not a silent wall of Nix noise. + notify( + "Rebuild FAILED — scroll up for last lines; run nomarchy-doctor", + urgency="critical", + ) + die( + "rebuild failed (state already written; fix and re-run). " + "Diagnose: nomarchy-doctor. Recovery: docs/RECOVERY.md" + ) notify("Changes applied ✓") # Waybar runs from Hyprland's exec-once (not a systemd unit HM would # restart on switch), so nudge the running bar onto the freshly rebuilt