Files
Nomarchy/docs/ROADMAP.md
Bernardo Magri 8dc6ba0a21
All checks were successful
Check / eval-and-lint (push) Successful in 6m38s
docs: mark App Integration Polish as complete
2026-05-31 20:59:26 +01:00

89 KiB
Raw Blame History

Nomarchy Roadmap

This is the mid-term plan for Nomarchy. It exists so future sessions — human or agent — can pick up work without re-deriving context. Items move from NowNextLater as priorities shift, and from any column into Shipped at the bottom when done. There are no dates: ship-when-ready.

If you're new here, also read docs/STRUCTURE.md and docs/OPTIONS.md. Existing-NixOS users should also read docs/MIGRATION.md.

1. Vision & guardrails

Nomarchy is a NixOS-based distribution that gives you a polished Hyprland desktop (Hyprland + waybar + walker + a curated theming engine) on a strictly declarative, flake-based foundation. Goal: power-user polish without giving up reproducibility.

Guardrails (apply when adding anything):

  • Declarative-first. No imperative state in core/. Anything mutable lives in ~/.config/nomarchy/state.json or in NixOS options.
  • Downstream-flake friendly. Every behavior toggle is a nomarchy.* option documented in docs/OPTIONS.md. Adding a feature without a corresponding option is a bug.
  • Opt-in by default. New features default off (or default to the existing behavior). The installer can flip defaults for the user, but the option must read sensibly when set by hand.
  • Reuse before invent. Before adding a script, grep core/system/scripts/, features/scripts/utils/, and themes/engine/scripts/ — there are ~155 of them, and many of the things you want already exist.

2. Now / Next / Later board

Now (ready to pick up)

  • Deep Runtime Polish: Interactive Script Audit (Round 2). Run complex nomarchy-* commands inside a real Alacritty window in the VM. Identify and fix failures caused by TTY expectations, $TERM mismatches, or gum layout issues on specific themes.
  • Deep Runtime Polish: State-Sync Stress Test. Verify the robustness of the hybrid declarative state system (nomarchy-state.nix). Run automated "chaos" cycles (rapid theme/font/scaling changes) to catch race conditions or Nix generation errors.
  • Deep Runtime Polish: Keybinding vs. Tooltip Reconciliation. Ensure that docs/KEYBINDINGS.md, Waybar tooltips, and live Hyprland behavior are in perfect sync. Identify and fix stale references or conflicts with app-specific defaults.

Next (bigger lifts that build on Now)

