Extend checks.doctor: the bare test VM lacks every probe tool, so the healthy nomarchy-doctor run drives all six hardware checks in skip mode. Assert the self-gated skip rows appear (NetworkManager, fingerprint, fwupd, VA-API) and the sheet still exits 0 — proving the section runs without erroring under set -euo pipefail. No node changes. Verified V2: nix build .#checks.x86_64-linux.doctor passes. Closes #44. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
33 KiB
Backlog — the prioritized task queue
This is the only executable work list for agents. Product themes and
v1.0 intent live in docs/VISION.md; design history
in docs/ROADMAP.md; map in
docs/README.md and agent/README.md.
Rules:
- Agents take the topmost actionable item (see LOOP.md). Finished items are deleted here — the journal + git log are the record; durable design notes get a ✓-entry in docs/ROADMAP.md (and/or a note in VISION) if worth keeping.
- Item numbers are stable IDs — never renumbered or reused. A gap in the sequence means shipped (or dropped) work; new items take the next free number regardless of tier.
- Tags:
[blocked:hw]needs real hardware (see HARDWARE-QUEUE.md) ·[human]needs Bernardo ·[stuck]two failed attempts, needs help ·[big]must be split before starting. - Agents may append to PROPOSED and Decisions freely (include
VISION § …orROADMAP § …when relevant); only Bernardo moves items out of PROPOSED into the tiers.
NOW
(empty — NEXT's top item is the queue head)
NEXT
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:
- 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.
- V3 — real LVFS flash + reboot note on hardware → HARDWARE-QUEUE (entry added).
- 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.
14. Automated lock bumps — confirm the first real run
Slices b+c shipped 2026-07-05 (.gitea/workflows/bump.yml): weekly
schedule (Mon 05:17 UTC) + workflow_dispatch as the security
fast-lane; nix flake update → eval gate → pathspec-limited lock
commit pushed to main on green (that push triggers check.yml as the
second net). Update/commit/push logic simulated locally end-to-end in
a scratch clone, incl. a real update; today's bumped lock evals green.
Remaining (not confirmable from a session): the first scheduled or
dispatched run must land — watch that the runner picks up the cron and
that the Actions token can push. Then delete this item. Item 20's KVM
runner later upgrades the gate from eval-only to the VM suite.
20. KVM runner → VM suite in CI [human]
The remaining stretch of the CI item — checks-on-push is live and
green (run #58; runner = gitea/act_runner docker, eval tier).
Register a second runner on a host with /dev/kvm + nix (host-mode
label nix-kvm), then an agent uncomments the workflow's vm-checks
job: the checks.* VM suite + real toplevel/HM builds on every push
that later upgrades item 14's bump gate from eval-only to the full suite.
33. rofi page-overflow hint (scrollbar)
(Raised by Bernardo, 2026-07-07 — item 3.) When a list/grid overflows
onto another page, nothing signals there's more below. Add a scrollbar
(rofi's scrollbar element) or a "more ↓" hint, themed to the palette,
on the launcher grid and the long text menus. Check rofi 2.0.0's
scrollbar support/theming.
Scoped 2026-07-07: rofi only draws the scrollbar when the list actually
overflows (lines < rows), so enabling it self-hides on short menus —
the right primitive. But it's a visual, ~10-file slice: the generated
palette theme (rofi.nix, scrollbar = false) plus every authored
.rasi (boreal/nord/lumon/kanagawa/retro-82/neon-glass/executive-slate/
summer-day/summer-night) — all deliberately set scrollbar { width:0 }
today, each needs a per-theme handle width/colour. Payoff is V3-only
(rendering), so it wants a themed session, not a headless edit.
41. Floating-window audit — remaining (needs hardware class checks)
(Raised by Bernardo, 2026-07-07 — item 11.) Broaden the windowrule
float set beyond the conservative first cut.
Conservative cut shipped 2026-07-07 (iteration #63, on Bernardo's "take a
conservative approach"): float + center the mixer (item 35), blueman
(manager/adapters) and system-config-printer — the only shipped,
unambiguous config dialogs whose classes are confident. Remaining
candidates, deliberately deferred because their window class can't be
verified headlessly (a guessed class = dead rule): the polkit auth
prompt (hyprpolkitagent — no discoverable class in the package), GTK
file-chooser portals (xdg-desktop-portal-gtk), and any pinentry dialog.
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).
51. Waybar/menu behaviour bugs — V2 render pending
Fixes shipped V1 (2026-07-09): doctor indicator emits + class:bad
when unhealthy (was empty text → self-hidden); CC appearance toggles print
"(requires rebuild)"; summer-day scroll e±1→r±1. Remaining V2: a
theme-shot render with an induced doctor failure to see the glyph (fold into
#44's checks.doctor extension); CC message + scroll are behavioural (V1
- self-evident).
52. Theme fidelity bugs — btop V2 render pending
Six per-theme defects fixed 2026-07-09 (rose-pine btop→Dawn; everforest +
summer-night btop inactive_fg; vantablack role inversion; osaka-jade
text/subtext + warn; catppuccin-latte mantle/accentAlt/ANSI; catppuccin
Mocha btop). JSON fixes V0-verified (check-theme-contrast 24×7 all
pass — accentAlt retuned to Latte mauve #8839ef, not the audit's pink
#ea76cb which fails the 3.0 floor). Remaining V2: a theme-shot render
of the btop-changed themes (rose-pine, everforest, summer-night, vantablack,
catppuccin) — btop.theme isn't contrast-checked.
54. Installer safety + polish — V2 scenarios pending
Four guards shipped 2026-07-09 (V0/V1: bash -n, flake check, nomarchy-install
builds): offline compose-lock failure now fail-closes instead of a network
flake lock; disk-review warn when the target shows Windows/BitLocker/NTFS/
LUKS; account password min 8 (mirrors LUKS); HM pre-activate failure drops a
NOMARCHY-DESKTOP-NOT-THEMED.txt hint on the target home. Remaining V2
(need crafted install scenarios): offline install actually failing closed; an
NTFS/BitLocker disk firing the warning; the pre-activate hint landing on a
booted target. (Password ≥8 is V0-complete.)
LATER
- Wallpapers artifact split (ROADMAP § Faster switches — decided,
deferred): pinned
Nomarchy-wallpapersinput so a state write stops re-copying 86 MB. Follow-on: pre-built theme variants if switches are still slow after. - Installer round 2 (ROADMAP § Installer): multi-disk BTRFS RAID, impermanence, BIOS/legacy boot.
- Boot-from-snapshot: a systemd-boot equivalent of grub-btrfs.
- Night-light geo mode: lat/long auto sunset/sunrise (means wlsunset).
- Per-theme icon overrides / more icon packs (ROADMAP § Icon themes).
- MIPI/IPU software-ISP camera support (no-UVC machines).
- VPN exit-node richer display (country/city) (optional).
- NixOS release bump → v2
[human]: deliberate, hand-edited, never automated; the previous attempt was discarded (2026-06-22) over a Hyprland OOM blocker — see MEMORY.md before retrying (NOW#3 should also soften that blocker class).
PROPOSED (agent suggestions — await human triage)
Agents: append here with a one-paragraph pitch (what/why/cost). Do not implement. Bernardo moves accepted items into a tier.
v1.0 track — see docs/VISION.md
Product themes and the release bar live in VISION. Shipped 2026-07-09: #42 boreal default (V2-verified) · #43 Firmware menu (V1, V2 pending) · #44 doctor hardware (V1 + hw smoke, V2 pending). Remaining candidate promotions: fingerprint menu · first-boot tips · human rebuild errors · neon-glass quarantine.
Pre-existing
-
Battery charge-limit — make the toggle instant
[blocked:hw](follow-up to the preset toggle shipped 2026-07-07, iteration #55). The control-center now has a proper toggle (Off / 80% / 90% / 60% / Custom…) writingsettings.power.batteryChargeLimit— but that's a baked NixOS option, so it only lands on the nextsys-rebuild. To make it instant (no rebuild): add a udev rule making/sys/class/power_supply/BAT*/charge_control_end_thresholdgroup-writable (MODE/GROUP) so the menu canecho N >it live alongside persisting state (the sysfs oneshot in power.nix still owns boot + AC-replug re-apply), and/or surface a rofi-menu quick row or a Waybar action.[blocked:hw]: the sysfs write + no-rebuild effect can only be confirmed on a laptop exposing the threshold. Decide first whether the small privilege grant (a local user can set the charge cap) is acceptable. -
Portal/Flatpak camera picker still lists the internal IR sensor (ROADMAP § Webcam follow-up). The shipped IR-hide is a WirePlumber v4l2 rule, but Flatpak/portal apps consume cameras via the libcamera path, where both sensors remain visible — a Flatpak Zoom user can still pick the black IR "camera". Options, roughly ascending cost: (a) do nothing — document it (portal camera support is still rare in practice); (b) a WirePlumber libcamera monitor rule disabling GREY-only nodes — needs verifying that libcamera monitor rules can match early enough (the v4l2 investigation found only
device.apibinds pre-rule, which is why surgical scoping failed before — same wall likely applies); (c) a libcamera configuration/udev quirk hiding the IR sensor at the libcamera layer itself. Cost: (b)/(c) need a T14s-style RGB+IR machine to verify → pairs with a hardware-queue session. Recommend (a) now, (b) investigated when the T14s is next available.
Bugs / broken behavior (codebase exam 2026-07-09)
(Waybar doctor indicator, Control Center appearance no-ops, summer-day
scroll → #51; neon-glass broken waybar → fixed 2026-07-09 by quarantine
(removed waybar.css → generated bar; render-confirmed).)
- Battery charge-limit / powerprofile only match
BAT*sysfs namespower.nixoneshot and menu/waybar globs use/sys/class/power_supply/BAT*.nomarchy-battery-notifycorrectly treats any system battery (type=Battery, notscope=Device). Machines withCMB0(and similar) get notify but not charge-cap / inconsistent gating. Fix: name-agnostic scan aligned with battery-notify. Cost: small multi-file;[blocked:hw]to confirm on non-BAT* hardware.
Docs / option-surface drift (codebase exam 2026-07-09)
(i2c option-docs → #48; README/docs drift pack, keybind nmtui label, nomarchy-menu usage string, secondary docs, always-on pieces → #47.)
-
Template / seed state drift (residual after SoT work) (1)
templates/downstream/theme-state.jsonlacksborderandsettingskeys present in repo root state (eval merges defaults); (2) no commentednomarchy.system.snapper.enableorhardware.i2c.*in templatesystem.nixdespite opt-in convention. Main home/system sync is Installer consumes template as SoT below — do that first, then close these residual gaps on the template itself. Cost: small template polish. -
Installer ↔ template SoT — follow-ups (shipped 2026-07-09: copy +
patch-template.py). Remaining: (1) optional CI that the install share ships the same template files; (2) V2test-install.shafter ISO rebuild (HM pre-activate now pulls starter packages — larger closure); (3) residual theme-state / i2c comment polish on template (see residual seed drift item).
Theme polish / completeness (codebase exam 2026-07-09)
-
theme preview recapture nicety (all 24 themes now have
preview.pngas of 2026-07-09 — executive-slate + neon-glass captured via theme-shot). These headless captures are a clean bare desktop+bar, not the theme-shot capture — a clean bare desktop+bar, not the floating-terminal (fastfetch+btop) composition the other 21 use; a real-hardware recapture to match the grid would be nicer (VM is the documented fallback). Optional handbtop.themefor the three identity themes still open. Cost: asset capture; V3 visual. -
Generated Waybar missing identity-bar affordances Whole-swap bars ship
custom/powermenuand a left logo → main menu; the generatedwaybar.nixbar has neither. Optional parity add for default-theme users. Cost: small waybar.nix + CSS; parity rule says whole-swaps must get the same modules if added. -
summer- CSS under-styles status module states* summer-day/night include modules in selectors but largely lack
.on/.available/.recordingpolish that boreal, executive-slate, and the generated style have. Functional OK; visual hierarchy weak. Cost: CSS pass; V3. -
Optional CI: whole-swap CSS self-containment Contrast check does not require that a
waybar.cssdefines every@colorit references, nor that every preset has preview + backgrounds. A cheap gate would have caught neon-glass. Cost: small tool + flake check.
Per-theme design audit (2026-07-09)
Method: checks.theme-contrast (all 24×7 pairings pass) +
tools/audit-theme-design.py + per-theme agent review of JSON roles,
ANSI, assets, whole-swaps, and fidelity to canonical sources. Gated
WCAG floors are green; items below are fidelity, hierarchy, btop
drift, identity semantics, and polish. Identity themes (white,
vantablack, lumon, hackerman, matte-black, miasma, neon-glass) are
flagged separately from fidelity bugs.
Broken / high-ROI fixes
→ promoted as NEXT #52 (2026-07-09); the six bullets below are its spec (exact hexes). The rest of the per-theme audit stays PROPOSED.
Residual ANSI drift exposed by the #52 fixes (not yet touched — small
follow-up): vantablack ansi[8] (bright-black) still #fdfdfd, now
diverging from the new muted #666666; osaka-jade ansi[3]
(normal-yellow) still the old warn-green #459451 while warn/ansi[11]
are now #E5C736. Decide per theme whether these are identity or bugs.
-
rose-pine btop is Main-on-Dawn (near-invisible hi_fg) JSON is Rosé Pine Dawn (
mode: light, base#faf4ed, text#575279) butthemes/rose-pine/btop.thememixes Dawnmain_bg/main_fgwith Main accents:hi_fg=#e0def4on#faf4ed≈ invisible,selected_bg=#524f67, love#eb6f92, foam/iris Main hexes. Fix: rewrite btop entirely to Dawn roles (foam#56949f, iris#907aa9, love#b4637a, gold#ea9d34/#d68a16, pine#286983). Also rename display name to "Rosé Pine Dawn" (or ship a dark Main preset as a separate slug). Cost: one btop rewrite + optional rename; V1 + visual V2. -
everforest + summer-night btop: inactive_fg == main_bg
themes/everforest/btop.themeandthemes/summer-night/btop.themesetinactive_fgto#2d353b(=main_bg) → inactive/disabled labels invisible. Fix:inactive_fg→ grey1/muted range (#859289/#7a8478/ JSON muted). Cost: two lines; V1. -
vantablack role inversion breaks selection / muted
overlayandmutedare near-white#fdfdfdwhile base is#0d0d0d. Generated consumers useoverlayas selected_bg; hand btop hasselected_bg=#fdfdfd+selected_fg=#ffffff(white-on-white) andinactive_fg=#fdfdfd(inactive rows scream). Status greys are intentional monochrome identity. Fix (keep void identity):surface #1a1a1a,overlay #2a2a2a,muted #666666; btopselected_bg #333/selected_fg #fff/inactive_fg≈ muted. Cost: JSON + btop; re-run contrast; V1–V2. -
osaka-jade: warn≈good and text/subtext inverted
warn #459451is green (same family asgood #549e6a) → battery warning reads as "ok".subtext #F6F5DDis brighter thantext #C1C497(secondary louder than primary). Fix: swap text↔subtext; setwarn #E5C736(from bright yellow ANSI, already in palette). Keep jade accent + blossom accentAlt. Cost: small JSON retune; contrast re-check; V1. -
catppuccin-latte: ANSI black/white axis inverted + mantle sludge Latte UI roles mostly match (base/text/accent/good/bad exact), but
ansi[0]=#bcc0cc(light) andansi[7]/[15]are darkish → terminal "black"/"white" slots misbehave; design-audit flags inverted slots.mantle #cbcdd0is import-darken of light base (should be Latte mantle#e6e9ef);accentAlt #d260b5is not Latte pink/mauve. Fix:mantle #e6e9ef; accentAlt #ea76cb (pink); ansi[0] #5c5f77; ansi[7] #acb0be; ansi[8] #6c6f85; ansi[15] #bcc0ccwarn keep
#d6860aif contrast requires, else#df8e1d. Cost: JSON only; btop already Latte-correct. V0 contrast + V1. -
catppuccin (Mocha) btop is Frappé-on-Mocha JSON is exact Mocha;
btop.themeuses Mochamain_bgbut Frappé fgs/boxes (main_fg #c6d0f5,hi_fg #8caaee, mauve/green/maroon Frappé hexes). Fix: replace with official Mocha btop hexes (#cdd6f4,#89b4fa, …). Optional: rename to "Catppuccin Mocha". Cost: btop rewrite; V1.
Whole-swap / identity themes
-
neon-glass — already queued above (broken waybar.css). JSON palette itself is fine (high-chroma cyber). Finish or quarantine.
-
summer-day / summer-night pair polish Structurally paired (inverted Everforest bar language) but: (1) waybar CSS hexes drift from JSON (day warn/accentAlt; night red/blue/yellow/purple vs JSON); bar follows legacy EF source, Stylix/swaync follow JSON — dual sources of truth; (2) night JSON collapses
subtext=muted=overlay#868d80(no secondary ladder for generated surfaces); (3) day font 16px vs night 13px; day battery thresholds 30/15 vs night 25/10; day missing#custom-vpnin pill selectors; (4) day scrolle±1already queued. Fix: pick JSON as source of truth and map waybar tokens to it (or document intentional EF split); split night muted darker / subtext lighter; align font + battery thresholds + VPN pill. Cost: CSS/JSON polish pass; V3. -
boreal / executive-slate — whole-swaps self-define colors and match JSON; best-in-class. Only gaps:
preview.png+ optionalbtop.theme(already queued). -
white (monochrome light) — identity-ok. Status good/warn/bad are greys by design (audit hue/CVD noise expected). Optional: widen L steps (
good #555,warn #777,bad #222), raisesurface #f0f0f0, splitsubtext #404040while staying hueless. Do not inject traffic-light hues. Cost: optional taste retune. -
lumon (Severance blue mono-status) — identity-ok. good/warn/bad all blue family by design; CVD collapse expected — rely on glyph/shape (item 28). Optional: dim
subtextone step (#9bb0c0); increase L separation only among blues. Cost: optional; document as identity exemption in audit tooling. -
hackerman — matrix identity: warn cyan, bad green, ANSI reds are greens. CVD collapse expected. Keep identity or optional cyber-semantic UI only:
warn #e8d44f,bad #ff5a7awhile leaving ANSI matrix. Raisesurface #1a1c2e(flat base=surface). Cost: product call + small JSON. -
matte-black — identity:
good=#FFC107amber,warn=#b91c1cred (inverted traffic-light). Matches Omarchy matte-black. Minimal fix:subtext #9a9a9d(text==subtext today). Full semantic remap only if product wants conventional battery colors on this theme. Cost: one-line hierarchy or deliberate status retune. -
miasma — earthy
bad #685742(brown, contrast ~2.3 audit-only) is JOURNAL-exempt identity. Optional more readable brown-red#8b5a4a/#a65d4ewithout leaving the forest. Cost: optional.
Fidelity / hierarchy polish (popular ports)
-
gruvbox is Material medium, not classic — name + btop split JSON hexes are Gruvbox Material (
text #d4be98, material green/yellow/red) while name says "Gruvbox" andbtop.themeis classic (#ebdbb2,#d79921, …).surface=overlay,text=subtext. Fix: rename to "Gruvbox Material" or retune JSON to classic; sync btop to the chosen lineage;overlay #504945,subtext #a89984. Cost: naming + assets. -
nord — clean Polar Night. Only nit:
subtext #e5e9f0is brighter thantext #d8dee9(hierarchy inverted). Fix: subtext → nord4-dim or bump text to nord6#eceff4. Cost: one hex. -
tokyo-night — Night (not Storm), JSON solid. btop
main_fg/titleuse warm#cfc9c2instead of Night#c0caf5/#a9b1d6. Optional:text #c0caf5,accentAlt #bb9af7(modern purple). Cost: btop + optional JSON. -
kanagawa — Wave, clean. No action required; optional rename "Kanagawa Wave"; optional brighter good
springGreen #98bb6c. -
ethereal — vibe solid;
surface=base,muted=overlay. Fix:surface #1a2340(or Omarchy color0#3C486D); split muted darker than overlay; optional richer good. Cost: small JSON. -
retro-82 — strong synthwave + excellent rofi whole-swap.
surface #00172edarker thanbase #05182e(inverted raise);good #028391teal (reads info not ok). Fix:surface #0a2844; optionalgood #3f8f8aor phosphor green. Cost: small JSON; keep rofi. -
ristretto — Monokai Pro Ristretto, ship-quality. Only
subtext=text; btopmain_bg1-step drift (#2c2421vs#2c2525). Fix:subtext #b5a9aa; align btop bg. Cost: tiny. -
flexoki-light — best of the Flexoki/import set post item-28. Optional: distinct ANSI bright-black
#575653; recapture preview if terminal chrome still looks dark-on-paper. Cost: polish only.
Systemic theme tooling
-
Import pipeline collapses hierarchy when ANSI 0==8
tools/import-palettes.pymapssurface←color0,overlay←color8,good/warn/bad←color2/3/1,mantle←darken(base). When color0==8 (gruvbox, everforest) surface=overlay; light themes get sludge mantle. Long-term: allow explicit role overrides independent of ANSI for identity themes; don't re-import without a hierarchy pass. Cost: tool + convention doc. -
audit-theme-design identity exemptions Document expected noise for white/vantablack/lumon/hackerman/ matte-black/miasma (hue-family + CVD) so future audits don't "fix" identity into traffic lights. Optional: special-case in the report script. Cost: docs or small script tweak.
Tooling / CI / installer hardening (codebase exam 2026-07-09)
(py_compile expand, installer pure contracts, hardware-db ∈ nixos-hardware, windowrule dead-syntax guard → #49.)
- Installer soft gaps
(1) fingerprint path prefers
lsusbbut package PATH haspciutilsnotusbutils(sysfs fallback usually OK); (2)chown -R 1000:100on the flake dir assumes first-user UID/GID; (3) flakepackagesexports only theme-sync + install, not doctor / control-center / battery-notify (runtime via overlay is fine — discoverability only). Cost: small each.
(Control Center /tmp/nomarchy-gens → mktemp → #50.)
Distro improvement ideas (codebase exam 2026-07-09)
-
Fail-closed / friendlier theme-state errors in
mkFlakeMissingtheme-state.jsonfails later atreadFile; invalid JSON fails atfromJSONbefore theme.nix's field-level validator. A friendly "add theme-state.json" / schema pointer would help downstream authors. Related:settings.displayProfile*not in defaults block (consumers useor); unknown border role falls through to raw string. Cost: medium lib/theme.nix UX. -
Look & Feel submenu (ROADMAP optional) Night-light, wallpaper cycle, blur/gaps (once CC appearance is fixed) grouped with Theme once the root stays six entries. Cost: menu structure only; product call.
(Export overlay tools as flake packages → #50.)
- Unattended-install test matrix
test-install.shalways LUKS+swap; add (or document) no-swap and no-LUKS paths once those contracts are fixed, so swap/LUKS-class bugs cannot recur. Cost: script flags + time on KVM host.
(Document always-on home pieces (easyeffects/udiskie/cliphist) → #47.)
Hardware product (investigation 2026-07-09)
Full write-up: docs/HARDWARE.md. Install-time
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-hwCLI (post-install re-probe) The installer already has purenomarchy_detect_hwstdout protocol (MODULE / NOMARCHY / DETAIL). Ship it as a package on PATH that prints suggestedhardwareProfile = [ … ]andsystem.nixsnippets without reinstalling — closes the template/migration gap and “I swapped the Wi‑Fi card.” Does not rewrite the flake unless a later--applyis explicitly designed. Spec: docs/HARDWARE.md §8. Cost: extract script + package + man/README pointer; V0–V1. -
Fingerprint menu: enroll / list (+ optional PAM toggle) Installer enables fprintd on known USB VIDs but enroll is CLI-only (
fprintd-enroll) and PAM is a commented rebuild. Self-gated System row whenfprintdis present: enroll, list, delete; optional “use for login” that writessettings/system intent + rebuild note (Control Center Bluetooth pattern). Spec: docs/HARDWARE.md §5. Cost: menu module; V3 enroll on real reader ([blocked:hw]for full path). -
Installer: NVIDIA commented system.nix guidance Detection already adds
common-gpu-nvidia; there is nonomarchy.hardware.nvidia.*and hybrid/PRIME is wiki territory. When NVIDIA is detected, emit a commented block in generatedsystem.nix(same style as ROCm/NPU) pointing at PRIME / powerManagement / open-module and docs/HARDWARE.md §6 — not a full second stack. Cost: install script strings; V0 + doc.
(hardware-db ∈ nixos-hardware → #49; usbutils on install PATH → #50; i2c README table → #48.)
-
Post-install hardware hints (MOTD / first session) When relevant services exist, surface one line each: firmware (
fwupdmgr get-updates), fingerprint (fprintd-enroll), optional “run nomarchy-doctor”. Avoid nagging — once or until dismissed. Spec: HARDWARE.md §4/§5. Cost: small greeter/MOTD or notify; V2/V3. -
NVIDIA first-class options (larger, optional) Only if a maintainer commits to hybrid testing: thin
nomarchy.hardware.nvidia.*wrapping common PRIME/power patterns. Prefer the commented-guidance item first; promote only with hardware-queue coverage. Cost: high;[big]+[blocked:hw].
Installer process (audit 2026-07-09)
Full-path review of live ISO → nomarchy-install → disko → config
generation → offline/online nixos-install → HM pre-activate → first
boot. Philosophy applied: opinionated, stability-first — prefer safer
defaults and fewer install questions over option sprawl. Day-2 firmware /
fingerprint / re-detect stay in Hardware product above, not in the
installer questionnaire.
Already strong (do not “fix” with more choices)
- Single whole-disk GPT, UEFI + systemd-boot only; multi-disk RAID / dual-boot / BIOS deferred (ROADMAP LATER).
- LUKS2 default + greeter auto-login (one gate); type-to-confirm wipe; live medium excluded from disk list; careful pre-wipe.
- BTRFS subvols + snapper on by default; hibernation swap default = RAM; hardware autodetection with safe defaults on, heavy bits commented.
- Offline-capable install (compose-lock, ISO store pin, daemon substituter); HM pre-activate so first boot is themed.
- No Secure Boot theater; no install-time app-suite wizard / custom
partitioner / pbkdf knobs. (Starter apps come from the template
home.packagesonce the installer consumes the template as SoT — see above; not a separate install questionnaire.) - Live: no idle suspend (avoids mid-install sleep); WiFi via normal desktop NM path.
Bugs (stability contracts — fix, don’t optionalize)
- Installer swap=0 + unattended LUKS fail-closed — ✓ shipped
(workflow test run 2026-07-09): pass bare
"0"; disko accepts"0"/"0G"; unattended needs passphrase orNOMARCHY_NO_LUKS=1.
(Offline fail-closed → #54.)
Safety / clarity (one line each — no new install menus)
(Review-panel destructive-data warning → #54.)
- Review panel: offline vs online source line
Review always implies “no network needed” even when the online path
(skip full store copy, use substituters) is active. Make the Source
line conditional on the same
cache.nixos.orgprobe so expectations match. Cost: tiny; V0.
(User password minimum length = 8 → #54.)
Live ISO discoverability (one durable cue)
- Live: one always-visible “Install Nomarchy” action
Install is only in: 3s notify-send toast, getty helpLine, and
tribal knowledge of
nomarchy-install. No desktop entry / menu row. One durable surface on the live host only: e.g.xdg.desktopEntries(Terminal=true) or a single Tools/System menu item that opens a terminal intonomarchy-install. Prefer that over more install-time questions or a second installer UI. Also fix stalehosts/live.nixheader (“No installer yet” — already in docs drift pack). Cost: live.nix only; V1 ISO rebuild + V2 smoke.
Generated config / post-install polish
(HM pre-activate failure → durable recovery hint → #54.)
- MIGRATION.md: installer snapshot layout vs
@home-snapshotsInstaller creates disko@snapshots→/.snapshotsand a first-boot oneshot for nested/home/.snapshots. MIGRATION still speaks of top-level@home-snapshots(TuringMachine vocabulary). One paragraph clarifying installer layout vs migration machines prevents wrong expectations. Cost: docs only.
Test / pure contracts (after P0 bugs)
- Installer pure checks + expanded unattended matrix — overlaps
existing Tooling items (disko
swapSizecontract, compose-lock py_compile, hardware-db ∈ nixos-hardware). After swap/LUKS fixes: document or script unattended no-swap and explicit no-LUKS paths intest-install.sh(env flags only — no interactive options). Do not grow the interactive installer questionnaire.
Explicit non-goals for the installer (defer)
Do not add install-time: dual-boot / preserve partitions, multi-disk RAID, Secure Boot/lanzaboote, recovery-key wizard (optional silent recovery print is the only recovery-key idea worth considering later), custom partitioner, online/offline user toggle, app suite selection, pbkdf/TRIM knobs, or a second installer frontend. Stability and the single golden path win.
Decisions [human]
Open calls only Bernardo can make; agents add options/evidence but never decide.
-
Formatter adoption: repo deliberately has none;
nixfmt-rfc-stylewould flatten the aligned hand-formatting of ~33 files. Adopt or declare never? -
Docs site vs Markdown-in-repo (from the docs-review item).
-
zram swap: faster under pressure and pairs with NOW#3, but it interacts with the hibernation-swapfile story (resume device/priority ordering) — adopt, adopt-with-hibernation-guard, or skip?
-
Default browser: the template comments Firefox out. The shipped mime defaults (item 8, done) point
text/html/http(s) atfirefox.desktopas inert entries — they activate the moment Firefox is installed and are skipped otherwise, so the remaining call is only: ship a browser active in the suite, or stay browserless-by-default? -
Default power backend — PPD vs TLP: (raised by Bernardo 2026-07-08: would TLP be more power-efficient, and should it be the default?) TLP does get more idle battery life, but only from device-level knobs PPD deliberately omits — PCIe ASPM, disk/NVMe link PM, USB autosuspend, runtime PM — which are the same knobs behind NVMe/USB flakiness that pillar 1 (rock-stable, never fight your machine) guards against. Evidence (2026-07-08): no credible hard-watt benchmarks exist — TLP's own maintainer declines to quote any ("measure on your hardware") and says PPD's power-saver gives similar savings under load; TLP's edge is idle-only (linrunner.de/tlp/faq/ppd.html — PPD covers a subset of TLP, "no settings to reduce consumption when the CPU is idle"). Our sibling distro Omarchy ran this exact experiment — a "replace Power Profiles with TLP for battery" guide — and the author reverted to PPD ("more headaches and weird issues"); Omarchy shipped PPD auto-switching instead (basecamp/omarchy#3907). PPD 3.4.0 now does AC/battery auto-switching, closing part of TLP's UX gap. Cost of TLP-default: TLP has no live D-Bus profile API, so the
powermgmtmenu + Waybar profile indicator + low-battery auto power-saver (allpowerprofilesctl) would need a rework — it's not a one-line backend swap. Agent rec (evidence, not a decision): keep PPD default; chase battery via targeted low-risk tweaks (PCIe ASPM policy, battery-side EPP, the charge start threshold, PPD auto-switching) and keep TLP the documented one-line opt-in it already is (nomarchy.system.power.backend = "tlp"). Options: (i) status quo + targeted tweaks [rec]; (ii) TLP default (reworks the profile UX); (iii) nothing.