Files
Nomarchy/docs/HARDWARE.md
Bernardo Magri bbdc329ed6
All checks were successful
Check / eval (push) Successful in 3m39s
feat(first-boot): post-install hardware hints — one self-gated toast, once
After the #81 "you're set" card, at most one additional "Hardware tips"
toast: a Firmware line when fwupdmgr is on PATH, a Fingerprint line when
fprintd-list is (VISION § B). One-shot marker settings.hardwareHintsShown,
in-checkout like firstBootShown. When no tooling matches, the marker is
deliberately left unset — the re-check costs a command -v per session,
and a later-enabled fwupd or newly-added reader still gets its hint once.
Never a permanent nag; live-ISO gate covers the new stage too.

Lives inside nomarchy-first-boot: the card's semantics are unchanged
(retry loop, exit 1 so a failed notify retries next login, marker only
after success); hints run only once the card has landed. Docs: README
option row, HARDWARE.md hint paragraphs, VISION § B checked off.

Verification: V2 — shellcheck clean, nix flake check --no-build green,
nix build .#checks.x86_64-linux.first-boot green (bare node silent →
fwupdmgr appears → fires once → silent again → live-ISO still skips).
Real toast rendering is the same session surface as the proven #81 card.
Implementation by a Sonnet subagent; design and review on Fable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 07:56:03 +01:00

