All checks were successful
Check / eval (push) Successful in 3m31s
Four failures from Bernardo's round-4 dock pass on the AMD dev box, plus a headphone regression, tracked to three causes. The display watcher ran socat with `-T 1`, which closes Hyprland's IPC socket after one second of *inactivity*. A dock is normally plugged into an idle desktop, so the socket was almost always mid-reconnect at that moment and `monitoradded` was lost outright — and the wallpaper repaint, the docking profile, and the dock-audio reprobe all hung off that single event. The reconnect path recovered only the lid inhibitor, so the dock stayed half-configured until something else poked the watcher. Make the connection long-lived and take the periodic tick from a 1s `read` timeout instead, then let the *output set* — not the event — decide: a new `reconcile` diffs it and is called on both ticks and monitor events, so an event now only makes the reaction instant rather than necessary. A newly present external output is as unambiguous a physical plug as the event was, so it may still override a manual sink choice. Wallpaper paints are retried over the first few seconds because awww registers an output on its own schedule, not the compositor's. Hyprland calls every key-capable evdev node a "keyboard": the lid and power buttons, a monitor's control channel, and each extra HID collection of a real keyboard. One dock with one keyboard asked for a layout four times. udev already draws the distinction properly, so take ID_INPUT_KEYBOARD from it, map the names into Hyprland's spelling, and ask once per physical keyboard — applying the answer to every node it brought with it. Finally, a sink WirePlumber has been told to prefer is stored as the configured default and outranks every priority rule. On UCM cards the headphones are a sink of their own rather than a route, so once anything pinned a sink (this feature on a dock plug, or the user in the Audio menu), plugging headphones in could no longer take the audio back. The `watch` loop already subscribed to exactly the right events with an empty handler; finish it. Unplug needs no undo — the pin goes stale and WirePlumber falls back by priority on its own, to the dock when docked and the speakers otherwise. Verified V2: checks.docking-ux and checks.dock-audio pass with new guards against each regression; the keyboard filter and both sink selectors run against the dev box's real devices and sink names. The hotplug paths need hardware — queued as docking round 5. Also queues #107, renaming theme.json now that it holds the system state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
342 lines
22 KiB
Markdown
342 lines
22 KiB
Markdown
# Hardware queue — V3 checks only a human can run
|
||
|
||
Everything shipped at V1/V2 whose final verification needs real hardware.
|
||
Agents **append** (newest at the bottom of a section) with exact steps;
|
||
Bernardo runs them and either checks off (`[x]` + date + verdict) or files
|
||
the failure as a NOW bug in BACKLOG.md. Checked-off entries are **pruned**
|
||
on the next sync sweep (LOOP.md §5) — outcomes live in the journal/ROADMAP;
|
||
git history is the archive. Machines: the **AMD dev box** (Ryzen AI
|
||
laptop: AMD + fingerprint + NPU), the **Latitude 5310/5410** (Intel QA),
|
||
the **T14s** (webcam case).
|
||
|
||
## Any machine (dev box is fine)
|
||
|
||
- [ ] **#96 battery-limit row on threshold-less firmware (Acer M5-481T)** —
|
||
on the Acer (live or installed session with the commit carrying this
|
||
entry): open System (`SUPER+CTRL+I`). **Pass:** a "Battery limit" row
|
||
IS listed (battery present); picking it shows the notification
|
||
explaining the firmware exposes no charge-stop control (not a raw
|
||
error, and the row never silently disappears). On the T14s the row
|
||
must still open the working preset picker.
|
||
- [ ] **#101 charge-limit service survives USB-C power-event bursts**
|
||
(round 2) — round 1 FAILED on TuringMachine 2026-07-13 18:16: a
|
||
*spaced* storm (each run finished before the next AC event) landed 5
|
||
successful starts in 10s → `start-limit-hit`, unit marked failed,
|
||
doctor badge — although every run succeeded. Fixed by exempting the
|
||
unit from start rate limiting (`StartLimitIntervalSec=0`) + a
|
||
spaced-storm guard in `checks.battery-charge-limit` (the commit
|
||
carrying this entry). **Re-check:** after pulling/rebuilding this
|
||
commit, `sudo systemctl reset-failed nomarchy-battery-charge-limit
|
||
.service`, then plug/unplug the powered USB-C dock several times in
|
||
quick succession. **Pass:** `systemctl is-failed
|
||
nomarchy-battery-charge-limit.service` stays false, `Result=success`,
|
||
BAT0's `charge_control_end_threshold` still matches the limit, and the
|
||
journal has no new `start-limit-hit`/`Failed with result` lines.
|
||
- [ ] **Docking recovery round 5 (dock/keyboard/audio hotplug, 2026-07-14)**
|
||
— round 4 was run on the AMD dev box and **failed on four counts**
|
||
(Bernardo): no wallpaper on the external monitor, no automatic dock
|
||
mode (System › Display had to be used by hand), audio staying on the
|
||
laptop speakers while docked, and one dock + one external keyboard
|
||
asking for a layout **four times**. Separately, plugging headphones had
|
||
stopped moving audio to them. Causes and fixes in the commit carrying
|
||
this entry: the display watcher's `socat -T 1` closed Hyprland's IPC
|
||
socket after a second of idle, so a dock plugged into an idle desktop
|
||
lost `monitoradded` in the reconnect gap (wallpaper + dock mode + audio
|
||
all hang off that one event); Hyprland lists every key-capable evdev
|
||
node as a "keyboard"; and a pinned `default.configured.audio.sink`
|
||
outranks the priority rules, which kills jack-follow on UCM cards where
|
||
the headphones are their own sink. **Re-run round 4 below in full**,
|
||
plus: (a) leave the desktop untouched for ~30s, then plug the dock —
|
||
wallpaper, dock mode, and audio must all follow with no manual step;
|
||
(b) the external keyboard must prompt **exactly once**, and never for
|
||
the monitor or the lid/power buttons; (c) docked and undocked, plug and
|
||
unplug headphones — audio must move to them and back each time.
|
||
`journalctl --user -t nomarchy-display-watch` should show
|
||
`outputs-changed added=…`, and `-t nomarchy-dock-audio`
|
||
`trigger=jack selected=…` on a headphone plug.
|
||
- [ ] **Docking recovery round 4 (#100, closed-lid BenQ sequence)** — after
|
||
updating to the commit carrying this entry, run `nomarchy-home` and
|
||
relogin. With the lid open, put visible windows on at least workspaces
|
||
1, 2, and 3 and start audio; plug the BenQ GW2790QT. **Pass on plug:**
|
||
wallpaper appears, audio toasts and moves to a BenQ/GPU HDMI sink, and
|
||
`journalctl --user -t nomarchy-dock-audio -n 10` shows
|
||
`trigger=monitoradded` plus `selected=…` (not only a card event). Open
|
||
System › Display › **Dock mode**. **Pass on dock:** every workspace and
|
||
window is on the BenQ, focus follows, eDP is disabled in `hyprctl
|
||
monitors all -j`, and `systemd-inhibit --list` shows Nomarchy holding
|
||
`handle-lid-switch` for “Safe dock/undock display transition”; there is
|
||
no dangling laptop workspace and no application exits. Close the lid;
|
||
audio/session must stay awake. While still docked, manually choose the
|
||
speakers and change volume/mute: it must stay on speakers. Unplug the
|
||
BenQ **with the lid still closed**, wait 10 seconds, then open it.
|
||
**Pass on undock:** no suspend/crash/hard reset, eDP is already active,
|
||
workspaces 1/2/3 and their windows are intact on it, and the inhibitor
|
||
disappears only after lid-open. `journalctl -b --since '-5 min'` must
|
||
contain no cable-removal `systemd-logind: Suspending...`. Finally close
|
||
the undocked lid normally: the laptop must suspend, proving policy was
|
||
restored. Wake it, replug the BenQ: that fresh plug must move audio back
|
||
to HDMI (manual speakers do not survive a physical replug). If any step
|
||
fails, capture `journalctl --user -t nomarchy-display-watch -t
|
||
nomarchy-display-transition -t nomarchy-dock-audio --since '-10 min'`,
|
||
`systemd-inhibit --list`, `hyprctl monitors all -j`, `hyprctl workspaces
|
||
-j`, and `pactl --format=json list sinks` before changing state again.
|
||
- [ ] **Parallel fingerprint-or-password on the real reader** (AMD dev
|
||
box, 2026-07-12) — with a finger enrolled and
|
||
`fingerprint.pam = true` (parallel is the default): `sudo -k true`
|
||
must show ONE prompt ("Enter Password or Place finger…"); typing
|
||
the password immediately works, touching the sensor instead works,
|
||
wrong-finger ×3 falls back to password, and password keeps working
|
||
with fprintd stopped (`systemctl stop fprintd`). Also check
|
||
hyprlock and the greeter accept both factors and don't wedge on a
|
||
leftover prompt after a fingerprint win (known cosmetic quirk of
|
||
the hack — pthread_cancel'd prompt). `fingerprint.parallel = false`
|
||
must restore the old sequential behavior. VM already asserts the
|
||
PAM stack shape + password-only lockout safety with no reader
|
||
(checks.hardware-toggles).
|
||
- [ ] **#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) → `nomarchy-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
|
||
and Power profile rows appear, Waybar power-profile module shows,
|
||
doctor charge-limit section runs. On `BAT0`-only machines this is
|
||
a no-op (charge-limit re-apply passed on `BAT0` — Latitude
|
||
2026-07-10).
|
||
- [ ] **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.
|
||
- [ ] **SSH_AUTH_SOCK for GUI clients** — after relogin, launch a GUI git
|
||
client (or `rofi`-launched terminal-less app) and confirm it reaches
|
||
gpg-agent's SSH socket without an interactive shell parent.
|
||
- [ ] **Notification inhibited-state glyph** (item 28 color-only sweep,
|
||
iteration #69) — have an app hold a notification inhibitor (e.g. run
|
||
a fullscreen video, or `busctl --user call org.freedesktop.Notifications
|
||
… Inhibit`); the Waybar bell must switch to the muted **bell-off**
|
||
(same glyph as DND), NOT the normal bell /. Then release it → the
|
||
bell returns. Repeat on a whole-swap bar (summer-day/night use their
|
||
own bell-off glyph, executive-slate/boreal use ). The glyph itself
|
||
already renders (DND uses it); this only confirms swaync emits the
|
||
`inhibited-*` class and the bar routes it.
|
||
- [ ] **Keyboard layout cycle bind** — with a comma layout (e.g.
|
||
`nomarchy.keyboard.layout = "us,de"`), SUPER+SHIFT+K cycles the
|
||
focused keyboard's layout, the Waybar `` indicator follows, and
|
||
the row shows in the SUPER+? cheatsheet. — 2026-07-04 attempt:
|
||
no comma layout was configured, so the bind wasn't rendered (the
|
||
gate working as designed, not a failure) — retest after setting a
|
||
comma layout + rebuild + relogin. The SUPER+? no-op found en
|
||
route was a real bug → BACKLOG item 26 (fix shipped; SUPER+?
|
||
cheatsheet PASS on Latitude 2026-07-10).
|
||
- [ ] **swaync readable on summer-day** (item 25 fix) — on summer-day
|
||
after `home-update`: `notify-send "title" "body text"` shows
|
||
readable body text; open the control centre (SUPER+N), hover a
|
||
notification row and check the Clear button — all text legible
|
||
(body/buttons now @text on tinted chips, not subtext/surface).
|
||
- [ ] **Bar + rofi legible on flexoki-light** (item 27 fix) — switch to
|
||
flexoki-light: every Waybar module readable (window title, tray
|
||
row, dimmed inactive workspaces / muted volume visible-but-dim),
|
||
rofi inputbar/alternate rows show text. Spot-check one dark theme
|
||
(e.g. tokyo-night) for no visual regression in the same spots.
|
||
- [ ] **Stub-bar themes got the generated bar** (item 28, 90a5104) —
|
||
switch to catppuccin, lumon, nord and retro-82: each now shows
|
||
the generated styled bar in its own palette (workspace pill,
|
||
padded right cluster) instead of the old raw default Waybar.
|
||
Their rofi menus should look unchanged.
|
||
- [ ] **Back-audit spot-check** (item 24) — the keybinds cheatsheet
|
||
(SUPER+? / root menu › Keybindings) now ends in ↩ Back and
|
||
returns to the root picker; spot a couple of submenus (Display,
|
||
VPN › Tailscale) still Back correctly after the audit pass.
|
||
- [ ] **Per-device keyboard menu + hotplug restore (re-verify after in-flake
|
||
graduation)** — update to the current `main`, run `nomarchy-home`, and
|
||
relogin with an external keyboard already connected. Open System ›
|
||
Keyboard: both the built-in and external boards must be listed with
|
||
their current layouts. Pick a different layout for the external board;
|
||
it must apply only there and persist in `settings.keyboard.devices`.
|
||
Unplug/replug it: the saved layout must restore without another prompt
|
||
and graduate into a `device{}` block on the next rebuild. Finally plug
|
||
a previously unseen keyboard in after login: the automatic picker must
|
||
appear once and remember that choice too.
|
||
- [ ] **Snapshots restore + rollback exercise** (residual — the
|
||
GUI/polkit half passed on hardware 2026-07-04, a47aa3a): in
|
||
`sudo nomarchy-snapshots`, restore a single file (`undochange`)
|
||
and walk a root-config rollback up to (or through) the
|
||
typed-`yes` gate.
|
||
- [ ] **Rollback menu (item 9b)** — after a couple of theme changes,
|
||
menu › System › Rollback: recent desktop generations listed
|
||
(newest marked current); picking an older one opens a terminal,
|
||
activates it, and the theme visibly reverts; picking the newer one
|
||
again rolls forward. The two System rows: Snapshots opens the
|
||
snapshot flow, "boot an older generation (how)" fires an
|
||
instruction notification.
|
||
- [ ] **Open-a-file smoke (viewers + mime defaults, item 8)** — after
|
||
`nomarchy-home`: from yazi/Thunar, open a PDF (→ zathura, themed to
|
||
the palette), an image (→ imv, NOT GIMP), a video (→ mpv);
|
||
`xdg-open .` on a directory → Thunar; a link → **Chromium**
|
||
(`chromium-browser.desktop` — template default as of 2026-07-10).
|
||
- [ ] **Update awareness** — with `nomarchy.updates.enable`, let the timer
|
||
fire (or start the unit): indicator appears only when inputs are
|
||
behind, notification only on count growth, click opens the upgrade
|
||
flow.
|
||
- [ ] **VPN menu live paths** — import a real WireGuard `.conf` and an
|
||
`.ovpn` via System → VPN, toggle up/down (● / ○ state), and the
|
||
Tailscale block: up/down + exit-node without sudo (operator grant).
|
||
Exit-node rows now show "hostname — Country City" (2026-07-11,
|
||
header-offset parsing): confirm Mullvad-style nodes carry their
|
||
location, a locationless self-hosted node stays a bare hostname,
|
||
and picking either still sets the node (`tailscale status` shows it).
|
||
- [ ] **Printer menu** — with `nomarchy.services.printing`, System →
|
||
Printers opens system-config-printer; add a printer, test page.
|
||
- [ ] **GRUB UEFI ISO theme render** — boot the ISO on UEFI hardware:
|
||
composed splash background, palette menu in the lower third, accent
|
||
timeout bar.
|
||
- [ ] **Visual theme pass** — live ISO: all six identity themes (bars) +
|
||
the four authored rofi `.rasi` (nord/retro-82/lumon/kanagawa) look
|
||
right, not just parse.
|
||
- [ ] **Display profiles, slice a (item 15)** — declare two
|
||
`nomarchy.displayProfiles` (e.g. docked disables eDP-1 + arranges
|
||
the externals; undocked re-enables it), `home-update`, then:
|
||
System › Display › Profiles lists them (● marks active); applying
|
||
is instant (no rebuild) and survives a relogin (the baked
|
||
overlay); "Base layout" restores; a menu resolution pick made
|
||
earlier must NOT re-enable a profile-disabled panel after the
|
||
next rebuild.
|
||
- [ ] **Display profiles workspace pins, slice c (item 15)** — give the
|
||
docked profile `workspaces = { "1" = "<ext>"; "9" = "eDP-1"; }`:
|
||
applying the profile moves open workspaces 1/9 to those outputs
|
||
immediately, new visits land there too, and the pins survive a
|
||
relogin (baked `workspace` rules). Switching to a profile without
|
||
pins leaves workspaces where they are (stale session pins are
|
||
expected until reload/rebuild — noted in the applier).
|
||
- [ ] **Display profiles auto-switch, slice b (item 15)** — same setup,
|
||
then menu › Profiles › Auto-switch on: plugging the dock/monitor
|
||
applies the matching profile within ~3s (toast names it);
|
||
unplugging switches back; Auto-switch off stops that; with two
|
||
profiles naming the same outputs, no flapping (ties do nothing).
|
||
- [ ] **P2 retunes eyeball (item 28b)** — spot-check on top of the P1
|
||
entry below: gruvbox/nord/lumon/everforest/retro-82/white dimmed
|
||
text (inactive workspaces, muted volume) now visible-but-dim;
|
||
latte + rose-pine(dawn) + summer-day warn/battery tint reads on
|
||
the light bases; flexoki-light statuses are the deeper canonical
|
||
600s; latte selected-row/alt-accent pink darker. Anything that
|
||
lost its "dim" feel → reopen 28b.
|
||
- [ ] **Retuned palettes eyeball (item 28b P1)** — switch through
|
||
summer-day, flexoki-light, kanagawa, miasma: chips/menus/toasts
|
||
now draw on a *raised* surface (summer-day's was slate-on-cream,
|
||
kanagawa's near-black, miasma's pure black), secondary text
|
||
(tooltips, fastfetch labels) is visible on summer-day +
|
||
flexoki-light, kanagawa floats are lighter than the bg (upstream
|
||
sumiInk4). Anything that reads worse than before → reopen 28b.
|
||
- [ ] **Doctor bar tripwire (LATER item)** — with everything healthy
|
||
the bar shows nothing; `systemctl --user start doomed`-style
|
||
induced failure → within ~5 min a red appears (tooltip lists
|
||
the ✖ lines), clicking opens the sheet in a terminal;
|
||
reset-failed → it disappears on the next poll. Also visible on
|
||
both summer bars.
|
||
- [ ] **OCR region (LATER item)** — Tools › Capture › "OCR region →
|
||
clipboard": select a region with visible text → toast reports
|
||
the word count and `wl-paste` yields the text; Esc in slurp
|
||
cancels silently; a text-free region toasts "No text recognized"
|
||
without clobbering the clipboard.
|
||
- [ ] **Look & Feel submenu (item 19)** — root menu: "Look & Feel"
|
||
(replacing Theme, root still six rows) → Theme grid opens, Next
|
||
wallpaper cycles instantly, Night light toggles (and is GONE
|
||
from System). SUPER+T / SUPER+SHIFT+T direct binds unchanged.
|
||
- [ ] **Launch-or-focus (item 17)** — uncomment the template's
|
||
`nomarchy.launchOrFocus` firefox example (with firefox
|
||
installed), `home-update` + reload: SUPER+B launches firefox
|
||
when closed, FOCUSES the existing window when open (also from
|
||
another workspace); with firefox removed the bind fires a
|
||
"not installed" toast; the row shows under SUPER+?.
|
||
- [ ] **Themed greeter + console (item 16)** — after `sys-rebuild` +
|
||
logout: tuigreet renders in theme colors (dark container, accent
|
||
border, themed prompt/time) and a raw tty (CTRL+ALT+F2) shows the
|
||
theme's ANSI palette; on a LUKS machine the passphrase prompt
|
||
follows too. Then switch theme + `sys-rebuild` + logout → the
|
||
greeter follows the new palette. (tuigreet can't run under the
|
||
VM harness — see MEMORY.md — so rendering is hardware-tier.)
|
||
- [ ] **Color picker (item 13, final slice)** — SUPER+CTRL+P (or Tools ›
|
||
Color picker): hyprpicker's zoom loupe appears; click a pixel →
|
||
toast shows the hex and `wl-paste` yields it; Esc cancels with no
|
||
toast. Row present in the SUPER+? cheatsheet.
|
||
- [ ] **Low-battery toasts (item 13 slice)** — on battery, drain past
|
||
25%: one "Battery low" toast; past 10%: a critical "Battery
|
||
critical" toast that stays up until dismissed (swaync); plug in,
|
||
drain again → it re-notifies; no repeat toasts while it just keeps
|
||
draining. (Crossing logic VM-verified — this checks the real
|
||
swaync rendering in a session.)
|
||
|
||
- [ ] **Audio opens in Amberol** (iteration #60, item 37) — after
|
||
`nomarchy-home`: double-click an mp3/flac/ogg (or `xdg-open song.mp3`)
|
||
→ it opens in Amberol, not mpv; video files still open in mpv.
|
||
(`xdg-mime query default audio/mpeg` → io.bassi.Amberol.desktop.)
|
||
- [ ] **rofi menu polish** (iteration #58, item 39 + #56/#57 34/40) —
|
||
after `nomarchy-home`: (a) menu › System › Power profile shows a
|
||
colored icon per profile (performance/balanced/power-saver), not
|
||
just text — icons *render* (not blank); (b) every submenu's ↩ Back
|
||
shows a single arrow, no double; (c) on this single-monitor box,
|
||
System › Display → pick a resolution → Back returns to System
|
||
(not back into the same resolution list).
|
||
- [ ] **Screenshot annotation (satty)** (iteration #73) — after `nomarchy-home`:
|
||
hit SUPER+SHIFT+Print (or Tools ▸ Capture ▸ Annotate region) → a region
|
||
select (slurp) appears, then the `satty` UI opens in fullscreen with the
|
||
screenshot loaded. Check that the UI draws on the current theme palette
|
||
(tools colored properly) and hitting save places the screenshot in
|
||
`~/Pictures/Screenshots/` while hitting copy places it in the clipboard.
|
||
- [ ] **#76 no-swap Hibernate notify** (#76 itself is closed — the
|
||
hibernate→resume power-cycle **PASSED on TuringMachine 2026-07-12**:
|
||
Bernardo ran the full hibernate → power off → single LUKS unlock →
|
||
session-restored cycle "flawlessly"; this notify check is the one
|
||
remaining leftover) — on a **Nomarchy** machine installed
|
||
with `swap = 0` (or temporarily `sudo swapoff -a` on one): `nomarchy-menu
|
||
→ Power → Hibernate` must surface a desktop notification ("Couldn't
|
||
hibernate — likely no swap is configured. See docs/MIGRATION.md →
|
||
Enabling hibernation."), **not** a silent no-op. (`swapon` after, if you
|
||
swapoff'd for the test.)
|
||
- [ ] **Night-light geo mode (2026-07-11)** — in `home.nix` set
|
||
`nomarchy.nightlight = { enable = true; latitude = "<lat>";
|
||
longitude = "<long>"; }` (your real coordinates), `nomarchy-home`,
|
||
relogin. Then: `systemctl --user status wlsunset` is running (and
|
||
`hyprsunset` is NOT); after local sunset the screen visibly warms
|
||
(or test by setting coordinates where it's currently night); the
|
||
Waybar moon + menu toggle still flip it instantly and an *off*
|
||
survives relogin (the ExecCondition gate on the swapped unit —
|
||
the eval check proves the wiring, not the runtime gate). **Pass** =
|
||
warm shift at the location's night + toggle/persistence intact.
|
||
|
||
## AMD dev box only
|
||
- [ ] **AMD runtime bits** — VA-API (`vainfo` → radeonsi), amd-pstate EPP
|
||
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 5310 / 5410 only
|
||
- [ ] **v1 QA batch on-hardware pass** (583708d batch was QEMU-verified) —
|
||
general smoke before the next `main → v1` promotion (broader than
|
||
the 2026-07-10 session; include theme/ISO/greeter leftovers).
|
||
|
||
## T14s only
|
||
- [ ] **Webcam IR-hide end-to-end on Nomarchy** — installer detects the
|
||
RGB+IR pair, bakes `hardware.camera.hideIrSensor`; `wpctl status`
|
||
shows one colour source; an app picker lists one camera; Howdy-style
|
||
direct `/dev/video2` reads still work.
|
||
- [ ] **Portal/Flatpak libcamera IR (b)/(c)** — after #71 docs: on hardware,
|
||
confirm a Flatpak/portal picker still lists the internal IR node;
|
||
only then investigate (b) WirePlumber libcamera GREY-only monitor
|
||
rule or (c) libcamera/udev-layer hide. Do not ship either without a
|
||
live dual-sensor check (see HARDWARE.md §7 / ROADMAP § Webcam).
|