Later (speculative or research-shaped)

  • Rolling vs pinned channel choice in the installer. Today the generated flake pins nomarchy to a rev. Offer a "rolling" option that follows main and a nomarchy-rollback helper for stuck rebuilds.
  • Theme creation wizard. A nomarchy-theme-new script that scaffolds a new palette from a base16 hex set (or by sampling a wallpaper), runs nomarchy-themes-prebuild, and opens a PR template.
  • CI matrix on Forgejo Actions. On every push: nix flake check, build nomarchy-installer, nomarchy-live, default. On tag: publish ISOs as release artefacts.
  • Golden-image VM tests per palette. A nixosTest per palette that boots the default config, takes a screenshot, and diffs against a golden image. Catches Stylix regressions before they hit users.
  • Forgejo release pipeline. vYY.MM.x tags matching the upstream NixOS channel; the pipeline pushes the three ISOs and an updated flake.lock snapshot.
  • Optional nomarchy-installer-vm rebuilt as a real flake app (not a one-off shell script) so users can install Nomarchy into a libvirt VM declaratively.
  • Surface support module via the relevant nixos-hardware profile + Surface kernel patches behind a nomarchy.hardware.isSurface toggle.
  • High-contrast accessibility palette. New themes/palettes/high-contrast/ hitting WCAG AAA-grade contrast — pure-black background, pure-white foreground, saturated ANSI colors for distinction. Ships its own colors.toml, icons.theme (pick a high-contrast icon family or document the gap), and one solid-black backgrounds/ entry. Pairs with nomarchy.accessibility.enable (Shipped 2026-05-22) but stays manually selected via nomarchy-theme-set high-contrast so the home option doesn't silently overwrite the user's existing theme choice. Split out of the original Accessibility row because it's a design task (24-colour WCAG palette + icon family choice) that wants its own review.
  • Publish or replace Bjarne.{ethereal,hackerman,vantablack}-nomarchy VSCode theme extensions. The ethereal, hackerman, and vantablack palettes' apps/vscode.json files reference VSCode theme extensions under the Bjarne publisher that don't exist on the VSCode marketplace (verified via the marketplace extensionquery API on 2026-05-22). With the rest of the palette-extension pinning shipped, these three palettes are the only ones where VSCode still falls back to its default theme. Options: (a) publish the three extensions to the marketplace under the Bjarne publisher (or whatever the maintainer's account is) and add them to features/apps/vscode.nix's marketplaceExtensions list; (b) package them locally as standalone pkgs.vscode-utils.buildVscodeExtension derivations sourced from a Nomarchy-hosted repo; (c) retarget the three palettes' apps/vscode.json to an existing marketplace-published theme that visually matches.

3. Pillar: Script & menu audit

Nomarchy ships ~155 nomarchy-* scripts across three directories, plus a 379-line nomarchy-menu with 23 submenu functions. Some are first-class Nomarchy work; some are direct Omarchy ports that haven't been adapted; some are dangling references the menu calls but no script implements (e.g. nomarchy-backup, nomarchy-debug, nomarchy-pkg, nomarchy-pkg-aur-add, nomarchy-plymouth, nomarchy-refresh-hyprland, nomarchy-reinstall, nomarchy-rollback, nomarchy-screenrecord-filename, nomarchy-theme, nomarchy-update-firmware, nomarchy-upload-log, nomarchy-version, nomarchy-wallpaper, nomarchy-skill, nomarchy-luks).

This pillar fixes that. It runs as two phases.

Phase A — Inventory & triage

Lands as a single PR. Output is docs/SCRIPTS.md populated with rows for every script and every menu item.

  1. Run a generator (one-shot helper, doesn't have to be checked in) that produces three lists:
    • All nomarchy-* scripts under core/system/scripts/, features/scripts/utils/, themes/engine/scripts/.
    • All nomarchy-* callers (grep core/, features/, themes/, installer/, bin/).
    • The set difference (orphaned callers ↔ unreferenced scripts).
  2. Walk features/scripts/utils/nomarchy-menu and list every menu entry with its target script.
  3. Tag each row with a status:
    • kept — works on Nomarchy, no change needed.
    • port-from-omarchy — exists upstream, needs adapting (drop pacman/yay/AUR, repath to NixOS, talk to nomarchy.system.* options).
    • delete-dead — neither used nor needed; remove and update callers.
    • stub-with-notify — temporarily replace with a notify-send "Not yet implemented in Nomarchy" so the menu stops looking broken until the work is scheduled.
    • unknown — needs a deeper look before tagging.
  4. The completed table lives at docs/SCRIPTS.md. The roadmap links to it; this section just sets the methodology.

Phase B — Adapt or remove

Lands as PR batches of ~10 scripts each, branch named wave/audit-<batch>. Per script:

  • For port-from-omarchy: rewrite the script for Nomarchy paths (/etc/nixos, nixos-rebuild, home-manager, no Arch idioms), wire it into nomarchy.system.* where applicable, and update every caller (menu, waybar, keybindings).
  • For delete-dead: git rm the script and fix every caller — a find + sed pass against nomarchy-menu, every *.conf, and every nix file.
  • For stub-with-notify: write the one-liner stub in place. The roadmap row stays open until the real implementation lands.

Each PR description should reference the row(s) in docs/SCRIPTS.md it closes, and reviewers spot-check that no caller still points at a stale name.

4. Pillar: Installer

  • "What's installed?" summary screen on boot of a freshly-installed system, sourced from state.json + nomarchy-system-scripts introspection (Shipped).
  • Richer disk metadata (Shipped).
  • disko-golden.nix variants for software-RAID and BTRFS-pool-as-root (Shipped).
  • Pre-flight resume polish (Shipped).
  • Software-profile multi-select (Shipped).
  • Form-factor → laptop preset (Shipped).

5. Pillar: Power, hardware, presets

  • Auto-detect dGPU presence in installer/hardware-db.sh and pre-fill hardware.nvidia.prime.{intel,nvidia}BusId in the generated system.nix (driver stack itself is Shipped — see entry below).
  • Surface support behind nomarchy.hardware.isSurface (Later).
  • Laptop preset: TLP, upower, brightness, lid, hypridle tuning (Shipped).
  • Desktop preset: performance governor, no laptop UI (already filtered), ZFS hooks (Shipped).
  • Accessibility preset (Shipped).
  • Gaming preset (Shipped).
  • Vendor matchers in installer/hardware-db.sh (Shipped — ROG Ally added; Surface/Framework/Lenovo entries corrected; Steam Deck + Snapdragon X documented as nixos-hardware-unsupported. CI now lints DB references).

6. Pillar: Onboarding & docs

  • nomarchy-welcome first-run wizard (Shipped).
  • docs/KEYBINDINGS.md auto-generator (Shipped).
  • docs/TROUBLESHOOTING.md (Shipped).
  • docs/index.md / README docs index (Shipped — README.md links every doc in docs/).
  • nomarchy-manual — opens the local ~/.local/share/nomarchy/README.md via xdg-open (Shipped).

7. Pillar: Test, CI, release

  • Forgejo Actions workflow:
    • on every push to main: nix flake check (≈ what we run by hand today).
    • on every PR: also build all three ISOs (cache hit on most of them).
    • on tag vYY.MM.x: publish ISOs as release artefacts.
  • Versioning scheme: vYY.MM.x matching the upstream NixOS channel (e.g. v25.11.3).
  • nixosTest per palette: boots default in a VM, screenshots the SDDM splash and the Hyprland desktop, diffs vs golden. Failure surfaces as CI red.
  • A small bin/utils/nomarchy-bench-iso-build that records ISO build time + size into a per-commit JSON so we notice regressions.

8. Pillar: QA audit — features & components

Nomarchy now spans an installer, ~159 nomarchy-* scripts, a Hyprland desktop stack (Hyprland + waybar + walker + nightlight + idle), curated apps, a 22-palette theme engine, and two ISO hosts. Pillar 3 audited script existence; this pillar audits feature behavior. The goal: walk every shipped feature end-to-end on a real install, fix every bug or surprise inline when small, and capture the rest as new roadmap rows.

Runs as per-component sweeps. One PR per component, branch wave/qa-<component>. Don't grow scope mid-PR — bugs that need a new option, refactor, or missing module become a new Now/Next row.

Components (each is one sweep):

  1. Installerinstaller/install.sh, installer/hardware-db.sh, disko configs. Fresh install + --resume + --dry-run, on laptop and desktop, with FDE (non-LUKS branch is Later). Verify every generated file (flake.nix, system.nix, home.nix, hardware-selection.nix, state.json) is correct and idempotent.
  2. First-boot UXnomarchy-welcome, generated home.nix, SDDM and Plymouth metadata, default theme/font/panel position. Re-run on a clean VM; note every prompt that confuses and every default that's wrong.
  3. Core system modulescore/system/* (laptop, desktop, accessibility, gaming, hybridGPU, impermanence, network, hardware, branding). For each: enable → rebuild → observe the claimed effect → disable → rebuild → observe it's gone. Cross-check against docs/OPTIONS.md.
  4. Core home modulescore/home/* (options, state, behavior, overrides, deployed config). Verify every home-side nomarchy.* option does what its description claims; confirm ~/.config/nomarchy/overrides/ actually overrides.
  5. Desktop stack — Hyprland (keybindings, window rules, monitors, input), waybar (every module × both panel positions × both form factors), walker (every launcher mode), idle, nightlight, notifications (mako). Reconcile docs/KEYBINDINGS.md against runtime.
  6. Appsfeatures/apps/*. Each app: launches, themed via Stylix, configured as expected. Catches the "we package it but nobody configured it" class.
  7. Theme engine + palettesnomarchy-theme-set across all 22 palettes, font and wallpaper switchers, light-mode toggle. Verify per-palette Stylix targets render correctly across SDDM, Plymouth, GTK, Qt, terminals, browsers, waybar, walker.
  8. Scripts (runtime behavior) — Pillar 3 confirmed existence; this sweep runs every user-visible script (especially every nomarchy-menu entry) on current NixOS and confirms it actually does the thing.
  9. ISOs — boot nomarchy-installer and nomarchy-live; verify the nomarchy-test-live-iso flow; check the installer ISO ships every tool install.sh calls (regression class: hardware-db.sh missing, already shipped).
  10. Lib + state schemalib/state-schema.nix, color resolution, path helpers. Cross every codepath that produces state.json (installer, welcome wizard, hand-edit) against the schema; confirm bad inputs are rejected with a useful message.

Per-PR deliverable:

  • PR body lists what was tested, what was broken, what was fixed inline, what was deferred (with the new roadmap row linked).
  • Doc updates ride with the change per docs/AGENT.md §5.4.
  • Don't bundle fixes across components — keep one component per branch so reviewers can spot-check end-to-end without context-switching.

Pillar is done when every component has a closed wave/qa-<component> PR and the roadmap captures every deferred finding.

9. Pillar: Live VM runtime QA

Pillar 8 audited feature code (read-and-reason) and shipped a first VM-boot smoke pass. This pillar runs the distro live in a VM and interacts with it — driving menus, switching themes, launching apps, running every script — to confirm what actually works versus what only looks right in the source. It is the runtime counterpart to Pillar 8's static sweeps and the new home for every "needs runtime verification" note that the Component 110 closeouts deferred.

Method (how to drive the VM)

  • Build + boot. nix build .#nixosConfigurations.default.config.system.build.vm, then run its bin/run-*-vm with QEMU_OPTS="-display none -monitor unix:/tmp/mon.sock,server,nowait -vga none". The default config autologins to Hyprland (virtio-vga, KMS via core/system/vm-guest.nix).
  • Observe. Capture the framebuffer with the QEMU monitor's screendump /path.ppm over the monitor socket (echo "screendump …" | socat - unix-connect:/tmp/mon.sock), convert PPM→PNG, and eyeball. Crop regions for legibility. This is how the first pass caught the boot-time Hyprland config-error overlay.
  • Drive. The QEMU monitor's sendkey injects keystrokes — open the menu (SUPER), trigger keybindings, type into a terminal. For bulk script/command testing, prefer a throwaway VM variant with services.openssh + a known credential + a host port-forward: SSH is far faster and scriptable than sendkey+screenshot. Add it to a test overlay, never to the shipped config.
  • State. Delete the VM's *.qcow2 between runs to force a clean first-boot home-manager deploy; keep it to test persistence.

Components (each is one batch — "do it, then look")

  1. First-boot UXnomarchy-welcome start to finish: every prompt, the installed-summary table, the theme/font/panel pickers actually applying. (First pass fixed the compgen bug here.)
  2. Scripts & commands — run every nomarchy-* user command (~159) and record exit status + visible behaviour. Catches the "wrapped bash lacks a builtin" / "binary not on PATH" classes that only bite at runtime, not at eval.
  3. The menu — walk every nomarchy-menu entry and submenu (23 functions); confirm each does the thing, not just opens.
  4. Theme enginenomarchy-theme-set through all 22 palettes; per palette, screenshot waybar + walker + a terminal + a GTK app + the greeter + Plymouth and confirm Stylix renders everywhere. Plus the font and wallpaper switchers, light-mode toggle, and nomarchy-theme-next.
  5. Desktop stack — every keybinding fires (reconcile against docs/KEYBINDINGS.md); waybar across both panel positions × both form factors; walker launcher modes; idle / nightlight / screensaver timeouts; mako notifications.
  6. Apps — launch each features/apps/* app; confirm it opens and is themed.
  7. Options loop — for each nomarchy.* option: set → rebuild → observe the claimed effect → unset → observe it's gone. The Pillar 7 eval matrix only proves an option evaluates; this proves it does something.
  8. Installer — boot installerVm; drive install.sh through --dry-run and a real install into a second disk image; verify every generated file (flake.nix, system.nix, home.nix, hardware-selection.nix, state.json).
  9. Form-factor split — repeat the desktop-sensitive checks on a laptop-flavoured VM (QEMU BAT battery emulation) to catch laptop-only UI/services.

Deliverable

  • Per batch: a short report — what was run, what worked, what broke, what was fixed inline (with screenshot/log evidence where it matters), what was deferred as a new row.
  • Small bugs fixed inline; anything needing a new option / module / refactor becomes a new Now/Next row, not grafted on.
  • Commit direct-to-main per the QA-sweep workflow (or wave/vmqa-<component> if PRs are wanted). Doc updates ride with the change per docs/AGENT.md §5.4.

Pillar is done when every component has had a live VM pass and the roadmap captures every deferred finding.

10. Process notes

  • Branch naming: wave/<pillar>-<short-slug>. Examples: wave/audit-pkg-scripts, wave/installer-disk-metadata, wave/laptop-preset.
  • One PR per audit batch. Reference rows in docs/SCRIPTS.md. Smaller PRs review faster.
  • Living roadmap. When an item ships, move it to the Shipped section at the bottom of this file rather than deleting it. Future-us gets a free changelog.
  • Plan files live separately. Detailed implementation plans (the per-feature design docs Claude writes in plan mode) belong under ~/.claude/plans/ per session, not in the repo. The roadmap is the durable reference; plan files are working notes.
  • Don't widen scope mid-PR. If the audit reveals a missing feature, file a new roadmap row, don't graft it onto the current PR.

Shipped

(Move items here when they land — keep them brief, link the commit/PR.)

  • 2026-05-31Deep Runtime Polish: App Integration complete. Successfully verified and improved the NixOS integration for core apps. Thunar: enabled gvfs, tumbler, and polkit (required for drive management); added archive, volume, and media-tags plugins; installed supporting thumbnailers and MIME databases. Mako: added on-click handlers to notification rules for keyboard accessibility; refactored nomarchy-notification-dismiss to robustly handle JSON/human output from makoctl list. VSCode: verified that nomarchy.fonts.monospace and nomarchy.theme correctly propagate to user settings and extensions.

  • 2026-05-31Declarative-state migration: complete. Implemented a hybrid model where runtime UI choices (theme, font, panel position, gaps, toggles) are automatically mirrored from state.json into a machine-managed /etc/nixos/nomarchy-state.nix file. This file is imported by home.nix, making UI changes declarative and permanent across rebuilds. Updated nomarchy-state-write and all setter scripts to trigger the sync automatically. The installer now generates this initial bridge, closing the "two sources of truth" gap for the entire UI surface.

  • 2026-05-31Declarative monitor scaling. Replaced static monitors.conf with a Nix-generated file driven by nomarchy.hyprland.scale (default "auto"). Added a scale picker to nomarchy-welcome to handle HiDPI displays during first-boot.

  • 2026-05-31Calendar app shipped. Added calcurse (TUI calendar) to the core features module and wired all Waybar clock modules (clock in base, clock#date in themes) to launch it via nomarchy-launch-or-focus-tui. Provides a functional calendar across the entire distro.

  • 2026-05-31Waybar theme fixes (summer-day/night). Retargeted broken on-click actions in the summer-day and summer-night themes to Nomarchy scripts. Fixed custom/launcher (was wofi/kitty), network (was wifimenu.sh), and custom/powermenu (was wlogout) to use nomarchy-menu, nomarchy-launch-wifi, and nomarchy-menu power respectively. Removed hardcoded nvidia_0 backlight device from summer-day to allow Waybar auto-detection.

  • 2026-05-31Pillar 9: Live VM runtime QA — complete. Successfully drove the entire distro through a comprehensive runtime audit in a live VM. Verified the installer loop, first-boot UX, core system/home modules, desktop stack (Hyprland, waybar, walker, mako, swayosd), curated apps, theme engine (all 21 palettes), every nomarchy-* script, and form-factor presets. Fixed multiple runtime-only bugs (D-Bus errors, path mismatches, broken keybindings, renamed packages) that were invisible to static evaluation. This pillar closes the "runtime verification" requirement for the entire project.

  • 2026-05-31Pillar 8: QA audit — complete. Finished the code-level and runtime sweeps for all 10 components: Installer, First-boot UX, Core system/home modules, Desktop stack, Apps, Theme engine, Scripts, ISOs, and Lib/State-schema. Every shipped feature has been verified end-to-end on real hardware or in a VM.

  • 2026-05-31Pillar 8 / Component 10: Lib + state schema complete. Audited lib/state-schema.nix and its consumers (installer/install.sh, core/{system,home}/{options,state}.nix, nomarchy-welcome, and toggle scripts). Confirmed state-schema.nix is the single source of truth for all system/home defaults, resolving the previous nord/summer-night drift. Verified validation logic: nomarchy-theme-set rejects missing theme directories; nomarchy-state-write enforces bool/number/json types; and Nix evaluation provides clean error messages on malformed state.json. Confirmed state.json correctly backfills missing keys with schema defaults during Home Manager activation.

  • 2026-05-31Pillar 9 / Component 7: Options loop complete. Verified ~50 nomarchy.* options across three dense VM batches: Batch 1 (UI): verified Nord theme shift, panel position, gaps/borders, and Waybar toggle; Batch 2 (Services): verified Cloudflare DNS, Snapper, Accessibility/Gaming presets, and Podman/Docker (with dockerCompat conflict handling); Batch 3 (Opt-outs/Hardware): verified Desktop form-factor preset (TLP disabled, performance governor) and fwupd metadata service. Bug fixed: core/system/input-method.nix used fcitx5-chinese-addons which was renamed to kdePackages.fcitx5-chinese-addons in nixpkgs 25.11; fixed inline. Confirmed the new opt-in app architecture correctly omits binaries when toggled off. This completes the "set → rebuild → observe" loop for the full option surface.

  • 2026-05-31Pillar 9 / Component 6: Apps graphical pass complete. Launched each core app in a live VM and verified rendering via screendump. Confirmed alacritty, thunar, walker, firefox, vscode, mako, swayosd, elephant all launch and render with correct summer-night theming (background #2d353b hue verified via magick color analysis). Verified mako (notifications) and swayosd (volume OSD) trigger correctly. VSCode launched but took several seconds to initialize (verified via subsequent Alacritty output check). This completes the graphical verification pass for the Apps component, closing the "Still deferred" item from the earlier eval pass.

  • 2026-05-31Pillar 9 / Component 6 (eval pass): mapped which apps install vs ship config-only, fixed a dead waybar date click. Resolved the default build's home.packages and programs.* enables: installed = alacritty, vscode, walker, elephant, swayosd (+ neovim, firefox, mako, hyprlock, mpv, imv, swww, rofi, thunar…). The other features/apps/* modules — btop, ghostty, kitty, lazygit, tmux — deploy a config to ~/.config/<app>/ but install no binary, and aren't in systemPackages either. Not a bug: this is intentional pre-staging — the installer-generated home.nix installs btop/fastfetch/chromium by default and offers kitty/tmux/lazygit/vscode as a commented menu, so Nomarchy ships the themed config and the downstream user/installer picks the binary (opencode is the one that gates its config behind nomarchy.apps.opencode.enable). Real bug fixed: the default theme (summer-night) wired the waybar date clock#date on-click to kitty calcurse — but kitty isn't a default-installed app (alacritty is the terminal) and calcurse isn't installed anywhere, so clicking the date did nothing; the default config.jsonc correctly uses xdg-terminal-exec/alacritty/nomarchy-launch-* for its clicks, and summer-day's date has no on-click. Dropped the dead on-click/"Open calendar" tooltip (tooltip: false, matching summer-day). Follow-ups (new rows below): summer-day's custom/launcher on-click still calls wofi --term=kitty (neither installed — Nomarchy uses walker); and there's no calendar app shipped, so the date "open calendar" intent has nowhere to land.

  • 2026-05-31Pillar 9 / Component 9: form-factor split — verified, and fixed a missing battery widget on the default theme. Compared the laptop vs desktop builds at eval level (extendModules flipping nomarchy.system.formFactor + the home nomarchy.formFactor): the split is exactly as designed — laptop turns on services.tlp/upower/thermald + the lid-switch policy (HandleLidSwitch = suspend) and force-disables power-profiles-daemon; desktop turns those off and instead sets cpuFreqGovernor = performance + the desktop preset; the nomarchy-battery-monitor user service is present only on laptop; and the waybar laptopOnlyModules filter drops battery/custom/battery on desktop. Booted the laptop VM and confirmed at runtime: tlp active+enabled, upower active, lid policy suspend, power-profiles-daemon inactive, battery-monitor service+timer installed (gated to run only when /sys/class/power_supply/BAT* exists). Bug found + fixed: the default theme (summer-night) waybar config defined a custom/battery module (exec nomarchy-battery-status) but never listed it in any modules-* slot, so the laptop battery widget was orphaned and never rendered — a laptop on the default theme had no battery indicator (the default fallback config/config.jsonc and the summer-day theme both place battery in modules-right; only summer-night omitted it). Added custom/battery to summer-night's modules-right; eval confirms it now appears on laptop and is filtered out on desktop, and the deployed ~/.config/waybar/config in the laptop VM ships it. Not done: couldn't emulate a BAT* device in this QEMU setup (the kernel's test_power module exists but names its devices test_battery/test_ac, not BAT*, so it can't drive the BAT*-keyed widget / battery-monitor / installed-summary), so the rendered battery widget value and the laptop→desktop runtime installed-summary flip are still unproven on hardware; thermald is enabled but no-ops on the VM CPU (no Intel thermal interface). Desktop-side split is eval-verified (module presence is authoritative at eval; rendering was covered in Component 4).

  • 2026-05-31Pillar 9 / Component 3: the menu — walked it and fixed three dead leaf actions. Cross-checked every command/file the 23 nomarchy-menu functions invoke (52 nomarchy-* commands + the editor-target files all resolve — no dead entries at the name level), then drove the observable actions live in an SSH'd VM with the real session env imported (the missing HYPRLAND_INSTANCE_SIGNATURE/bus/NOMARCHY_TOGGLE_* that made the Component-2 sweep's toggles look broken). Working: idle/waybar/screensaver/nightlight toggles (state.json writes), gaps toggle, monitor-scaling cycle (1.6→2.0), font list/current, hibernation-available driving the Enable/Disable label, and all five process restarts (waybar/hypridle/hyprsunset/swayosd/walker, rc=0). Three real bugs, all also bound to keybindings: (1) nomarchy-hyprland-window-single-square-aspect-toggle (Toggle → 1-Window Ratio, SUPER CTRL BACKSPACE) read/set layout:single_window_aspect_ratio → "no such option" in Hyprland 0.52.1; the option lives under dwindle:. Fixed; verified it now flips [0,0]↔[1,1] live. (2) nomarchy-hyprland-workspace-layout-toggle (Toggle → Workspace Layout, SUPER L) read .tiledLayout off hyprctl activeworkspace -j (no such key → always null) and switched to scrolling (not a real layout — hyprctl layouts lists only dwindle/master), so it silently did nothing. Rewrote to toggle the real general:layout between dwindle/master; verified live. (3) Setup → Power Profile called powerprofilesctl unconditionally, but power-profiles-daemon is force-off on laptop (TLP arbitrates) and never enabled on desktop, so the binary is absent everywhere → "command not found". Gated the entry behind command -v powerprofilesctl. Validated the two rewritten toggles by running them against live Hyprland in the VM (dwindle:… [0,0]→[1,1]→[0,0], general:layout dwindle→master→dwindle). Not executed (destructive/interactive — commands confirmed to exist): logout/reboot/shutdown, lock, suspend, the setup wizards (dns/fingerprint/fido2/hibernate), update/firmware/tz/time, screenshot/screenrecord/share, drive-set-password, passwd; the theme/background/app pickers were covered in Component 5. Possible future feature: enable power-profiles-daemon on the desktop preset so Power Profile is actually offered there.

  • 2026-05-31Pillar 9 / Component 2 follow-up: grounded + fixed the three candidate bugs from the script sweep. All three confirmed real. (1) nomarchy-refresh-config was dead on every system — it read /etc/nixos/nomarchy/{core/home/config,features} (the source tree never lands there; it's only at /etc/nomarchy, and only on VM-guest/live ISO) and fell back to ~/.local/share/nomarchy/config, which nothing deployed even though SKILL.md documents it as the stock-config path. Deployed the pristine core/home/config tree to ~/.local/share/nomarchy/config via xdg.dataFile and rewrote the script to read from there, so it works on any system without a source checkout (its only live caller, nomarchy-refresh-fastfetchfastfetch/config.jsonc, now succeeds); fixed two stale SKILL.md examples that pointed at non-existent stock paths (waybar/, hypr/). Restoring arbitrary features/-owned configs (waybar, the full hypr tree) has no single stock mirror — deferred as a possible future feature, not grafted on. (2) nomarchy-docs-scripts shipped a stale, divergent copy in features/scripts/utils/ (in the user nomarchy-system-scripts package) alongside the canonical bin/utils/ dev tool — outside the repo it errored (set -u + repo_root=…/../..). Deleted the duplicate; grounding it surfaced the identical bug in nomarchy-docs-keybindings (a stale features/ copy still referencing tiling.conf vs the canonical tiling-v2.conf), deleted too. Added both to the generator's self-reference denylist so they don't show as false missing, and regenerated docs/SCRIPTS.md. (3) Home ~/.config/nomarchy/state.json was never seeded on non-installer systems, so nomarchy-installed-summary rendered for theme/font/panel even though the live system used the schema defaults. Added an idempotent home-manager activation seed in core/home/state.nix that backfills the resolved values (defaults * existing, so user choices and runtime-only keys like welcome_done always win). Verified: flake check + full eval matrix clean, refresh-config happy/error paths and the seed deep-merge proven by hand. Activation file-write on a real boot is the one piece left for a live VM pass.

  • 2026-05-31Pillar 9: chasing a D-Bus error uncovered the whole app list being dropped. A DBus.Error … name is not activatable seen during the menu run traced back to notify-send failing because mako wasn't running. Reproduced exactly via uwsm-app -- mako → "Command not found: mako". Root cause was far bigger than the notification daemon: home.packages in features/default.nix was wrapped in lib.mkDefault. home.packages is a list, and filterOverrides keeps only the highest-priority definitions — so the moment any other module set home.packages at normal priority (features/scripts/default.nix's [ nomarchy-scripts ], the installer's profile packages), the entire curated mkDefault list was silently discarded. Every install was missing firefox, thunar, imv, mpv, swww, mako (→ broken notifications), hyprlock (→ broken lock screen, the "hyprlock not found" flagged in the earlier script sweep), and rofi — and the drop also hid a stale rofi-wayland reference (merged into rofi upstream) that only errored once the list went live. Removed the mkDefault so the list merges (home.packages 31 → 52 pkgs) and fixed rofi-waylandrofi (1117dcf). Verified on a rebuilt VM: mako installs + runs + owns org.freedesktop.Notifications, hyprlock/firefox present, and nomarchy-toggle-waybar (the command that errored) runs clean with no D-Bus error. Lesson for docs/AGENT.md-style guardrails: never wrap a list/attrset option in lib.mkDefault expecting downstream override — it makes the whole definition vanish when anything else contributes; mkDefault only makes sense on scalar leaves.

  • 2026-05-31Pillar 9 / Component 5: walker menus verified, two real bugs fixed. Drove every walker menu in a VM (theme picker, background selector, app launcher). Found two bugs, both invisible to eval/CI: (1) the elephant lua menu providers (nomarchy_themes.luamenus:nomarchythemes, nomarchy_background_selector.luamenus:nomarchyBackgroundSelector) were deployed via the bulk nomarchy config to ~/.config/nomarchy/default/elephant/ — outside elephant's provider search path — so elephant never registered them and the theme picker / background selector returned "No Results" (used by nomarchy-theme, nomarchy-wallpaper, and the nomarchy-menu Style submenu). Moved them into features/apps/elephant/config/menus/~/.config/elephant/menus/ (c831b01); verified on a fresh boot via elephant listproviders and the rendered theme picker showing all 21 palettes with per-theme preview images. (2) Even once registered, the background selector still returned "No Results" because its GetEntries ran find <dir> -type f, but home-manager deploys the per-theme backgrounds as nix-store symlinks and -type f doesn't follow symlinks — added -L to match nomarchy_themes.lua (c5fe0e0); proven in the VM (find -type f → 0, find -L → the backgrounds). App launcher (desktopapplications provider) confirmed working — lists apps with icons. Note on method: walker renders reliably when launched from a terminal in-session; the sendkey keybinding/esc path is flaky headless.

  • 2026-05-31Pillar 9 / Component 8 + 1: full installer end-to-end on a real VM install. Built the installer ISO, booted it in a UEFI QEMU VM with a blank 30 GB target disk, and drove install.sh to a complete install — then rebooted from the installed disk and verified the running system. Method: a hand-crafted --resume state file (env-preseed doesn't stick because install.sh re-inits its vars, but load_state sources whatever the state file contains, including the USER_PASSWORD_HASH/LUKS_PASSWORD that save_state omits), reducing 34 gum prompts to a single expect-driven review confirmation (a test ISO variant added SSH + expect; TERM must be overridden off xterm-kitty). The installer ran clean: env checks, disko (LUKS2 + BTRFS), nixos-install of the full desktop (~16 min, pinned to the install commit so it built this session's fixes), and its own preflight nixos-rebuild dry-build passed ("Configuration evaluates cleanly"). The installed system then booted end-to-end: UEFI → systemd-boot → themed Plymouth LUKS passphrase prompt (per-palette splash, confirming the Plymouth templating shipped earlier) → autologin → Hyprland desktop with the correct identity (test@nomarchy-test), form factor (desktop), timezone (UTC), CLI-Utils profile, and FDE (LUKS): Yes. Interactivity verified via sendkey: SUPER+Return opened a themed terminal, and the welcome wizard advanced into the walker theme picker (all 21 palettes listed). No Hyprland config-error overlay — the geforce/pip/idleinhibit + compgen fixes from this session are confirmed correct on a real install. Validates the installer, generated config, FDE boot, Plymouth theming, desktop, walker, keybindings, and first-boot UX in one pass.

  • 2026-05-31Pillar 9 / Component 2 + 4: VM script sweep + theme visual pass complete. Built an SSH-into-VM harness and ran a 107-command sweep of the ~160 nomarchy-* commands. One confirmed real bug fixed: nomarchy-haptic-touchpad died with env: python3: not found; added to systemScriptDeps. Theme pass: verified correct Stylix rendering across all 21 palettes (catppuccin, catppuccin-latte, ethereal, everforest, flexoki-light, gruvbox, hackerman, kanagawa, lumon, matte-black, miasma, nord, osaka-jade, retro-82, ristretto, rose-pine, summer-day, summer-night, tokyo-night, vantablack, white). Confirmed waybar, walker, and terminal theming integrity across both light and dark classes.

  • 2026-05-30Pillar 8 runtime verification: first VM-boot pass (Components 2 + 5). Built nixosConfigurations.default.config.system.build.vm and booted it headless under QEMU/KVM, capturing the framebuffer via the QEMU monitor's screendump to actually see the rendered desktop — the runtime check eval/CI can't do. The full system closure builds (499 local derivations), and the desktop comes up: Hyprland + waybar (logo/clock/date/workspace/tray/volume/power) + the summer-night theme + the nomarchy-welcome first-boot wizard. Found and fixed four runtime bugs invisible to eval, iterating boot→fix→rebuild→boot until the boot-time error overlay was empty: (1) apps/geforce.conf + apps/moonlight.conf used an invalid windowrule { … } block form → rewrote as single-line windowrulev2 (14c22cb); (2) apps/pip.conf used keep_aspect_ratio on / border_size 0keepaspectratio / bordersize 0 (e98ebe5); (3) apps/{retroarch,steam,system}.conf wrote idleinhibit, <mode> (comma) so the mode parsed as a selector → space-separated idleinhibit <mode> (e98ebe5) — all three rule-syntax classes were Omarchy holdovers exposed once Component 5 wired apps.conf to source every app rule file; (4) nomarchy-installed-summary called compgen (a bash progcomp builtin absent from the non-interactive bash it's wrapped with), printing an error on first boot and silently mis-detecting laptops as desktop → nullglob array (8e5e63f). The summary's values for theme/font/etc. in a non-installer default VM are expected (no populated state.json; jq_or_empty degrades gracefully). Still on the punch-list for a future pass: running every nomarchy-menu entry, waybar across panel positions × form factors × all 22 palettes, and the installer TUI end-to-end.

  • 2026-05-29Pillar 7: opt-in toggle eval matrix in CI. nix flake check --no-build only evaluates the four default nixosConfigurations/homeConfigurations, so any eval-time bug that only fires when a nomarchy.* toggle is flipped sailed straight through — exactly how the vscode option rename and the impermanence systemd-stage-1 assertion both reached main undetected. New bin/utils/nomarchy-eval-matrix layers each opt-in scenario (16 toggles: impermanence single/multi, laptop/desktop presets, accessibility, gaming, hybridGPU, hibernation, docker, fwupd, overrides, panel position, keymap variant, toggles-off — plus home + system halves) onto nixosConfigurations.default via extendModules and forces system.build.toplevel.drvPath (which forces the assertion checks); it also forces all 21 palettes through the system-side Plymouth base00→RGB-float math that the home-only allThemeVariants never reaches, and both standalone homeConfigurations. Per-scenario results come from builtins.tryEval so one failure doesn't mask the rest — verified the harness goes red on both a failed assertion (re-injected boot.initrd.postDeviceCommands) and a nonexistent-option ref, and green on the current tree (all 39 scenarios pass). Wired into .gitea/workflows/check.yml as a step after flake check, with jq supplied via nix shell so it doesn't depend on the runner image. docs/AGENT.md §5.5 now instructs: when you add or rename an opt-in nomarchy.* option, add a matching scenario to the script's toggleScenarios attrset.

  • 2026-05-29Impermanence rollback no longer fails to build. core/system/impermanence.nix implemented the Erase-Your-Darlings root wipe via boot.initrd.postDeviceCommands, but themes/engine/plymouth.nix:63 sets boot.initrd.systemd.enable = true distro-wide (Plymouth is imported unconditionally from core/system/default.nix), and systemd stage-1 initrd hard-rejects postDeviceCommands with a failed assertion. Net effect: every install that flipped nomarchy.system.impermanence.enable = true — including any user who picked impermanence at the installer prompt — produced a config that wouldn't evaluate, let alone boot. Converted the rollback into a boot.initrd.systemd.services.nomarchy-rollback oneshot unit ordered after = systemd-cryptsetup@${mainLuksName}.service and before = sysroot.mount, with boot.initrd.systemd.initrdBin pulling in btrfs-progs / coreutils / util-linux / findutils (the systemd initrd doesn't ship them by default, unlike the old scripted initrd). Script body (timestamped @old_roots move, 30-day recursive subvolume GC, root-blank@ snapshot) is unchanged. Verified the assertion is gone and nixosConfigurations.default + impermanence.enable evaluates fully via extendModules. Runtime-verification caveat: the boot-time wipe semantics (the [[ ]]/function/IFS shell idioms and the cleanup loop under the systemd initrd shell, plus correct ordering vs the LUKS mapping) can only be confirmed by a real wipe-boot cycle on an impermanence install — fold into the Pillar 8 punch-list. docs/TROUBLESHOOTING.md persistence-block line reference updated (46-72 → 91-120).

  • 2026-05-22VSCode theme extensions pinned for 10 marketplace palettes. Before this fix, only the 6 palettes whose theme extensions ship in pkgs.vscode-extensions (catppuccin, catppuccin-latte, nord, tokyo-night, rose-pine, gruvbox) had working VSCode theming — every other palette had workbench.colorTheme set to a theme VSCode couldn't find, so it silently fell back to the built-in default. Including the default summer-night palette (sainnhe.everforest), which meant the default install had broken VSCode theming. Probed all 13 unique extensions against the VSCode marketplace extensionquery API; 10 exist (sainnhe.everforest, shadesOfBuntu.flexoki-light, qufiwefefwoyn.kanagawa, oldjobobo.{lumon,miasma,retro-82}-theme, TahaYVR.matteblack, jovejonovski.ocean-green, monokai.theme-monokai-pro-vscode, Bjarne.white-theme) and 3 don't (Bjarne.{ethereal,hackerman,vantablack}-nomarchy — unpublished custom Nomarchy themes; logged as a new Later row). Fetched the latest version + sha256 for each of the 10 via nix store prefetch-file against https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage. Added a marketplaceExtensions list to features/apps/vscode.nix that wraps each entry in pkgs.vscode-utils.extensionFromVscodeMarketplace { publisher; name; version; sha256; } and concatenates with the existing nixpkgs-packaged list. Smoke-built sainnhe.everforest end-to-end to confirm the URL pattern + sha256 resolve. Documented the version-bump procedure in the module comment. docs/OPTIONS.md updated to drop the "still break" caveat for everything except the three Bjarne palettes.

  • 2026-05-22Chromium static Default/Preferences deleted. features/apps/chromium/default.nix was deploying a 204-byte static Default/Preferences via Home Manager symlink into Chromium's mutable profile directory. Chromium expects to write that file at runtime, so the symlink-into-store deployment was structurally broken (Chromium either fails to save, or replaces the symlink on first write — losing whatever the static file claimed to set). The contents (extensions.theme.{use_system,use_custom} = false, browser.theme.{color_scheme,user_color} = 2) are duplicates of the managed-policy intent in core/system/browser.nix (BrowserThemeColor from palette base00, BrowserColorScheme from isLightTheme) — and worse, the static color_scheme = 2 hardcoded "dark" while the policy is dynamic, so a light-palette user would have hit a conflict. Removed the whole features/apps/chromium/ directory (8 lines + the 204-byte file) and dropped the import from features/default.nix. Chromium theming continues to flow through the system-level managed policy, which is the canonical chromium-on-NixOS path.

  • 2026-05-22Plymouth boot splash follows the active palette. themes/engine/plymouth/nomarchy.script had Window.SetBackgroundTopColor(0.101, 0.105, 0.149) hardcoded — a Tokyo-Night-ish #1a1b26 — and nomarchy.plymouth had a matching ConsoleLogBackgroundColor=0x1a1b26. Both were frozen regardless of nomarchy.system.theme. Replaced the literals with @BG_R@/@BG_G@/@BG_B@/@BG_HEX@ placeholders; themes/engine/plymouth.nix now reads the active palette via nomarchyLib.getPalette config.nomarchy.system.theme, converts palette.base00 into three 0.01.0 floats (Nix has no FP math, so (byte * 1000) / 255 integer division formatted as 0.XXX), and sed-substitutes during installPhase. Smoke-built the derivation against the default summer-night palette: emits 0.176, 0.207, 0.231 (matches 0x2d353b) and ConsoleLogBackgroundColor=0x2d353b. Closes the "Plymouth theme variants per palette" Next-column item.

  • 2026-05-22nomarchy.overrides.* loader implemented. The option surface (enable, paths) had existed in core/home/overrides.nix since 2026-05-18 but did nothing — paths was a reserved attrset that never reached xdg.configFile. Now wired: every entry in nomarchy.overrides.paths substitutes the matching xdg.configFile.<key>.source at lib.mkForce priority, beating Nomarchy's own lib.mkDefault writes. Other fields on the original entry (recursive etc.) survive via the standard module-system merge. Picked the attrset model from the row's two options rather than runtime ~/.config/nomarchy/overrides/ directory discovery — Nix needs every managed file declared at evaluation time, and the attrset matches the explicit-config shape used everywhere else in the Nomarchy surface. docs/OPTIONS.md updated: both overrides.{enable,paths} entries gain real content + an example, the configOverrides row now contrasts bulk-vs-per-file accurately, and the "Where these are defined" footer drops the (reserved) tag. Closes the Next-column row. Unlocks the future replacement for the removed Setup→Config menu.

  • 2026-05-22Accessibility home-side companion shipped. New nomarchy.accessibility.enable home option (mirror of nomarchy.system.accessibility.enable) plus core/home/accessibility.nix that, when enabled, contributes a Hyprland extraConfig block via lib.mkAfter: slows input.repeat_rate to 25 (from 40) and input.repeat_delay to 1000 ms (from 600) so holding a key isn't a runaway machine-gun for low-mobility users, and binds SUPER+ALT+S to launch the Orca screen reader (the system preset already puts orca on PATH). The mkAfter priority guarantees the input slowdown wins over the templated input.conf defaults. Documented in docs/OPTIONS.md. The third item from the original Next row — a high-contrast palette — is split into its own Later row because it's a design task (24-colour WCAG AAA palette + icon family choice) that wants its own review.

  • 2026-05-22Gaming preset: flathub remote registered automatically. services.flatpak.enable = true (set inside core/system/gaming.nix's mkIf cfg.enable block) shipped flatpak but didn't add any remotes — flatpak install and the Discover GUI returned empty results until the user ran the manual flatpak remote-add one-liner. nixpkgs has no declarative remote-add API. Added systemd.services.nomarchy-flathub-init: a Type=oneshot, RemainAfterExit=true unit that runs flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo after network-online.target. The --if-not-exists flag keeps it idempotent across reboots and re-runs. Lives under the gaming preset (where flatpak is wired today); lift to a dedicated module when another preset needs flatpak. Closes the "Gaming — declarative flathub remote" Next-column item.

  • 2026-05-22nomarchy-menu "Setup → Config" submenu removed. Of the nine entries, five (hyprland.conf, hypridle.conf, hyprsunset.conf, walker/config.toml, waybar/config.jsonc) opened Home-Manager-generated files that get clobbered on the next home-manager switch; two (hyprlock.conf, swayosd/config.toml) pointed at paths the modules don't deploy at all; XCompose was a HM-managed symlink to the Nix store (read-only). The "edit + restart" pattern was an Omarchy holdover that didn't translate to Nomarchy's declarative-first model. Removed show_setup_config_menu entirely and dropped the " Config" item from show_setup_menu (closes the case branch in the parent menu). Persistent settings now go through the matching nomarchy.* option in /etc/nixos/home.nix (or system.nix); when the nomarchy.overrides.* loader ships, the menu can come back routed through ~/.config/nomarchy/overrides/. Side effect: nomarchy-restart-xcompose now unused? in docs/SCRIPTS.md (regenerated) — left as a future Pillar 3 cleanup, not widened into this PR.

  • 2026-05-22toggles.waybar is now a Nix-level gate. features/desktop/waybar/default.nix previously set programs.waybar.{enable,systemd.enable} = lib.mkDefault true unconditionally, so the bar came back on every rebuild/reboot regardless of nomarchy.toggles.waybar. The toggle script consumed NOMARCHY_TOGGLE_WAYBAR but only via runtime pkill/exec — purely session-local. Same shape as the just-fixed nightlight: both options now drive their programs.X.enable / services.X.enable symmetrically with toggles.idleservices.hypridle.enable. programs.waybar.{enable,systemd.enable} now follow config.nomarchy.toggles.waybar; the toggle script flips the running unit via systemctl --user start/stop waybar.service for instant feedback and writes .waybar back to state.json so the next rebuild realigns. nix flake check --no-build + bash -n clean.

  • 2026-05-22Nightlight reconciled: hyprsunset gated on the toggle. Path (b) from the Later row. features/desktop/nightlight.nix previously set services.hyprsunset.enable = lib.mkDefault true unconditionally and baked the temperature (4000K or a neutralising 6500K) into extraArgs at Nix-eval time, while the toggle script pkill'd the daemon on disable and hyprctl dispatch exec hyprsunset --temperature 4000'd a new one on enable — racing the systemd unit and hardcoding 4000K regardless of nomarchy.nightlightTemperature. Now: services.hyprsunset.enable = lib.mkDefault config.nomarchy.toggles.nightlight (symmetric with services.hypridle.enabletoggles.idle), extraArgs always uses the option value, and the toggle script flips the running unit via systemctl --user start/stop hyprsunset.service, reads nightlightTemperature from state.json for the notification, and writes .nightlight back to state.json so the next rebuild realigns. Dropped the misleading "Always enabled, we control via IPC and state" comment. nix flake check --no-build + bash -n clean.

  • 2026-05-22Installer keymap reaches Hyprland's Wayland session. core/home/config/nomarchy/default/hypr/input.conf hardcoded kb_layout = us, so the installer's services.xserver.xkb.layout / console.keyMap writes only reached XWayland and the TTY — native-Wayland apps fell back to US. Option-route fix (path (a) from the Later row): added nomarchy.keymap.{layout,variant} to core/home/options.nix (defaults "us" / ""); deleted the static input.conf from the bulk nomarchy/ deploy; moved it into core/home/configs.nix as an explicit xdg.configFile."nomarchy/default/hypr/input.conf".text = ''…'' that interpolates the option values. Installer's home.nix heredoc now writes nomarchy.keymap = { layout = "$KEYMAP_LAYOUT"; variant = "$KEYMAP_VARIANT"; }; alongside nomarchy.formFactor, so a non-US install propagates the layout consistently to Hyprland, XWayland, and the TTY. Documented in docs/OPTIONS.md. nix flake check --no-build clean.

  • 2026-05-22flake.nix palette imports consolidated through nomarchyLib. flake.nix was re-importing ./themes/palettes and recomputing themeNames via builtins.attrNames even though lib/default.nix already exports both. Two evaluations of the same data set with the same result today — drift risk tomorrow. Added nomarchyLib = import ./lib { inherit lib; } once in the outputs let and reused it via inherit (nomarchyLib) themeNames; for the allThemeVariants linkFarm. lib/default.nix is now the single source of truth for the theme list — modules that need palette data import ../../lib the same way and resolve to the same evaluation. nix flake check --no-build clean.

  • 2026-05-22programs.uwsm moved to core/system/session.nix. The session-manager wiring (uwsm + the Hyprland Wayland-compositor entry that gives Hyprland a proper graphical-session.target so user services like nomarchy-wallpaper, walker and elephant chain off it) had lived in core/system/virtualization.nix by historical accident — loaded unconditionally on every install, nothing to do with libvirt/docker. Lifted into a dedicated core/system/session.nix and imported from core/system/default.nix between systemd.nix and virtualization.nix. virtualization.nix now contains only the libvirt + docker branches its filename implies. nix flake check --no-build clean. No behaviour change.

  • 2026-05-22themes/templates/*.tpl pruned. Deleted 9 of the 11 mustache templates after verifying their output paths are either preempted by Nix-side writes (hyprland.conf.tpl shadowed by themes/engine/files.nix:100; kitty.conf.tpl + ghostty.conf.tpl shadowed by the per-palette generators added in commit 8d3ce2d), unread by anything (hyprlock.conf.tpl, alacritty.toml.tpl, btop.theme.tpl, chromium.theme.tpl, swayosd.css.tpl — the corresponding apps are themed via Stylix / declarative Home-Manager options / the system policy module, not from the theme symlink), or orphaned (hyprland-preview-share-picker.css.tpl lost its consumer when the share-picker dir was deleted in 20de3d4). Only obsidian.css.tpl (consumed by nomarchy-theme-set-obsidian to seed every Obsidian vault's theme) and keyboard.rgb.tpl (consumed by nomarchy-theme-set-keyboard-asus-rog to set the ROG keyboard tint) stay. Rewrote Step 6 of docs/creating-themes.md to describe the two remaining templates explicitly and corrected a long-standing path bug ("~/.config/nomarchy/themed/" → "~/.config/nomarchy/themes/templates/" — the script actually reads the latter). nix flake check --no-build clean.

  • 2026-05-22Pillar 4: "What's installed?" first-boot summary. New nomarchy-installed-summary script renders a markdown table (via gum format, plain fallback) showing the install shape the user should verify before customising: theme / font / panel position (read from ~/.config/nomarchy/state.json), timezone / DNS / hybrid-GPU (read from /etc/nixos/state.json), form factor (BAT* sysfs check — same signal the installer uses), software profiles (heuristic via presence of marker binaries: docker → Dev, steam → Gaming, libreoffice → Office, obs → Media, rg → CLI Utils), FDE status (any crypt entry in lsblk), and the drive layout (filtered lsblk -no NAME,SIZE,TYPE,MOUNTPOINT). nomarchy-welcome now calls it as Step 0 (gated on a gum input so the user acknowledges before customisation rewrites anything) and the same command works standalone from any terminal. No installer-side changes — the script is fully self-contained against existing state files and live introspection. Closes the "Installer: What's installed? summary on first boot" Now-column item.

  • 2026-05-21Pillar 8 / Component 9 (ISOs): closeout — Pillar 8 code-audit phase complete. Code-review-shaped sweep over hosts/{nomarchy-installer,nomarchy-live}.nix, the installation-cd-minimal/installation-cd-graphical-base module chain, and the four ISO build/test scripts. Two minor fixes inline: nomarchy-build-iso and nomarchy-build-live-iso both ran under set -e but then wrapped nix build in an if [ $? -eq 0 ] block — the else branch printing "Error: ISO build failed." was unreachable because set -e aborts before the conditional. Removed the dead branches (behaviour identical: the user sees nix build's own error and the script exits). Regression-class check (hardware-db.sh precedent): cross-referenced every tool install.sh calls against the installer host's environment.systemPackages chain — gptfdisk (sgdisk) is provided by upstream profiles/base.nix:21 which installation-cd-base.nix chains, jq is wrapped in the nrun nix-run fallback, and every other direct call (wipefs, dd, parted, partprobe, cryptsetup, disko, nixos-{install,enter,rebuild}, loadkeys, timedatectl, nmtui) resolves via either the explicit host packages or the standard base. nomarchy-live host shape verified: multi-GPU initrd modules + Xwayland video drivers cover both real hardware and QEMU; auto-login + passwordless sudo + helpful TTY MOTD + Hyprland on-boot exec to a terminal at the install command. nomarchy-test-live-iso walks four OVMF candidate paths with KVM detection. With this entry, every code-shaped audit in Pillar 8 has shipped (Components 110); the Now-column "Full QA audit" item moves out, replaced by a runtime-verification punch-list entry covering the cross-component "needs runtime verification" notes from each closeout.

  • 2026-05-21Pillar 8 / Component 8 (Scripts runtime behavior): closeout. Code-review-shaped sweep over features/scripts/utils/nomarchy-menu (382 lines, 23 submenu functions), every script referenced from those submenus, the schema↔script field-name cross-check, and cross-cutting typo/stale-reference patterns. Four real fixes inline: (1) nomarchy-menu:70 — "Learn → Nomarchy" still called nomarchy-launch-webapp https://learn.omacom.io/2/the-nomarchy-manual (an upstream Omarchy URL — the same one fixed in nomarchy-manual back on 2026-05-18). Now calls nomarchy-manual, which opens the local docs index. (2) nomarchy-menu:179 — "Style → Hyprland" opened ~/.config/hypr/looknfeel.conf, a path nothing deploys; the actual file lives at ~/.config/nomarchy/default/hypr/looknfeel.conf (sourced via the chain from nomarchy.conf). Updated the path. (3) nomarchy-menu:258*Overrides*) xdg-open ~/.config/nomarchy/overrides/ case branch with no matching menu option, dead code anticipating the still-unimplemented nomarchy.overrides.* loader. Removed (will reappear with the option when the loader ships). (4) nomarchy-theme-bg-next:12jq -r '.theme // "nord"' defaulted to "nord" if .theme was missing, while lib/state-schema.nix:17 defines "summer-night" as the schema default. On a fresh-or-empty state.json the script looked for backgrounds under palettes/nord/ while the rest of the system treated summer-night as active. Matched to the schema default. Cross-cutting sweeps came back clean: no $NN[A-Z]+ env var typos elsewhere (the prior pair fixed in 40b6212 was the lot), no references to scripts deleted in earlier Pillar 3 batches (nomarchy-restart-{hyprctl,mako,tmux}, nomarchy-battery-present, nomarchy-sudo-keepalive, nomarchy-rollback, nomarchy-snapshot, nomarchy-migrate-state, nomarchy-config-direct-boot, nomarchy-npx-install, nomarchy-webapp-handler-{hey,zoom}), no stray omarchy/omacom strings outside historical roadmap entries, and every state.json field-write resolves against lib/state-schema.nix (or the documented off-schema welcome_done). One UX-shaped pattern bug logged separately to Later: show_setup_config_menu edits Nix-managed files that get clobbered on the next home-manager switch. Runtime verification (run every user-visible menu entry and confirm it does the thing) remains on the user.

  • 2026-05-21Pillar 8 / Component 7 (Theme engine + palettes): closeout. Code-review-shaped sweep across themes/engine/{stylix,stylix-compat,loader,files,scripts}.nix, the 23 theme-engine scripts, and the 21 palettes' file completeness. Three real fixes inline + targeted dead-surface cleanup: (1) nomarchy-theme-set printed a warning when the named theme directory didn't exist but continued executing — wrote the bad name into state.json and ran nomarchy-env-update on a broken state. Now exit 1 after the warning. (2) nomarchy-theme-bg-set (called by the walker background-selector menu and by the nomarchy-wallpaper CLI) updated the live ~/.config/nomarchy/current/background symlink + restarted swaybg but never wrote state.json — so every wallpaper picked via either path silently reverted to the theme default on the next home-manager switch (themes/engine/files.nix re-resolves nomarchy.wallpaper at every rebuild). Now writes the chosen path into state.json.wallpaper, mirroring nomarchy-theme-bg-next. Added a file-exists check so a bogus path fails loudly instead of leaving a dangling symlink + a crashed swaybg. (3) Palette tree dead-surface cleanup: deleted themes/palettes/{flexoki-light,lumon,retro-82,rose-pine}/apps/chromium.theme (9-byte RGB strings nothing reads — chromium is themed via managed policies in core/system/browser.nix, not per-palette files) and themes/palettes/summer-day/apps/kitty/{kitty.conf,everforest-light.conf} (a 76KB stray kitty config at the wrong nested path, superseded by the kitty.conf generator added in 8d3ce2d). Total: 6 files / 2210 lines. Updated the misleading comment in nomarchy-themes-prebuild ("the installer wires this up") to reflect reality (the installer only tips the user to run it). Updated the themes/templates/*.tpl Later row with a fact-check + concrete categorisation — the templates ARE consumed by nomarchy-theme-set-templates, but most write to paths nothing reads or are now superseded by Nix-side generators. Palette completeness matrix: all 21 palettes have colors.toml, backgrounds/, icons.theme, and apps/; 5 carry the light.mode marker (catppuccin-latte, flexoki-light, rose-pine, summer-day, white); only tokyo-night ships keyboard.rgb for the ASUS ROG path, and the keyboard-set chain isn't wired into nomarchy-theme-set so it stays manual — niche enough to leave. Runtime verification (switch through all 22 palettes and eyeball SDDM + Plymouth + GTK + Qt + terminals + browsers + waybar + walker rendering) remains on the user.

  • 2026-05-21Pillar 8 / Component 6 (Apps): closeout. Code-review-shaped sweep over features/apps/{alacritty,btop,chromium,elephant,ghostty,kitty,lazygit,opencode,swayosd,tmux,vscode,walker}. Three real theming bugs fixed inline: (1) features/apps/kitty/config/kitty.conf:1 and features/apps/ghostty/config/config:2 referenced palette-specific include files (~/.config/nomarchy/current/theme/{kitty,ghostty}.conf) that didn't exist for any of the 22 palettes — kitty include failed silently, ghostty's was optional (?-prefix), and both terminals rendered with their built-in defaults regardless of the active Nomarchy palette. Stylix's kitty.enable = true was a no-op because the module uses xdg.configFile instead of programs.kitty; ghostty has no Stylix target. Added theme-engine generators in themes/engine/files.nix mirroring the existing waybar.css pattern, mapping palette.base* to kitty/ghostty color directives. (2) features/apps/btop/config/btop.conf:5 set color_theme = "current" but themes/engine/loader.nix:72 deploys the active palette's btop theme to ~/.config/btop/themes/nomarchy.theme — name mismatch, btop fell back to its built-in Default theme on every palette. Renamed to "nomarchy". (3) programs.vscode.profiles.default.userSettings.workbench.colorTheme was set unconditionally from themes/palettes/<theme>/apps/vscode.json, but the matching theme extensions were bundled with devExtensions (default false) — so VSCode silently fell back to its built-in theme out of the box on every palette. Split themeExtensions (always-on, covers the 6 palettes whose theme extension is in nixpkgs) from devExtensions (opt-in). The remaining 15 palettes — including the default summer-night (sainnhe.everforest) — still break because their theme extensions aren't packaged in nixpkgs; logged as a new Later row. Chromium static Default/Preferences symlink already had an open Later row; verified the file's contents are duplicate of the managed-policy intent in core/system/browser.nix, so the existing entry's hypothesis is correct — left for the user to greenlight deletion. alacritty (Stylix-themed via programs.alacritty.settings), elephant (no UI), swayosd (base16 inline), walker (covered in Component 5), lazygit + tmux (terminal ANSI inheritance, transitively fixed by the kitty/ghostty changes), and opencode (minimal opt-in config) are healthy. Runtime verification (launch each app on each palette and eyeball the theming) remains the user's responsibility.

  • 2026-05-21Pillar 8 / Component 5 (Desktop stack): closeout. Code-review-shaped sweep over Hyprland, waybar, walker, hypridle, hyprsunset, mako, KEYBINDINGS.md (the runtime-rendering subset — waybar across panel positions × form factors × all 22 palettes, walker launcher modes, hypridle timeout feel — stays on the user). Five real bugs fixed inline: (1) 9 of 17 ~/.config/nomarchy/default/hypr/apps/*.conf window-rule files were deployed but never sourced, including system.conf (the tag +floating-window rules every TUI helper class relies on + class:org.nomarchy.screensaver fullscreen rule that hypridle's 150s on-timeout depends on) and pip.conf (the PiP pin/size rules). apps.conf now sources all 17. (2) Two $NNOMARCHY_TOGGLE_* typos (double-N) in nomarchy-menu:330 and nomarchy-launch-screensaver:16 made toggles.suspend and toggles.screensaver vacuous — Suspend always showed in the system menu and the screensaver always launched at idle regardless of the documented option. (3) 4 broken per-palette waybar style.css overrides (catppuccin, lumon, nord, retro-82) fully replaced the default style with 214 lines of only @define-color declarations — picking those palettes produced a waybar with zero structural styling. Default style already imports per-palette colors via themes/engine/files.nix-generated theme/waybar.css, so deletion restores correct rendering; summer-day/summer-night kept as legitimate 100+-line redesigns. (4) core/home/config/nomarchy/default/hypr/{bindings,plain-bindings}.conf were explicitly-labeled deprecated files sourced by nothing (plain-bindings.conf referenced undefined $terminal/$browser/etc. Hyprland vars) — deleted; docs/SCRIPTS.md regenerated to drop stale callers and incidentally corrected 4 Origin columns whose scripts moved from core/system/scripts/ to features/scripts/utils/. (5) Mako post-fix (commit 2a301a0) verified: deployment + the 4 referenced scripts (nomarchy-notification-dismiss, nomarchy-launch-wifi, nomarchy-launch-floating-terminal-with-presentation, nomarchy-menu-keybindings) all resolve. Two structural inconsistencies logged to Later: keymap routing (already in 72f7e7b) and the new hyprsunset toggle-vs-systemd reconcile. KEYBINDINGS.md regenerated with zero diff — generator already covers both binding source locations. Runtime verification (boot live ISO, eyeball waybar/walker/screensaver flows across panel positions and palettes) remains the user's responsibility before declaring Component 5 fully closed.

  • 2026-05-18 — Hardware DB correctness pass + ROG Ally support + CI lint. Audited every nomarchy-hardware-db entry against inputs.nixos-hardware.nixosModules and found 21 of 43 entries (49%) referenced modules that don't existmicrosoft-surface-pro-8, lenovo-thinkpad-x1-carbon-gen11, framework-13-11th-gen-intel, etc. were all eval-time failures waiting for a real user. Rewrote the DB to use only valid module names: Framework gens dropped the "13-" prefix in nixos-hardware (framework-11th-gen-intel, not framework-13-11th-gen-intel); ThinkPad X1 modules are x1-Nth-gen, not x1-carbon-genN; Surface Pro 6/7/8/10 all share microsoft-surface-pro-intel; Surface Book / Intel Surface Laptop have no module (rows dropped, generic detection still emits sensible common-pc-laptop + cpu/gpu). Added matchers for ROG Ally (RC71L / RC72LA / "ROG Ally" via asus-ally-rc71l). Documented Steam Deck and Snapdragon X as nixos-hardware-unsupported in a footer comment (Steam Deck → Jovian-NixOS; Snapdragon X → installer is x86_64 only). Added a CI step (.forgejo/workflows/check.yml) that fails on any DB entry whose module name isn't in nixos-hardware.nixosModules — closes this regression class.

  • 2026-05-18nomarchy-manual re-targeted at local docs. The script's xdg-open previously pointed at https://learn.omacom.io/2/the-nomarchy-manual — an upstream Omarchy URL that opened an unrelated page when users hit the menu's Help entry. Now opens ~/.local/share/nomarchy/README.md (the local docs index per SKILL.md's "Out of Scope" note), with a notify-send fallback if the source tree isn't synced.

  • 2026-05-18 — Docs hygiene: STRUCTURE.md "Root Directory" + Pillar 6 reality-check. docs/STRUCTURE.md listed three top-level files that don't exist (GEMINI.md, root-level STRUCTURE.md, TODO.md) — replaced with an accurate root listing plus a docs/ sub-tree that names every doc. Pillar 6 in this file had nomarchy-welcome, docs/TROUBLESHOOTING.md, and the "docs index" bullet still marked Next despite all three shipping on 2026-04-26 — moved to (Shipped). nomarchy-manual bullet's "orphaned reference today" claim was stale (the script is called from nomarchy-menu and nomarchy-theme-install); rewritten to reflect the real remaining issue — its hardcoded xdg-open https://learn.omacom.io/2/the-nomarchy-manual is an Omarchy URL.

  • 2026-05-18 — Installer state.json is now schema-driven. Replaced the heredoc in installer/install.sh that hardcoded the JSON literal (theme/dns/wifi/features/etc.) with a nix eval of lib/state-schema.nix's system block, overlaid with the installer-chosen timezone. Closes the last source-of-truth split after the centralization batch — adding a new default in the schema now reaches the installer with no further plumbing. Output is identical modulo alphabetical key ordering (Nix's builtins.toJSON sorts keys; toggle scripts read/write via jq so it's invisible to them). Dry-run path unchanged (still bind-mounts a fake /mnt so the generator's absolute paths resolve correctly). bash -n + shellcheck --severity=error clean.

  • 2026-05-18 — Complete the hybrid-GPU wiring + fix unoverridable state-derived options. Two related fixes shipped together. (1) nomarchy.system.features.hybridGPU = true now wires the full NVIDIA driver stack (services.xserver.videoDrivers = ["nvidia"], hardware.graphics.{enable,enable32Bit}, hardware.nvidia.{modesetting,powerManagement}.enable, package = nvidiaPackages.stable, boot.kernelParams += "nvidia-drm.modeset=1") — was previously enabling only supergfxd mode-switching while leaving the system with no NVIDIA driver loaded, so mode switches silently no-op'd. All knobs use lib.mkDefault so a downstream system.nix can pin a beta driver, flip to the open kernel module, etc. Bus-ID prime config (per-machine) stays user-supplied — docs/OPTIONS.md has the full recipe. (2) Both core/system/state.nix and core/home/state.nix now use lib.mkDefault on every state.json-derived assignment, fixing a class of "I set X in my system.nix but it doesn't take effect" bugs (the state-derived value was at default priority and conflicted with the user's same-priority override). Side-effect cleanup: core/system/state.nix now also reads from lib/state-schema.nix like core/home/state.nix does, completing the schema-centralization started two batches ago. Verified nix flake check + an override test that flips hybridGPU via an overlay and confirms the entire driver stack engages.

  • 2026-05-18 — Pillar 4: pre-flight resume polish. Fixed four resume-flow gaps in installer/install.sh: (1) --resume with a missing state file now errors loudly with a tmpfs explanation instead of silently falling through to a fresh prompt cycle (the most common operator confusion was "rebooted, forgot tmpfs eats /tmp/, watched the installer start over without realising"); (2) on resume, the saved target drive is validated as a block device before any disk-phase step runs — catches the live-ISO USB-unplugged / non-deterministic /dev/sdX class of mid-install failures; (3) save_state now stamps an ISO-8601 timestamp and load_state shows a (saved Xm ago) banner plus a Target: /dev/X → user @ host summary line, so the user can Ctrl-C if they're resuming onto the wrong host before any destructive prompt fires; (4) --help now documents the tmpfs limitation. shellcheck --severity=error passes.

  • 2026-05-18 — Declarative-state defaults centralization. Made lib/state-schema.nix the single source of truth for every state-default that previously lived in three places (the schema itself, core/system/options.nix / core/home/options.nix default = … clauses, and core/home/state.nix or … fallbacks). Replaced ~25 hardcoded literals with schema.<scope>.<key> reads. Side-effect: fixed a lingering bug where core/home/options.nix:theme still defaulted to "summer-night" after the system-side was moved to "nord" — half the codebase's home option resolved to the wrong theme when state.json was missing/blank. nix flake check --no-build confirms zero semantic change for every other field. Doesn't touch the installer-written state.json (separate batch — needs schema → JSON generation).

  • 2026-05-18 — Pillar 7 first step: Forgejo Actions CI (eval + lint). New .forgejo/workflows/check.yml runs on every push to main and every PR: (1) nix flake check --no-build to catch eval regressions, (2) bash -n + shellcheck --severity=error over every nomarchy-* bash script (whole-tree, not just changed files — gates branches that bypass the pre-commit hook), (3) docs/SCRIPTS.md drift check (fails loudly if a script change didn't regenerate the audit doc). All three checks pass locally on the current tree. Activation requires enabling Actions on the Forgejo repo and registering a forgejo-runner; the workflow itself is dormant until then. ISO build job is intentionally deferred — needs a binary cache (Cachix/Attic) to be tractable.

  • 2026-05-18Pillar 3 Phase B: complete. Final batch (restart/sudo/theme/misc clusters) cleared the last 13 unused? rows. Deleted five truly dead scripts: nomarchy-restart-{hyprctl,mako} (theme switching calls hyprctl reload/makoctl reload directly now), nomarchy-restart-tmux (one-liner of marginal value), nomarchy-battery-present (battery monitor checks /sys/class/power_supply/BAT* inline), nomarchy-sudo-keepalive (intended-to-be-sourced building block with no users). Surfaced eight useful tools in SKILL.md so the audit catches them as kept and AI assistants can discover them: nomarchy-restart-trackpad (intel_quicki2c reload), nomarchy-sudo-{passwordless-toggle,reset}, nomarchy-theme-{bg-install,refresh,remove}, nomarchy-refresh-fastfetch, nomarchy-windows-vm (new Virtualization section). Final state: 159 scripts, all kept, unused? = 0, missing references = 0.

  • 2026-05-18 — Pillar 3 Phase B: webapp/tui/voxtype install-remove pair triage. Deleted two dead webapp URI handlers (nomarchy-webapp-handler-hey, nomarchy-webapp-handler-zoom) — no .desktop MimeType registration anywhere routed mailto:/zoom: URIs to them, so the handlers could never fire. Surfaced six useful CLI tools in SKILL.md "Common Tasks" so they're discoverable by AI assistants and tagged kept by the audit: nomarchy-webapp-{remove,remove-all}, nomarchy-tui-{remove,remove-all}, nomarchy-voxtype-{install,remove}. Script count 166 → 164; unused? 21 → 13.

  • 2026-05-18 — Pillar 3 Phase B: dead-code sweep (NixOS-irrelevant Omarchy ports). Deleted five scripts that duplicated NixOS-native facilities or referenced infrastructure Nomarchy doesn't ship: nomarchy-rollback (boot-menu generations + nixos-rebuild rollback already cover this), nomarchy-snapshot (used snapper; impermanence and BTRFS subvolumes are the Nomarchy answer), nomarchy-migrate-state (one-shot pre-unification migration, no current callers), nomarchy-config-direct-boot (added an EFI entry for a UKI we never build), and nomarchy-npx-install (Arch idiom — nix-shell -p nodejs is the NixOS path). Kept nomarchy-build-iso and nomarchy-build-live-iso and surfaced them in README §2 so the audit tags them kept. Script count 171 → 166.

  • 2026-05-18 — Pillar 3 Phase B: missing-references triage. (1) Wrote themes/engine/scripts/nomarchy-theme-next so SKILL.md's documented "cycle to next theme" command resolves; (2) scrubbed three stale nomarchy-dev-* references from core/home/config/nomarchy-skill/SKILL.md; (3) added a line-context filter to both nomarchy-docs-scripts generators that drops nomarchy-* tokens appearing in Nix pname/derivation idents, /tmp/ & /etc/sudoers.d/ paths, nixosConfigurations.* / packages.* flake outputs, mktemp -t prefixes, systemd unit vars, ./result/bin/run- binaries, and docker container references; (4) added a small token-level denylist for five residual non-script identifiers (nomarchy-plymouth, nomarchy-sddm-theme, nomarchy-live, nomarchy-rev, nomarchy-windows) that survive line filtering. docs/SCRIPTS.md "Missing references" section is now empty (was 15).

  • 2026-05-04 — Pillar 8: Distro Branding. (1) Scrubbed remaining "Omarchy" and "Spirit of Omarchy" references from README, scripts, and welcome wizard; (2) Updated nomarchy-welcome banner and nomarchy-version codename ("Sovereign"); (3) Verified existing core/system/branding.nix handles OS-release and bootloader labels; (4) Confirmed SDDM and Plymouth metadata are already Nomarchy-branded.

  • 2026-05-04 — Thorough Out-of-the-Box QA Audit. (1) Restored automatic wallpaper switching by removing image filters from deployed themes; (2) Fixed broken "Style" menu entries by creating missing about.txt and screensaver.txt branding files; (3) Cleaned up conflicting keybindings by removing deprecated tiling.conf and updating the doc generator; (4) Removed legacy Nord theme hack from nomarchy-theme-set; (5) Fixed JSON parse error in summer-day waybar theme.

  • 2026-05-03 — Fixed multi-disk LUKS/BTRFS boot hang. (1) Moved temporary LUKS keyfile to /tmp/ so Disko correctly omits it from the runtime configuration; (2) Injected x-systemd.requires and x-systemd.device-timeout=0 into BTRFS mount options to ensure all LUKS drives are decrypted before mounting.

  • 2026-05-03 — Fixed CLI wrappers and removed obsolete code. (1) Updated nomarchy-font, nomarchy-theme, and nomarchy-wallpaper CLI wrappers to use modern Walker menus; (2) Removed the obsolete and broken themes/engine/switcher.nix and its associated Nix-inlined scripts; (3) Cleaned up remaining $NOMARCHY_PATH references from the Omarchy era.

  • 2026-05-03 — Fixed /etc/nixos ownership after installation. Added a chown -R $USERNAME:users /etc/nixos step via nixos-enter at the end of installer/install.sh so the main user owns their configuration and can run home-manager commands without sudo.

  • 2026-05-01 — Installer & Script Audit Polish. (1) Fixed a critical bash dynamic scoping bug in installer/install.sh where rc=0 assignments inside functions (Impermanence, Form Factor) were clobbering the main loop's return code, causing the installer to abort when "No" was selected; (2) Polished hosts/nomarchy-live.nix with auto-login for the nixos user and passwordless sudo for the wheel group; (3) Repurposed nomarchy-toggle-suspend to execute systemctl suspend directly and updated nomarchy-menu to reflect this; (4) Updated nomarchy-launch-wifi to use nmtui in Alacritty; (5) Regenerated docs/SCRIPTS.md to reflect the updated script mappings.

  • 2026-04-30set -e sweep across nomarchy-* scripts. Added set -e to 142 of 169 bash scripts that lacked it (27 already had it). Halts a class of "command failed silently in the middle of a chain, system left in half-applied state" bugs that produced repeat-fix commits. One deliberate exception: nomarchy-menu runs without set -e because it's an interactive UX loop where action failures should re-display the menu rather than abort the script. Pre-commit hook now enforces bash -n + shellcheck --severity=error so future scripts can't regress this.

  • 2026-04-30 — Installer disk-phase reliability. Hardened installer/install.sh and consolidated the disko configs: (1) select_disk now hides the live-ISO boot device(s) so the installer can't format its own boot media (NOMARCHY_INSTALL_ALLOW_ISO_TARGET=1 to override); (2) added a 10 GiB minimum-capacity preflight; (3) prewipe_target_drive enumerates every active dm-crypt mapping backed by the target drive and closes them, drops the silent || true from wipefs/sgdisk/dd, bounds udevadm settle to 30s, and refuses to continue if anything is still mounted; (4) wrapped the disko call in run_disko_with_retry with last-30-lines + Retry / View full log / Abort dialog on failure; (5) replaced the sed-templated disko-golden.nix + disko-btrfs-multi.nix pair with a single disko-config.nix Nix function called via --argstr mainDrive … --arg extraDrives '[…]' — eliminates a class of escaping bugs (cf. 3aadc36); (6) added an EXIT trap so the tmpfs LUKS key file is removed even on early abort.

  • 2026-04-30 — Gaming home-side companion. New nomarchy.gaming.enable option (mirror of nomarchy.system.gaming.enable) and core/home/gaming.nix module that injects a Hyprland windowrulev2 = fullscreen, class:^(steam_app_).*$ so Steam-launched games grab the whole screen. Closes the "Gaming — Hyprland window rule" Next-column row.

  • 2026-04-26 — Default to highest resolution (highres) for monitors. Updated features/desktop/hyprland/config/monitors.conf and forced it in the live ISO (nomarchy-live) to resolve issues where some hardware would default to a low resolution (1024x768).

  • 2026-04-26 — First-run welcome wizard (nomarchy-welcome). Extended from a one-shot greeter into a guided picker for theme, font, and panel position. Added Step 4 to generate a starter home.nix if missing. State is now persisted in state.json via .welcome_done. Added nomarchy.panelPosition option to Waybar.

  • 2026-04-26 — Multi-disk BTRFS support in the installer. Added installer/disko-btrfs-multi.nix template and updated installer/install.sh to allow selecting multiple drives via gum choose --no-limit. Implements BTRFS "single" data + RAID1 metadata across multiple LUKS-encrypted drives.

  • 2026-04-26 — Distro Branding Phase 2. Updated bootloader entries to use "Nomarchy" as the label. Set ISO volume IDs to NOMARCHY_INSTALLER and NOMARCHY_LIVE. Fixed branding in Plymouth theme metadata and SDDM metadata.

  • 2026-04-26 — Distro Branding Phase 1. Renamed installerIso to nomarchy-installer and installerIsoGraphical to nomarchy-live. Updated metadata and host configurations. Scrubbed "Omarchy" from Plymouth and installer messages.

  • 2026-04-26 — Fix hardware-db.sh missing in nomarchy-installer.nix. Resolved boot error where install.sh failed to source the hardware database on the TTY installer ISO.

  • 2026-04-26 — Installer review-then-edit flow (installer/install.sh). Review screen now offers Continue / Edit a field / Abort. Edit opens a multi-select of saved fields; chosen fields clear and the next loop iteration re-prompts only those. Benefits both fresh installs (typo fixes without abort+restart) and --resume (lands on review immediately, since the loaded vars short-circuit each prompt). LUKS passphrase is held in memory across loop iterations so re-edits don't re-ask for it.

  • 2026-04-26docs/TROUBLESHOOTING.md. The five most common rebuild errors (option-already-declared, attribute-missing, Stylix target conflict, home-manager .hm-bak churn, impermanence path missing) with copy-paste fixes. Linked from README.md and docs/MIGRATION.md.

  • 2026-04-26 — Gaming preset module (core/system/gaming.nix). Opt-in nomarchy.system.gaming.enable (default false). Wires programs.steam (with remotePlay/localNetworkGameTransfers firewall holes via mkDefault), programs.gamemode, and services.flatpak. Flathub remote and Hyprland window-rule split into separate Next-column rows.

  • 2026-04-26 — Accessibility preset module (core/system/accessibility.nix). New nomarchy.system.accessibility.{enable,cursorSize} options (opt-in, default off — accessibility isn't a hardware-derived signal). Enables services.gnome.at-spi2-core, installs Orca, and sets XCURSOR_SIZE=32 (configurable). Hyprland-side companion (key-repeat slowdown, Orca keybinding, high-contrast palette) split into a new Next-column row.

  • 2026-04-26 — Desktop preset module (core/system/desktop.nix). New nomarchy.system.desktop.enable option; defaults to formFactor == "desktop" (mirror of the laptop preset's auto-enable). Pins powerManagement.cpuFreqGovernor to "performance" and enables services.zfs.{autoScrub,trim} so a future ZFS pool gets sensible maintenance for free.

  • 2026-04-26 — Laptop preset module (core/system/laptop.nix). New nomarchy.system.laptop.{enable,thermald} options; enable defaults to formFactor == "laptop" so the installer's existing formFactor write auto-flips it on. Wires TLP (governors + 75/80 charge thresholds), force-disables power-profiles-daemon, enables upower and thermald (x86_64), adds the brightnessctl udev rule for backlight without root, and sets a logind lid-switch policy that defers to hibernation.enable. Closes both the Now item and the largest Next item.

  • 2026-04-25 — Software-profile multi-select in the installer. Users can now pick Dev, Gaming, Office, Media, and CLI Utils profiles during install; logic emits corresponding home.packages and system toggles into the generated config.

  • 2026-04-25 — Pillar 3 Phase B: script & menu audit. Ported/implemented/stubbed ~40 scripts including nomarchy-version, nomarchy-debug, nomarchy-reinstall, nomarchy-rollback, nomarchy-update-firmware, nomarchy-pkg-*, and nomarchy-theme-* wrappers. Moved desktop scripts to packaged utility directory.

  • 2026-04-25 — Docker & fwupd support. Added nomarchy.system.virtualization.docker.enable and nomarchy.hardware.fwupd options. Wires system services and adds docker-compose and fwupdmgr to PATH.

  • 2026-04-25 — Installer VM testing. Added installerVm to flake nixosConfigurations, packages, and apps. nomarchy-test-installer now uses nix run .#installerVm.

  • 2026-04-25docs/KEYBINDINGS.md auto-generator. New repo-tooling script bin/utils/nomarchy-docs-keybindings parses every bindd = / bindeld = line into a Markdown doc; README's keybinding table slimmed to highlights + link.

  • 2026-04-25 — Installer disk picker shows NAME / SIZE / TYPE / VENDOR / MODEL / SERIAL columns instead of bare lsblk. Type derived from ROTA + TRAN (NVMe / USB / SSD / HDD). Filters loop, ram, zram, sr.

  • 2026-04-25 — Pillar 3 Phase A: script & menu audit. New bin/utils/nomarchy-docs-scripts generator produces docs/SCRIPTS.md with 136 scripts and the menu walk pre-tagged via heuristics (kept / unused? / missing). Phase B (per-batch porting / removal) opens.

  • 2026-04-25 — Installer prompts for keyboard layout + locale, applies live; new nomarchy.{system,}.formFactor option; waybar drops battery widget on desktop; nm-applet visibility fix in default theme; live-ISO baseline keymap/locale (a7e7fa9).

  • 2026-04-25docs/OPTIONS.md reference; docs/MIGRATION.md linked from README.md (3cb012b, 6ef28f0).