530 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Hardware support
How Nomarchy enables CPUs, GPUs, laptops, firmware, and peripherals — and
what to do when your machine is not in the happy path.
**Minimum bar** (OpenGL, RAM, disk, UEFI): [`REQUIREMENTS.md`](REQUIREMENTS.md)
— read that before calling a machine “unsupported”; this file is the
enablement stack and quirk list.
> **Queue:** [`agent/BACKLOG.md`](../agent/BACKLOG.md) (PROPOSED Hardware
> product). Product framing: [`VISION.md`](VISION.md) § A. Design history:
> [`ROADMAP.md`](ROADMAP.md). Docs map: [`README.md`](README.md).
> Migration: [`MIGRATION.md`](MIGRATION.md).
## 1. Architecture (three layers)
Nomarchy does **not** reimplement [nixos-hardware](https://github.com/NixOS/nixos-hardware).
It stacks:
```
┌─────────────────────────────────────────────────────────────────────┐
│ A. Always-on desktop floor │
│ modules/nixos/default.nix + power.nix + audio/BT │
│ redistributable firmware · fwupd · NM · PipeWire · PPD · ddcci │
└───────────────────────────────┬─────────────────────────────────────┘
┌───────────────────────────────▼─────────────────────────────────────┐
│ B. nixos-hardware profiles (via mkFlake hardwareProfile) │
│ common-cpu-* · common-gpu-* · common-pc(-laptop|-ssd) · model │
│ microcode · GPU media · fstrim · vendor/model quirks │
└───────────────────────────────┬─────────────────────────────────────┘
┌───────────────────────────────▼─────────────────────────────────────┐
│ C. nomarchy.hardware.* (modules/nixos/hardware.nix) │
│ gap above commons: GuC · amd-pstate · VA-API env · fprintd · │
│ IR-webcam hide · ROCm/NPU/latestKernel · I2C/DDC/CI │
└─────────────────────────────────────────────────────────────────────┘
```
| Layer | Who turns it on | Where it lives |
|-------|-----------------|----------------|
| **A** | Distro defaults (`mkDefault`) | Any machine importing `nomarchy.nixosModules.nomarchy` |
| **B** | Installer DMI/`lspci``hardwareProfile = [ … ]` | Downstream `flake.nix` (`mkFlake`) |
| **C** | Installer probes → `system.nix`, or hand-edit | Downstream `system.nix` |
`hardware-configuration.nix` (from `nixos-generate-config`) still owns
initrd modules, filesystems, and the usual generate-config flags. The
installer writes a real one; the template ships a placeholder you must
replace.
Unknown `hardwareProfile` names **fail at eval** with Levenshtein
suggestions (`lib.nix`) — never silently ignored.
## 2. What works without thinking about it
These ship on every Nomarchy system unless you override them:
| Capability | Default | Notes |
|------------|---------|--------|
| WiFi / BT firmware blobs | `hardware.enableRedistributableFirmware` | iwlwifi, ath, rtw, brcm, SOF, … |
| NetworkManager | on | WiFi UI: System Network |
| PipeWire + WirePlumber | on | |
| Bluetooth + blueman | on | System Bluetooth |
| power-profiles-daemon | on | Menu + Waybar; TLP via `nomarchy.system.power.backend = "tlp"` |
| External monitor brightness | `nomarchy.hardware.i2c.ddcci` **on** | DDC/CI → backlight devices |
| Firmware updates (LVFS) | `services.fwupd.enable` | **Never auto-flashes** — see §4 |
| SMART / UPower / pcscd (FIDO) | on | |
| earlyoom | on | Process-level OOM, not cgroup kill of the whole session |
**Not** default-on (need detect or uncomment): fprintd, GuC/HuC,
amd-pstate, ROCm, NPU, thermald, charge limit, snapper (installer enables
snapper), `latestKernel`.
## 3. Install path (best experience)
`nomarchy-install` sources `pkgs/nomarchy-install/hardware-db.sh` and:
1. Probes CPU vendor, GPUs (`lspci`), battery, SSD, fingerprint USB VIDs,
RGB+IR webcam names, NPU PCI class.
2. Looks up DMI `sys_vendor` × `product_name` in a ~60-entry model table
(Framework, Dell XPS/Latitude, ThinkPad, Surface, ASUS ROG, Apple T2,
System76).
3. Emits `MODULE …` lines → `hardwareProfile` list in `flake.nix`.
4. Emits `NOMARCHY hardware.*=…` → active + commented blocks in
`system.nix`.
5. Asks you to confirm profiles (or pick manually from the full
nixos-hardware attr list baked into the ISO). Override with
`NOMARCHY_HW=auto|none|"mod1 mod2"`.
**Live ISO** is intentionally *generic* (no model profile): broad GPU
modules as *available*, redistributable firmware on, no baked
`nomarchy.hardware.*`. Tuning happens at install time.
Out of scope for the installer today: aarch64 (Pi, Snapdragon X), Steam
Deck (Jovian), Apple Silicon (T2 Intel Macs only in the DB).
## 4. Firmware updates (deep dive)
### What we ship
```nix
# modules/nixos/default.nix
services.fwupd.enable = lib.mkDefault true;
```
fwupd talks to the [LVFS](https://fwupd.org/): UEFI capsule (BIOS), some
SSDs, docks, Thunderbolt controllers, peripherals. It **only refreshes
metadata** on its own. Applying an update is always an explicit user
action.
### What you do today (CLI)
```sh
# After first boot (and occasionally later):
fwupdmgr refresh # optional; daemon often has metadata
fwupdmgr get-devices # what LVFS can see
fwupdmgr get-updates # pending
fwupdmgr update # apply (may need reboot / battery / AC)
```
Disable on VMs/headless: `services.fwupd.enable = false;` in `system.nix`.
### Why this is under-discovered
| Present | Missing |
|---------|---------|
| Daemon + package | Doctor check (“updates available”) |
| README one-liner | Waybar / updates panel integration |
| **System ▸ Firmware menu** (`nomarchy-menu firmware`) | |
| MOTD + first-boot tip (#43) | |
**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.
**Hints (#43 / #73):** MOTD cheat-sheet line when `fwupdmgr` is on PATH.
Fingerprint / doctor tips follow the same pattern (fingerprint MOTD only
when `nomarchy.hardware.fingerprint.enable`). A one-shot toast in the
first graphical session also points at System Firmware when `fwupdmgr`
is on PATH (`settings.hardwareHintsShown`, `nomarchy-first-boot`) — for
people who never read the MOTD.
**Still queued:** a Doctor “updates available” check, and
Waybar/updates-panel integration.
### Thunderbolt
Firmware for TB devices may appear via LVFS. There is **no** first-class
`services.hardware.bolt` / security-level UI in Nomarchy — use plain
NixOS options if you need bolt.
### Microcode / kernel firmware
- **CPU microcode:** from nixos-hardware `common-cpu-*` and
`nixos-generate-config` once redistributable firmware is on — not a
separate `nomarchy.*` toggle.
- **GPU GuC/HuC (Intel i915):** `nomarchy.hardware.intel.guc`
`i915.enable_guc=3`. Installer turns this **off** when the bound driver
is `xe` (GuC is default there; the param is ignored).
- **`hardware.enableAllFirmware`:** not set. Oddball non-redistributable
WiFi still needs a manual NixOS fix (or a broader policy decision).
## 5. Fingerprint (deep dive)
### Detect → enable
Installer scans USB vendor IDs common to libfprint (Goodix, Synaptics,
Elan, …) via `lsusb` or `/sys/bus/usb/.../idVendor`. On hit:
```nix
nomarchy.hardware.fingerprint.enable = true; # services.fprintd
# nomarchy.hardware.fingerprint.pam = true; # login + sudo (opt-in)
# nomarchy.hardware.fingerprint.parallel = false; # sequential prompt instead
```
### Enroll (menu or CLI)
**Shipped #55:** System Fingerprint (self-gated when `fprintd-list` is
on PATH) — a single **Fingerprint (on/off)** switch, plus Enroll / List /
Verify / Delete all (all usable while it's off — turning it on needs an
enrolled finger). The switch writes `settings.fingerprint.pam`, the one
state key behind *both* halves of "use my finger": login/sudo PAM here,
and the lock-screen unlock in `modules/home/idle.nix`. It runs
`nomarchy-fingerprint`, which sudos a system rebuild and then a home
switch, because the two halves live in different configurations.
It does **not** decide whether login prompts at all: auto-login skips the
greeter entirely, so this adds the finger to the prompts that actually
happen — sudo, the lock screen, and the greeter only when
[auto-login](#auto-login) is off.
**Hints (#73):** MOTD line when `fingerprint.enable` is on; first-boot
tip when `fprintd-list` is on PATH (`SUPER+M → System Fingerprint` /
`fprintd-enroll`). No permanent nag without a reader. A one-shot toast in
the first graphical session also points at System Fingerprint when
`fprintd-list` is on PATH (`settings.hardwareHintsShown`,
`nomarchy-first-boot`) — for people who never read the MOTD.
```sh
# CLI still works:
fprintd-enroll
fprintd-list "$USER"
nomarchy-fingerprint toggle # or on | off | status — what the menu row runs
```
PAM stays opt-in on purpose: password-only remains the cautious default
until a finger is enrolled. Full enroll on a real reader is V3/hardware.
### Auto-login
`settings.greeter.autoLogin` (System Auto-login, or `nomarchy-autologin
[toggle|on|off|status]`) decides whether boot goes straight to the desktop
or stops at the greeter. The installer seeds it ON for LUKS-encrypted
machines — the disk passphrase already gates the machine, so a greeter
password is a second prompt for the same thing — and leaves it off
without LUKS, where the greeter is the only thing between power-on and the
desktop. It's baked into greetd at system rebuild, so the change shows on
the next boot.
Auto-login and fingerprint are independent, and auto-login wins at boot:
with it on you are never asked for anything at startup, whatever the
fingerprint switch says. Turn auto-login off and the greeter asks — for a
password, or a password *or* finger when fingerprint is on.
Both are in-flake state rather than lines in `system.nix` on purpose: a
hand-set `nomarchy.system.greeter.autoLogin` (or
`nomarchy.hardware.fingerprint.pam`) outranks the state and pins the
setting, leaving the menu toggle unable to move it. That's the escape
hatch, not the default — leave those lines commented to use the menu.
### Parallel prompt (password *or* finger, whichever first)
With `fingerprint.pam` on, sudo/login/hyprlock show **one** prompt that
accepts either factor — type the password or touch the sensor
(2026-07-12; `pam-fprint-grosshack`, an fprintd fork, since stock PAM
can't express parallel factors). This is the default;
`fingerprint.parallel = false` restores stock pam_fprintd's sequential
wait-for-the-reader-then-password. Lockout safety is structural: the
module never validates passwords itself — a typed password is handed to
the normal `pam_unix` rule, and every failure (no reader, fprintd hung,
timeout) falls through to password, so finger auth can only ever *add* a
way in. Verify the wiring with
`grep pam_fprintd_grosshack /etc/pam.d/sudo`. Known cosmetic quirk: after
a fingerprint win a leftover password prompt may linger on the console.
### Doctor
`nomarchy-doctor` reports fprintd unit + enroll status when present.
## 6. NVIDIA (deep dive)
### What happens at install
```
lspci → NVIDIA ⇒ MODULE common-gpu-nvidia
```
That is the **entire** Nomarchy surface. Unfree packages are allowed
(`allowUnfree = true` in the module and in `mkFlake`), so the proprietary
path from nixos-hardware can evaluate.
There is **no** `nomarchy.hardware.nvidia.*` for:
- hybrid / PRIME (Intel+NVIDIA, AMD+NVIDIA)
- open vs closed kernel module
- power management / udev / suspend quirks
- CUDA / container toolkit packages
### What a hybrid laptop user must do today
1. Confirm `common-gpu-nvidia` (and often `common-gpu-intel` or
`common-gpu-amd`) are in `hardwareProfile`.
2. Read the relevant nixos-hardware module and [NixOS NVIDIA wiki](https://wiki.nixos.org/wiki/Nvidia).
3. Add plain NixOS options in `system.nix`, for example (illustrative —
hardware-specific):
```nix
# Example only — verify against your generation and nixos-hardware module.
# hardware.nvidia.prime = { ... };
# hardware.nvidia.powerManagement.enable = true;
# hardware.nvidia.open = false; # or true for open modules on newer cards
```
4. Rebuild the system. Home Manager does not own the driver.
### Live ISO note
The ISO lists `nouveau` among *available* initrd modules and does **not**
force-load every GPU driver (avoids multi-driver panics). Proprietary
NVIDIA on the live session is not the product focus; installed systems
use the profile.
**Product direction (shipped #59; first-class wrappers deferred for v1):**
when `common-gpu-nvidia` is in `hardwareProfile`, the installer emits a
**commented** `system.nix` block with PRIME / power / open-module pointers
(same pattern as ROCm / NPU comments). No `nomarchy.hardware.nvidia.*`
stack for v1 — hybrid PRIME remains wiki/plain NixOS until a maintainer
commits to hardware testing.
## 7. Day-2: “my laptop is mostly fine, make it fully fine”
| Goal | How | Rebuild? |
|------|-----|----------|
| Power profile (perf/balanced/saver) | System menu / Waybar | No (PPD D-Bus) |
| Charge limit 80% | Menu / CC — live sysfs + state; boot oneshot re-applies | No rebuild for live; rebuild bakes Nix option |
| Thermald (Intel) | Installer on for Intel laptops; else `power.thermal.enable` | System |
| Fingerprint enroll | `fprintd-enroll` | No |
| Fingerprint login | `fingerprint.pam = true` | System |
| ROCm / Intel compute | Uncomment opt-ins in `system.nix` | System (large) |
| NPU driver | Uncomment `npu` (+ often `latestKernel`) | System; userspace BYO |
| Newer kernel for brand-new silicon | `nomarchy.hardware.latestKernel = true` | System |
| Hide IR “dark camera” | Installer or `camera.hideIrSensor` | System |
| Firmware | `fwupdmgr update` | Reboot if capsule requires |
| Model quirks missing | Set better `hardwareProfile` (see §8) | System |
| OpenRGB / printing / Steam | `nomarchy.services.*` | System |
### Dual-sensor webcam / IR hide
Many dual-sensor modules (e.g. ThinkPad T14s) expose colour + IR as two
identically named “Integrated Camera” nodes. Picking the IR node yields a
black/dark greyscale frame — the classic “my webcam is dark” symptom.
`nomarchy.hardware.camera.hideIrSensor` (installer-on when RGB+IR names
are detected; overridable `irMatch`) drops the IR node from **WirePlumbers
v4l2 monitor** so native PipeWire pickers only offer the colour camera.
The kernel `/dev/video*` node stays open, so Howdy-style face unlock still
works. Design history: [ROADMAP § Webcam](ROADMAP.md).
**What it does not cover:** apps that list cameras via **libcamera** or
the **xdg-desktop-portal** / **Flatpak** camera path still see both
sensors — a Flatpak Zoom (or similar) user can still pick the black IR
“camera”. That is intentional: a blanket libcamera disable would risk
external USB cams that need the libcamera path, and surgical internal-only
libcamera rules could not match early enough (only `device.api` binds
before the WirePlumber monitor rule).
**Workaround:** prefer the colour device in the picker (or any non-IR
name). Apps that default to the first v4l2 colour source without a picker
are fine.
**Further engineering (needs T14s-class hardware):** (b) a WirePlumber
*libcamera* monitor rule disabling GREY-only nodes; (c) a libcamera/udev
quirk at the libcamera layer. Neither is implemented — the recommended
path is document-only until those can be verified on real dual-sensor
hardware (see `agent/HARDWARE-QUEUE.md` T14s).
Theme switches never touch drivers (Home Manager only).
## 8. Unsupported or unlisted machines
### Still good floor
Even with **no** DMI hit you usually get:
- `common-cpu-{intel,amd}`
- `common-gpu-{intel,amd,nvidia}` as applicable
- `common-pc` or `common-pc-laptop` + optional `common-pc-ssd`
- `nomarchy.hardware.intel` or `.amd` when vendor matches
- Layer A (firmware, audio, BT, PPD, fwupd)
You **lose** model-specific EC/suspend/keyboard/audio quirks that only
exist in a named nixos-hardware module.
### Pick a profile after install
1. List candidates:
```sh
nix eval github:NixOS/nixos-hardware#nixosModules \
--apply builtins.attrNames
# or: the ISO ships hardware-modules.txt for the same list
```
2. Set in your flake (installer already uses a list):
```nix
hardwareProfile = [
"common-cpu-amd"
"common-gpu-amd"
"common-pc-laptop"
"common-pc-ssd"
"lenovo-thinkpad-t14-amd-gen3" # if it matches
];
```
3. `sudo nixos-rebuild switch --flake ~/.nomarchy#default`
### Template / migration (no installer)
See [MIGRATION.md](MIGRATION.md): reuse `hardware-configuration.nix`, set
`hardwareProfile`, uncomment `nomarchy.hardware` / power in `system.nix`.
Post-install re-probe (**shipped #58**):
```sh
nomarchy-detect-hw # human report + suggested snippets
nomarchy-detect-hw --raw # MODULE / NOMARCHY / DETAIL protocol lines
```
Prints suggested `hardwareProfile` and `system.nix` lines; **does not**
rewrite the flake. Paste after review, then `sudo nixos-rebuild switch`.
## 9. Install-tested machines (hall of fame)
Models that have seen a real Nomarchy session (live ISO, install, or
day-to-day QA) — not a guarantee of every feature, just a public seed
list. **DB coverage** (hardware-db.sh) is broader; this table is the
smaller “someone actually sat at it” set.
| Model | DMI (`sys_vendor` × `product_name` / version) | Typical `hardwareProfile` | Last noted | Notes |
|-------|-----------------------------------------------|---------------------------|------------|-------|
| Lenovo ThinkPad T14s Gen 4 (AMD) | `LENOVO` × `21F8CTO1WW` / `ThinkPad T14s Gen 4` | common AMD laptop + SSD (plus `nomarchy.hardware.amd` / fingerprint / IR cam as probed) | 2026-07 | Maintainer day-to-day + HARDWARE-QUEUE (IR portal, fingerprint, NPU). Dual-sensor webcam is the motivating IR case. |
| Dell Latitude 5410 | Dell Latitude 5410 (Intel) | common Intel laptop + SSD (+ GuC when enabled) | 2026-07 | Primary Intel hardware-QA host (session, themes, polkit, bar). |
| Dell Latitude 5310 | Dell Latitude 5310 (Intel) | same family as 5410 | 2026-07 | Charge-limit / power QA sibling (see HARDWARE-QUEUE). |
### Send your DMI line
If you install Nomarchy on a machine and it works (or fails in an
interesting way), open a PR that:
1. Adds a row to the table above (model, DMI, profile, date, short notes).
2. Optionally adds a `HARDWARE_DB` line in
`pkgs/nomarchy-install/hardware-db.sh` when nixos-hardware has a
matching module (§10).
Quick DMI grab:
```sh
printf '%s | %s | %s\n' \
"$(cat /sys/class/dmi/id/sys_vendor)" \
"$(cat /sys/class/dmi/id/product_name)" \
"$(cat /sys/class/dmi/id/product_version)"
nomarchy-detect-hw # suggested MODULE / NOMARCHY lines
```
## 10. Adding your model to the distro
For contributors (and power users who will PR):
1. On the machine:
```sh
cat /sys/class/dmi/id/sys_vendor
cat /sys/class/dmi/id/product_name
```
2. Find a matching attr in
[nixos-hardware](https://github.com/NixOS/nixos-hardware) (or add one
upstream first).
3. Append to `pkgs/nomarchy-install/hardware-db.sh` in `HARDWARE_DB`:
```bash
"VendorRegex|Product regex|nixos-hardware-module-name"
```
First match wins — put specific lines above broad fallbacks.
4. Verify the name exists in the **pinned** nixos-hardware input
(`mkFlake` will throw if not). A CI check that every DB name ∈
`nixosModules` is queued so lock bumps cannot silently break installs.
5. Optional: note on-hardware QA steps in `agent/HARDWARE-QUEUE.md`.
Install-tested status goes in the hall-of-fame table (§9).
## 11. Doctor and hardware health (current vs target)
**Today** (`nomarchy-doctor`): failed units, disk space, theme-state
validity/git, generation age, snapper; hardware section self-gates per
machine (NetworkManager, audio sink, GPU smoke, fprintd, fwupd, charge
limit, battery health, hibernate/zram). All read-only; each ✖ prints one
fix command.
| Check | Pass condition | Suggested fix line |
|-------|----------------|--------------------|
| NetworkManager | device connected or wifi radio on | open System Network |
| Audio sink | default sink exists | System Audio |
| GPU accel | `glxinfo`/`vainfo` smoke (if installed) | check `hardwareProfile` / drivers |
| Fingerprint | if USB VID matched / fprintd unit | `fprintd-enroll` or enable option |
| fwupd | daemon active; optional “updates pending” warn | `fwupdmgr get-updates` |
| Battery threshold | if laptop + limit set, sysfs reports it | power docs / restart charge-limit unit |
| Battery health | cycle_count and/or charge\|energy_full÷design % when sysfs exports them | report-only (warn if &lt;70% of design) |
| First-boot pre-activate | installer log present + no HM generation | `home-manager switch --flake ~/.nomarchy -b bak` |
| Hibernate / zram | disk swap + resume=; zram active | docs/MIGRATION.md → Enabling hibernation |
## 12. Option quick reference
Full tables: [README § options](../README.md). Hardware-shaped surface:
| Option | Role |
|--------|------|
| `mkFlake.hardwareProfile` | nixos-hardware name or list |
| `nomarchy.hardware.intel.enable` / `.guc` / `.computeRuntime` | Intel gap layer |
| `nomarchy.hardware.amd.enable` / `.pstate` / `.vaapi` / `.rocm.*` | AMD gap layer |
| `nomarchy.hardware.fingerprint.enable` / `.pam` / `.parallel` | fprintd + PAM (parallel password-or-finger prompt by default) |
| `nomarchy.hardware.npu.enable` | in-kernel NPU only |
| `nomarchy.hardware.latestKernel` | `linuxPackages_latest` |
| `nomarchy.hardware.camera.hideIrSensor` / `.irMatch` | dual-sensor webcams (v4l2 only; §7) |
| `nomarchy.hardware.i2c.enable` / `.ddcci` | I2C + external backlight |
| `nomarchy.system.power.*` | PPD/TLP, laptop, thermald, charge limit |
| `nomarchy.system.bluetooth.enable` | BT stack |
| `services.fwupd.enable` | LVFS (native NixOS, default on) |
## 13. Ease summary
| Situation | Effort |
|-----------|--------|
| Known model in DB (Framework, many ThinkPads, …) | Low — install and go |
| Unknown modern Intel/AMD laptop | Lowmedium — commons cover a lot |
| Firmware updates | Medium — CLI only until product work lands |
| Fingerprint for login | Medium — enroll CLI + PAM uncomment |
| Hybrid NVIDIA | High — plain NixOS/wiki territory |
| ROCm / NPU userspace | High — opt-in + expert |
| Contribute a new DMI line | Medium for someone who can PR |
## 14. Related files
| Path | Role |
|------|------|
| `modules/nixos/hardware.nix` | `nomarchy.hardware.*` |
| `modules/nixos/power.nix` | PPD/TLP, charge limit, thermald |
| `modules/nixos/default.nix` | firmware, fwupd, ddcci default |
| `pkgs/nomarchy-install/hardware-db.sh` | DMI DB + probes |
| `pkgs/nomarchy-install/nomarchy-install.sh` | writes flake + system.nix |
| `lib.nix` | `hardwareProfile` resolution |
| `templates/downstream/system.nix` | commented opt-ins |
| `agent/HARDWARE-QUEUE.md` | on-machine V3 checks |