Compare commits
2 Commits
2ef0a8b710
...
a102dff508
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a102dff508 | ||
|
|
e81529c1bb |
@@ -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.)_
|
||||
|
||||
@@ -8,6 +8,11 @@ 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)
|
||||
- [ ] **#55 fingerprint enroll on real reader** — with
|
||||
`nomarchy.hardware.fingerprint.enable` and a physical reader: System ›
|
||||
Fingerprint › Enroll a finger; List shows it; Verify succeeds; optional
|
||||
Use for login (on) → `sys-rebuild` → login/sudo accept fingerprint.
|
||||
Menu surface is V1/V2 without a reader (self-gate + dry paths).
|
||||
- [ ] **#60 non-BAT* battery name (if available)** — on a machine whose
|
||||
system battery is **not** named `BAT*` (e.g. `CMB0`): confirm
|
||||
charge-limit oneshot writes the threshold, System › Battery limit
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -163,27 +163,26 @@ nomarchy.hardware.fingerprint.enable = true; # services.fprintd
|
||||
# nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in)
|
||||
```
|
||||
|
||||
### Enroll (CLI today)
|
||||
### Enroll (menu or CLI)
|
||||
|
||||
**Shipped #55:** System › Fingerprint (self-gated when `fprintd-list` is
|
||||
on PATH) — Enroll / List / Verify / Delete all, plus **Use for login**
|
||||
which writes `settings.fingerprint.pam` and applies on the next
|
||||
`sys-rebuild` (option default follows theme-state.json).
|
||||
|
||||
```sh
|
||||
fprintd-enroll # as your user
|
||||
# CLI still works:
|
||||
fprintd-enroll
|
||||
fprintd-list "$USER"
|
||||
# then, if you want login/sudo:
|
||||
# uncomment fingerprint.pam in system.nix → sys-rebuild
|
||||
# or: System › Fingerprint › Use for login (on) → sys-rebuild
|
||||
```
|
||||
|
||||
PAM stays opt-in on purpose: password-only remains the cautious default
|
||||
until a finger is enrolled.
|
||||
until a finger is enrolled. Full enroll on a real reader is V3/hardware.
|
||||
|
||||
### Gaps
|
||||
### Doctor
|
||||
|
||||
- No System menu “Fingerprint” row (enroll / list / delete).
|
||||
- No “use for login” toggle that writes state + rebuild note.
|
||||
- Doctor does not check reader presence or enroll status.
|
||||
|
||||
**Product direction (queued):** when `fprintd` is active, a self-gated
|
||||
menu module for enroll/list; optional PAM toggle via state + rebuild
|
||||
hint (same pattern as Bluetooth in Control Center).
|
||||
`nomarchy-doctor` reports fprintd unit + enroll status when present.
|
||||
|
||||
## 6. NVIDIA (deep dive)
|
||||
|
||||
|
||||
@@ -702,6 +702,62 @@ ${themeRows}
|
||||
fi
|
||||
printf "\nEnter to close."; read -r _' ;;
|
||||
|
||||
fingerprint)
|
||||
# System ▸ Fingerprint — enroll/list/delete + optional PAM for
|
||||
# login/sudo (HARDWARE.md §5, BACKLOG #55). Self-gated on fprintd
|
||||
# CLI (services.fprintd). Enroll is interactive → terminal.
|
||||
command -v fprintd-list >/dev/null 2>&1 \
|
||||
|| { notify-send "Fingerprint" "fprintd not available (nomarchy.hardware.fingerprint.enable?)."; exit 0; }
|
||||
pam=$(nomarchy-theme-sync get settings.fingerprint.pam 2>/dev/null || echo false)
|
||||
case "$pam" in true|True) pam_label="Use for login (on)" ;; *) pam_label="Use for login (off)" ;; esac
|
||||
choice=$( {
|
||||
row "Enroll finger" preferences-desktop-user-password
|
||||
row "List enrolled" view-list
|
||||
row "Verify" dialog-password
|
||||
row "Delete all" edit-delete
|
||||
row "$pam_label" system-lock-screen
|
||||
back
|
||||
} | rofi -dmenu -show-icons -p Fingerprint) || exit 0
|
||||
case "$choice" in
|
||||
"$BACK") exec "$0" system ;;
|
||||
*Enroll*)
|
||||
exec ${cfg.terminal} -e sh -c '
|
||||
echo "== Enroll fingerprint for $USER =="
|
||||
fprintd-enroll || true
|
||||
printf "\nEnter to close."; read -r _' ;;
|
||||
*List*)
|
||||
exec ${cfg.terminal} -e sh -c '
|
||||
echo "== Enrolled fingers for $USER =="
|
||||
fprintd-list "$USER" || true
|
||||
printf "\nEnter to close."; read -r _' ;;
|
||||
*Verify*)
|
||||
exec ${cfg.terminal} -e sh -c '
|
||||
echo "== Verify fingerprint for $USER =="
|
||||
fprintd-verify || true
|
||||
printf "\nEnter to close."; read -r _' ;;
|
||||
*"Delete all"*)
|
||||
exec ${cfg.terminal} -e sh -c '
|
||||
echo "== Delete all fingerprints for $USER =="
|
||||
printf "Type yes to delete every enrolled finger: "
|
||||
read -r ans
|
||||
case "$ans" in
|
||||
yes) fprintd-delete "$USER" || true ;;
|
||||
*) echo "Cancelled." ;;
|
||||
esac
|
||||
printf "\nEnter to close."; read -r _' ;;
|
||||
*"Use for login"*)
|
||||
case "$pam" in true|True) new=false ;; *) new=true ;; esac
|
||||
if [ "$new" = true ]; then
|
||||
if fprintd-list "$USER" 2>/dev/null | grep -qiE 'no fingers enrolled|No devices available'; then
|
||||
notify-send "Fingerprint" "Enroll a finger first, then enable login."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
nomarchy-theme-sync --quiet set settings.fingerprint.pam "$new" --no-switch
|
||||
notify-send "Fingerprint" "Use for login: $new — applies on next sys-rebuild."
|
||||
;;
|
||||
esac ;;
|
||||
|
||||
controlcenter)
|
||||
# Nomarchy TUI Control Center.
|
||||
exec ${cfg.terminal} -e nomarchy-control-center ;;
|
||||
@@ -811,6 +867,8 @@ ${themeRows}
|
||||
# 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
|
||||
# Fingerprint — self-gated on fprintd CLI (services.fprintd; BACKLOG #55).
|
||||
command -v fprintd-list >/dev/null 2>&1 && row "Fingerprint" preferences-desktop-user-password
|
||||
command -v nomarchy-control-center >/dev/null 2>&1 && row "Control Center" preferences-desktop
|
||||
if has_system_battery && command -v powerprofilesctl >/dev/null 2>&1; then
|
||||
row "Power profile" preferences-system-power
|
||||
@@ -835,6 +893,7 @@ ${themeRows}
|
||||
*Rollback*) exec "$0" rollback ;;
|
||||
*Doctor*) exec "$0" doctor ;;
|
||||
*Firmware*) exec "$0" firmware ;;
|
||||
*Fingerprint*) exec "$0" fingerprint ;;
|
||||
*"Control Center"*) exec "$0" controlcenter ;;
|
||||
*"Power profile"*) exec "$0" power-profile ;;
|
||||
*"Battery limit"*) exec "$0" batterylimit ;;
|
||||
@@ -904,7 +963,7 @@ ${themeRows}
|
||||
esac ;;
|
||||
|
||||
*)
|
||||
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autocommit|vpn|snapshot|doctor|firmware|controlcenter|rollback]" >&2
|
||||
echo "usage: nomarchy-menu [lookfeel|tools|system|power|power-profile|powermgmt|batterylimit|theme|clipboard|calc|files|emoji|web|network|bluetooth|audio|display|display-profile|printers|capture|colorpicker|keybinds|ask|dnd|nightlight|autotimezone|autocommit|vpn|snapshot|doctor|firmware|fingerprint|controlcenter|rollback]" >&2
|
||||
exit 64 ;;
|
||||
esac
|
||||
'';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
|
||||
let
|
||||
cfg = config.nomarchy.hardware;
|
||||
# Fingerprint PAM can follow theme-state.json (menu toggle → next
|
||||
# sys-rebuild), same bridge as autoTimezone (BACKLOG #55).
|
||||
hwState =
|
||||
if config.nomarchy.system.stateFile != null
|
||||
then builtins.fromJSON (builtins.readFile config.nomarchy.system.stateFile)
|
||||
else { };
|
||||
pamFromState = (hwState.settings or { }).fingerprint.pam or false;
|
||||
in
|
||||
{
|
||||
options.nomarchy.hardware = {
|
||||
@@ -92,9 +99,18 @@ in
|
||||
a fingerprint reader via fprintd (the installer turns this on when it
|
||||
detects a known reader). Enroll with `fprintd-enroll`'';
|
||||
|
||||
pam = lib.mkEnableOption ''
|
||||
using the fingerprint for login and sudo (PAM). Opt-in — password-only
|
||||
stays the default for the cautious; enroll a finger first'';
|
||||
pam = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = pamFromState;
|
||||
defaultText = lib.literalExpression
|
||||
"(settings.fingerprint.pam from theme-state.json) or false";
|
||||
description = ''
|
||||
Use the fingerprint for login and sudo (PAM). Opt-in — password-only
|
||||
stays the default for the cautious; enroll a finger first. Defaults
|
||||
from theme-state.json `settings.fingerprint.pam` (System › Fingerprint
|
||||
menu) when set; otherwise false.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
npu.enable = lib.mkEnableOption ''
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user