The default theme's clock#date wired 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 uses xdg-terminal-exec/alacritty for its
clicks and summer-day's date has no on-click. Drop the dead action
(tooltip: false), matching summer-day.
Found during the Pillar 9 Component 6 (apps) pass, which confirmed
btop/ghostty/kitty/lazygit/tmux ship config-only by design (the
installer/user picks the binary) — not a bug. Logged two follow-ups:
summer-day's wofi --term=kitty launcher, and shipping a calendar app.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The summer-night waybar config defined a custom/battery module
(exec nomarchy-battery-status) but never listed it in any modules-*
slot, so it was orphaned and never rendered. summer-night is the
default theme, so a laptop on a stock install had no battery
indicator — the default fallback config and the summer-day theme
both place battery in modules-right; only summer-night omitted it.
Add custom/battery to summer-night's modules-right. The formFactor
filter (laptopOnlyModules) already lists custom/battery, so it shows
on laptop and is dropped on desktop. Found during the Pillar 9
Component 9 (form-factor split) verification pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Found by driving the menu's observable actions live in a VM with the real
session env imported. All three are also bound to keybindings.
1. nomarchy-hyprland-window-single-square-aspect-toggle (1-Window Ratio,
SUPER CTRL BACKSPACE): read/set layout:single_window_aspect_ratio, which
is "no such option" in Hyprland 0.52.1 — the option lives under dwindle:.
The getoption returned nothing and the keyword set was silently dropped,
so the toggle did nothing. Point it at dwindle:single_window_aspect_ratio.
2. nomarchy-hyprland-workspace-layout-toggle (Workspace Layout, SUPER L):
read .tiledLayout off `hyprctl activeworkspace -j` (no such key → always
null) and switched to "scrolling" (not a built-in layout — hyprctl
layouts lists only dwindle/master), so it silently no-op'd. Rewrite to
toggle the real general:layout between dwindle and master.
3. show_setup_menu offered Power Profile unconditionally, but powerprofilesctl
is absent everywhere (power-profiles-daemon is force-off on laptop in
favour of TLP and never enabled on desktop), so the entry died with
"command not found". Gate it behind `command -v powerprofilesctl`.
Verified (1) and (2) against live Hyprland in the VM: aspect flips
[0,0]<->[1,1], layout flips dwindle<->master.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All three confirmed real on inspection.
1. nomarchy-refresh-config was dead on every system: it read
/etc/nixos/nomarchy/{core/home/config,features} (the source tree never
lands there — only /etc/nomarchy on VM-guest/live ISO) and fell back to
~/.local/share/nomarchy/config, which nothing deployed despite SKILL.md
documenting it. Deploy the pristine core/home/config tree to
~/.local/share/nomarchy/config via xdg.dataFile and read from there, so it
works without a source checkout; its live caller nomarchy-refresh-fastfetch
now succeeds. Fix two stale SKILL.md examples (waybar/, hypr/) that pointed
at non-existent stock paths.
2. nomarchy-docs-scripts shipped a stale divergent copy in
features/scripts/utils/ (in the user nomarchy-system-scripts package)
beside the canonical bin/utils dev tool — it errored outside the repo.
Grounding it surfaced the identical bug in nomarchy-docs-keybindings.
Delete both duplicates, add them to the generator's self-reference
denylist so they don't show as false `missing`, regenerate 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.
Add an idempotent home-manager activation seed in core/home/state.nix that
backfills the resolved values (defaults * existing — 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.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The "mkDefault everywhere user might override" rule is what caused the
home.packages bug. Clarify: mkDefault is for scalars; on list/attrset
options that other modules contribute to, a mkDefault def is dropped
entirely (filterOverrides) rather than merged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New pillar to drive the distro running in a VM and verify what actually
works vs. what only looks right in source: run every nomarchy-* command,
walk every menu entry, switch through all 22 palettes and eyeball
rendering, fire every keybinding, drive the installer. Documents the
method (build -> boot headless -> screendump/sendkey) proven in the first
VM-boot pass, the per-component checklist, and the deliverable format. The
old "Pillar 8 runtime verification" Now-board punch-list folds into it.
AGENT.md's verify step now points at the headless VM screenshot flow.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These three home options (Hyprland inner/outer gaps + active-border width,
read from state.json, wired in features/desktop/hyprland/default.nix) were
the only real options missing from OPTIONS.md — a guardrail violation
(every nomarchy.* option must be documented). Found via a full diff of the
live option tree against the doc's headings.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI's drift check failed on pure ordering noise: the generator's `sort`
collated rows and caller lists by the ambient locale (en_GB.UTF-8 on the
dev box that committed the file, C in the CI container), so `-` vs `/` and
`-` vs `s` ordered differently (e.g. theme-update vs themes-prebuild,
caller-list order). Force LC_ALL=C in the generator and regenerate
docs/SCRIPTS.md in that collation, so the committed copy and any
regeneration — dev box or CI — are byte-identical.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The per-toggle + per-palette matrix did ~39 full-system evaluations (16
toggle toplevels + 21 palettes each via a full extendModules eval + 2
home) and ran ~2h55m on the small self-hosted runner — long enough to hit
act_runner's 3h container lifetime (sleep 10800) and get killed.
Redesign:
* Combine compatible toggles into 3 configs (laptop-stack, desktop-stack,
impermanence-multi) instead of one eval per toggle. A failure means
re-run the suspect toggle alone; the trace hint covers that.
* Check palettes directly via the lib — the per-palette risk is the pure
base00 -> RGB hex math in plymouth.nix, which needs no module-system
instantiation. Forcing the palette attrset also catches a missing one.
* Drop the home configs; the per-output flake-check step already forces
both homeConfigurations.
~39 full evals -> 3, plus a near-instant palette pass. Runs in ~1m locally
(warm). AGENT.md updated for the new combined-scenario structure.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Gitea only scans .gitea/workflows and .github/workflows; it does not scan
.forgejo/workflows (that path is Forgejo-only). The CI was therefore
dormant on a Gitea instance regardless of whether Actions was enabled.
git mv to .gitea/workflows/ (scanned by both Gitea and Forgejo). Updated
the live references in STRUCTURE.md (Gitea + act_runner), AGENT.md, and
today's ROADMAP entry; left the dated historical Shipped entries as the
changelog they are.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nix flake check --no-build only evaluates the four default configs, so a
bug that only fires when a nomarchy.* toggle is flipped sails through —
exactly how the vscode option rename and the impermanence systemd-stage-1
assertion both reached main undetected.
Add bin/utils/nomarchy-eval-matrix: layers each opt-in scenario (16
toggles, both system and home halves) onto nixosConfigurations.default
via extendModules and forces system.build.toplevel.drvPath (which forces
assertion checks); also forces all 21 palettes through the system-side
Plymouth base00->RGB math that the home-only allThemeVariants never
reaches, plus both standalone homeConfigurations. Per-scenario results
come from builtins.tryEval so one failure doesn't mask the rest; verified
it goes red on a re-injected assertion failure and a bad option ref, green
on the current tree.
Wired into .forgejo/workflows/check.yml after flake check (jq via nix
shell so it doesn't depend on the runner image). AGENT.md §5 now tells
future agents to add a scenario when they add/rename an opt-in option.
nomarchy-docs-scripts: filter systemd-service declarations (.services.
nomarchy-) and denylist the eval-matrix repo tool so neither shows as a
dangling "missing" reference; also retroactively clears the latent
nomarchy-flathub-init drift from the gaming-flathub commit.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
themes/engine/plymouth.nix enables systemd stage-1 initrd
(boot.initrd.systemd.enable) distro-wide, and Plymouth is imported
unconditionally from core/system/default.nix. systemd stage 1 hard-rejects
boot.initrd.postDeviceCommands with a failed assertion, so every config
with nomarchy.system.impermanence.enable = true — including installs that
chose impermanence at the installer prompt — failed to evaluate.
Convert the Erase-Your-Darlings rollback to a boot.initrd.systemd.services
oneshot unit ordered after the LUKS mapping opens and before sysroot.mount,
and add boot.initrd.systemd.initrdBin for btrfs-progs/coreutils/util-linux/
findutils (the systemd initrd doesn't ship them by default). Script body is
unchanged. Verified eval via extendModules on nixosConfigurations.default;
boot-time wipe semantics still need a real wipe-boot cycle (Pillar 8).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Before this fix, only the 6 palettes whose theme extensions ship in
pkgs.vscode-extensions had working VSCode theming. Every other palette
had `workbench.colorTheme` set to a name VSCode couldn't find, so it
silently fell back to its built-in default. Including the DEFAULT
summer-night palette (sainnhe.everforest) — the default install had
broken VSCode theming.
Probed the 13 unique extensions against the VSCode marketplace
extensionquery API:
- 10 exist and are pinnable: 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.
- 3 don't exist on the marketplace and are unpublished custom
Nomarchy themes: Bjarne.{ethereal,hackerman,vantablack}-nomarchy.
Logged as a new Later row.
For the 10, fetched version + sha256 via:
URL='https://${publisher}.gallery.vsassets.io/_apis/public/gallery/publisher/${publisher}/extension/${name}/${version}/assetbyname/Microsoft.VisualStudio.Services.VSIXPackage'
nix store prefetch-file --hash-type sha256 "$URL"
Added a marketplaceExtensions list to features/apps/vscode.nix that
wraps each in pkgs.vscode-utils.extensionFromVscodeMarketplace and
concatenates with the existing nixpkgs-packaged list — so 10 more
palettes (including the default) now get correct VSCode theming on
first launch. Smoke-built sainnhe.everforest end-to-end. Module
comment documents the version-bump procedure.
docs/OPTIONS.md updated: the nomarchy.vscode.devExtensions entry
drops the "still break" caveat for everything except the three
unpublished Bjarne palettes.
`nix flake check --no-build` clean.
features/apps/chromium/default.nix was deploying a 204-byte static
Default/Preferences via Home Manager symlink into Chromium's mutable
profile directory. The deployment is structurally broken — Chromium
expects to write that file at runtime, so either the symlink is
silently replaced on first save (losing the static defaults) or the
write fails silently.
The contents are also redundant + incorrect:
- `extensions.theme.{use_system,use_custom} = false` — already
superseded by the managed-policy approach (BrowserThemeColor
overrides any user-installed theme extension regardless).
- `browser.theme.{color_scheme,user_color} = 2` — hardcoded "dark"
via Chromium's color_scheme enum, conflicting with the dynamic
BrowserColorScheme = isLightTheme ? "light" : "dark" set by
core/system/browser.nix. A user on flexoki-light / summer-day /
catppuccin-latte / rose-pine / white would have had a static-vs-
policy mismatch every time.
Removed the entire features/apps/chromium/ directory (default.nix +
config/Default/Preferences) 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.
`nix flake check --no-build` clean.
Moved the Next-column row → Shipped following commit 474bc16
("feat(plymouth): boot splash background follows the active palette").
Next column is now empty.
The option surface (`enable`, `paths`) lived in core/home/overrides.nix
since 2026-05-18 but didn't do anything — 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.
nomarchy.overrides.paths = {
"nomarchy/default/hypr/looknfeel.conf" = ./looknfeel.conf;
"waybar/style.css" = ./waybar.css;
};
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 get
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.
`nix flake check --no-build` clean.
New nomarchy.accessibility.enable home option mirroring
nomarchy.system.accessibility.enable. When enabled, core/home/
accessibility.nix contributes a Hyprland extraConfig block via
lib.mkAfter:
- input.repeat_rate = 25 (from 40)
- input.repeat_delay = 1000 ms (from 600)
Holding a key isn't a runaway machine-gun for low-mobility users.
- bindd = SUPER ALT, S, Launch Orca, exec, orca
The system preset already puts orca on PATH.
mkAfter guarantees the slowdown wins over the templated input.conf.
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.
`nix flake check --no-build` clean.
show_setup_config_menu was an Omarchy holdover where users edited
mutable config files at runtime. In Nomarchy:
- hyprland.conf, hypridle.conf, hyprsunset.conf, walker/config.toml,
waybar/config.jsonc are all Home-Manager-generated from declarative
settings — a `home-manager switch` clobbers any edit.
- hyprlock.conf and swayosd/config.toml point at paths the modules
don't deploy at all; open_in_editor created empty files.
- ~/.XCompose is a HM symlink into /nix/store — read-only.
Dropped the entire submenu function and the " Config" item from
show_setup_menu (and the matching *Config*) case branch). Persistent
settings go through the relevant nomarchy.* option in
/etc/nixos/home.nix (or system.nix); when the nomarchy.overrides.*
loader ships, a successor menu can route through
~/.config/nomarchy/overrides/.
Side effect (caught by the SCRIPTS.md regen): nomarchy-restart-xcompose
is now `unused?` — its only caller was the XCompose case I just
removed. Left for a future Pillar 3 cleanup rather than widening
this PR.
`bash -n` clean.
features/desktop/waybar/default.nix previously set
`programs.waybar.{enable,systemd.enable} = lib.mkDefault true`
unconditionally. The toggle script wrote .waybar to state.json and
pkill/exec'd waybar for instant feedback, but the next rebuild
re-enabled it because the Nix module didn't read the toggle. Result:
the bar came back on every rebuild/reboot regardless of the persisted
state — inconsistent with toggles.idle (gates services.hypridle.enable)
and now toggles.nightlight (gates services.hyprsunset.enable).
programs.waybar.{enable,systemd.enable} now follow
config.nomarchy.toggles.waybar. nomarchy-toggle-waybar flips the
running systemd user unit (`systemctl --user start/stop waybar.service`)
for instant feedback and writes .waybar back to state.json so the next
rebuild realigns. Disabled toggle now means no waybar across rebuilds
+ reboots, matching the option's documented meaning ("Whether the top
bar is enabled").
`nix flake check --no-build` + `bash -n` clean.
features/desktop/nightlight.nix previously set
`services.hyprsunset.enable = lib.mkDefault true` unconditionally and
baked the temperature (4000K when toggles.nightlight, 6500K otherwise)
into extraArgs at Nix-eval time. The toggle script bypassed systemd:
pkill on disable, `hyprctl dispatch exec hyprsunset --temperature 4000`
on enable — racing the systemd-managed instance and hardcoding 4000K
regardless of nomarchy.nightlightTemperature. The "Always enabled, we
control via IPC and state" comment was misleading: no IPC, the
temperature was rebuild-time, and the script forked a parallel
process.
Path (b) from the Later row:
- services.hyprsunset.enable now follows config.nomarchy.toggles.
nightlight — symmetric with services.hypridle.enable ← toggles.idle.
Disabled toggle = no process running.
- extraArgs always reads from config.nomarchy.nightlightTemperature.
Drops the 6500K neutralising fork; when off the unit just doesn't
start.
- nomarchy-toggle-nightlight flips the running systemd user unit via
`systemctl --user start/stop hyprsunset.service` for instant
feedback, reads nightlightTemperature from state.json for the
notify-send line, and writes .nightlight back to state.json so the
next rebuild realigns services.hyprsunset.enable.
`nix flake check --no-build` + `bash -n` clean.
core/home/config/nomarchy/default/hypr/input.conf hardcoded
`kb_layout = us`, so the installer's services.xserver.xkb.layout and
console.keyMap writes (both set from the installer's KEYMAP_LAYOUT
prompt) only reached XWayland apps and the TTY console. Native-Wayland
apps — i.e. almost everything in a Nomarchy desktop — fell back to US
regardless of what the user picked. Surprising for any non-US user.
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.
- Replaced it with an explicit
xdg.configFile."nomarchy/default/hypr/input.conf".text in
core/home/configs.nix that interpolates the option values into
kb_layout / kb_variant.
- Installer's home.nix heredoc now writes
nomarchy.keymap = { layout = "$KEYMAP_LAYOUT"; variant = "$KEYMAP_VARIANT"; };
alongside nomarchy.formFactor, so the layout reaches Hyprland
consistently with system.nix's xkb.layout / console.keyMap.
Documented in docs/OPTIONS.md (new `nomarchy.keymap.layout` /
`nomarchy.keymap.variant` entry). `nix flake check --no-build` clean.
flake.nix was re-importing ./themes/palettes and recomputing
themeNames via builtins.attrNames in its outputs `let`, even though
lib/default.nix already exports both. Two evaluations of the same
data, same result today — drift risk tomorrow as soon as one
computation grows extra logic the other doesn't.
Added `nomarchyLib = import ./lib { inherit lib; }` once and reused
it via `inherit (nomarchyLib) themeNames;` for the allThemeVariants
linkFarm. The local `palettes` binding wasn't read by anything else in
the outputs so it goes away with the rewrite. lib/default.nix is now
the single source of truth for the theme list; modules under core/
and themes/engine/ already import ../../lib the same way and resolve
to the identical evaluation.
`nix flake check --no-build` clean.
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
or 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.
themes/templates/ shipped 11 mustache templates, but
nomarchy-theme-set-templates only writes to a path when no file is
already there — and a careful trace shows 9 of the 11 outputs are
either preempted by an earlier write or never read at all:
- kitty.conf.tpl, ghostty.conf.tpl
→ shadowed by the per-palette generators in
themes/engine/files.nix added in 8d3ce2d.
- hyprland.conf.tpl
→ shadowed by files.nix:100, which always writes
~/.config/nomarchy/current/theme/hyprland.conf from the
palette/feature/nord fallback chain.
- hyprlock.conf.tpl, alacritty.toml.tpl, btop.theme.tpl,
chromium.theme.tpl, swayosd.css.tpl
→ output paths nothing reads. alacritty + swayosd are themed
via Stylix / declarative HM options inline. btop reads from
~/.config/btop/themes/nomarchy.theme (loader.nix:72), not
from the theme symlink. chromium is themed via the managed-
policy module in core/system/browser.nix. hyprlock has no
consumer of theme/hyprlock.conf anywhere in the tree.
- hyprland-preview-share-picker.css.tpl
→ orphaned when the share-picker dir was deleted in 20de3d4.
obsidian.css.tpl and keyboard.rgb.tpl stay: the first is consumed by
nomarchy-theme-set-obsidian (copied into every Obsidian vault), the
second by nomarchy-theme-set-keyboard-asus-rog (sets the ROG
keyboard tint via asusctl).
Rewrote Step 6 of docs/creating-themes.md to describe the two live
templates by name and corrected a path bug ("~/.config/nomarchy/themed/"
→ "~/.config/nomarchy/themes/templates/" — the script actually reads
the latter).
`nix flake check --no-build` clean.
Per user decision: not supporting a non-LUKS install path. Removed
the Now-column entry and the Pillar 4 bullet that tracked it. FDE
stays the only supported install shape.
New nomarchy-installed-summary script renders a markdown table via
gum format with the install shape the user should verify before they
start customising:
- theme / font / panel position (~/.config/nomarchy/state.json)
- timezone / DNS / hybrid GPU (/etc/nixos/state.json)
- form factor (BAT* sysfs presence)
- software profiles (presence of marker packages)
- FDE (any crypt entry in lsblk)
- drives (lsblk filtered to disk/part/crypt)
nomarchy-welcome calls it as Step 0 — before the theme/font/panel
pickers — and gates progression on a gum input prompt so the user has
to acknowledge before customisation rewrites anything. The script is
also callable standalone from any terminal: `nomarchy-installed-summary`.
Self-contained — no installer-side changes. Software profiles are
detected heuristically (the installer bakes the user's pick into the
generated home.nix as concrete home.packages rather than persisting a
profile list), which is good enough for verification but won't catch
manually-removed profile packages. gum is in the existing categoryDeps
so no new tools are needed; falls back to plain markdown when gum
isn't on PATH (recovery contexts).
Closes the "Installer: What's installed? summary on first boot"
Now-column item from Pillar 4.
Component 9 (ISOs) closeout entry covers the two inline cleanups
(unreachable else branches in nomarchy-build-{iso,live-iso}) and the
regression-class verification: every tool install.sh calls is provided
by either the explicit host packages, the upstream profiles/base.nix
chain (gptfdisk, util-linux, kbd, systemd), or the nrun nix-run
fallback.
With Components 1–10 all shipped, the "Full QA audit" Now-column item
has done its job. Replaced it with a runtime-verification punch-list
entry that consolidates the "needs runtime verification" notes carried
forward by each component's closeout — boot the live ISO and walk
through waybar/menu/option-toggle paths on real hardware.
Component 8 (Scripts runtime behavior) closeout entry summarises the
four inline fixes: omacom URL in nomarchy-menu "Learn → Nomarchy",
looknfeel.conf path drift, unreachable Overrides case branch, and
schema-vs-script default drift for the theme fallback in
nomarchy-theme-bg-next.
New Later row tracks an interaction-pattern bug in
show_setup_config_menu: five of nine entries edit files that Home
Manager generates from declarative options, so the next rebuild
clobbers the edit. Two more open paths the modules don't deploy.
Either rewire the menu or surface the ephemerality.
Component 7 (Theme engine + palettes) closeout entry summarises the
three inline fixes (theme-set early-exit on missing dir; bg-set
state.json persistence + path validation; palette dead-surface
cleanup) plus the script-comment correction.
Updated the existing `themes/templates/*.tpl` Later row: the original
claim "no script in the tree consumes them" was wrong —
nomarchy-theme-set-templates does. Replaced with a concrete
categorisation: (a) functionally dead (alacritty/btop/chromium/swayosd
write to paths nothing reads), (b) superseded by Nix-side generators
(kitty/ghostty after 8d3ce2d), (c) still relevant
(hyprland/hyprlock/obsidian/keyboard.rgb plus the now-orphan
share-picker tpl to verify).
Component 6 (Apps) closeout entry covers the three inline theming
fixes (kitty/ghostty per-palette colors, btop color_theme name match,
VSCode theme extensions split). One new Later row tracks the 15
palettes — including the default summer-night (sainnhe.everforest) —
whose theme extensions aren't in nixpkgs and need
pkgs.vscode-utils.extensionFromVscodeMarketplace per-palette pinning.
Chromium's static Default/Preferences symlink was confirmed redundant
with the managed-policy intent in core/system/browser.nix, but left
under the existing Later entry (the user already hedged on deletion
without chromium-internals confirmation).
Pillar 8 Component 5 (Desktop stack) closeout entry covers the five inline
fixes from this sweep (hyprland apps.conf wiring, NNOMARCHY typo pair,
broken waybar palette overrides, dead bindings files, mako post-fix verify)
plus the doc reconciles (SCRIPTS.md, KEYBINDINGS.md). One new Later row
captures the nightlight/hyprsunset toggle-vs-systemd inconsistency — Nix
always enables the systemd unit with a rebuild-time temperature while the
toggle script pkills/exec's hyprsunset directly and hardcodes 4000K
instead of reading nightlightTemperature.
Runtime verification (boot live ISO; eyeball waybar across panel
positions × form factors × all 22 palettes, walker launcher modes, the
screensaver at idle) remains on the user before declaring Component 5
fully closed.
bindings.conf was explicitly labeled "Deprecated bindings file. New
installations include everything directly." and was sourced by nothing.
plain-bindings.conf referenced \$terminal/\$browser/\$fileManager/\$music/
\$messenger/\$passwordManager — Hyprland variables that aren't defined
anywhere in the loaded config tree — and was likewise sourced by nothing.
Both files have been superseded by features/desktop/hyprland/config/
bindings.conf (the user-overrideable, mkDefault-deployed one at
~/.config/hypr/bindings.conf) and the entries already inside
default/hypr/bindings/{utilities,media,clipboard,tiling-v2}.conf.
Regenerated docs/SCRIPTS.md; the diff drops the stale plain-bindings.conf
callers and incidentally corrects four scripts whose Origin column was
out of date after they moved from core/system/scripts/ to
features/scripts/utils/ (nomarchy-env-update, nomarchy-pkg-add,
nomarchy-pkg-remove, nomarchy-preflight-migration).
Two behavioral wrinkles found during the Pillar 8 desktop-stack sweep
that need a design decision before they can be fixed. Logged as Later
rows so the audit doesn't lose them.
1. The Hyprland Wayland keymap is hardcoded to `us` in
`core/home/config/nomarchy/default/hypr/input.conf:3`, ignoring the
installer-chosen layout for native Wayland apps. Fix needs either a
templated input.conf driven by a new home option, or session-level
`XKB_DEFAULT_LAYOUT` propagation. Either path touches the installer
heredoc and the home modules, so not a same-PR fix.
2. `nomarchy.toggles.waybar` is exported only as an env var consumed
by the runtime toggle script. The Nix module always sets
`programs.waybar.enable = lib.mkDefault true`, so the toggle is
session-only — waybar comes back on every rebuild/reboot.
Inconsistent with `toggles.idle` which correctly gates
`services.hypridle.enable`. Needs a behavioral call (persistent
gate vs intentional runtime-only with a clearer name).
core/system/virtualization.nix wires `programs.uwsm` + the Hyprland
session config at the top of the file — loaded unconditionally on every
install, with no actual relationship to libvirt/docker. Cosmetic
mislocation, not a behavior bug; logged as a Later row so it can be
fixed in a dedicated session module without growing this audit PR.
Found during Pillar 8 audit of core/system modules.
The persistence block at core/system/impermanence.nix:75 read
`users.nomarchy = { directories = [...]; }` — the username was a
literal, not a reference. For any user not literally named "nomarchy"
the block was silently inert and ~/.ssh, ~/.gnupg, ~/.local/share/keyrings,
Documents, Downloads, Pictures, Videos, Projects were wiped on every boot.
Adds `nomarchy.system.impermanence.user` (str, default "nomarchy") and
uses it via `users.${cfg.user}`. The installer now writes the chosen
username alongside `enable` and `mainLuksName` so impermanence installs
with non-default usernames are correct out of the box.
docs/OPTIONS.md: fixes the wrong path on the impermanence row
(documented `impermanence.enable`, real option is
`nomarchy.system.impermanence.enable`) and adds entries for
`mainLuksName` and `user`.
Found during Pillar 8 audit of core/system modules.
Two unreferenced asset files removed; two larger concerns deferred to
roadmap rows because they need more thought than a focused audit
allows.
Deleted:
- `features/apps/alacritty/config/alacritty.toml` — the alacritty
module uses `programs.alacritty.settings` (Nix attrset) exclusively;
nothing references the on-disk file. The neighbouring (already-empty)
`themes/` directory goes with it.
- `themes/templates/mako.ini.tpl` — no script reads it.
Deferred to ROADMAP "Later":
- `features/apps/chromium/Default/Preferences` is deployed as a Home
Manager symlink into chromium's mutable profile directory. Either
silently replaced on first save or silently failing to write —
either way the static defaults don't survive. The actual chromium
theming work happens via managed policies in
core/system/browser.nix. Needs chromium-internals knowledge to
decide whether to remove or rework, so flagged rather than
unilaterally deleted.
- `themes/templates/*.tpl` (the remaining 10 templates) are also
apparently orphan — deployed via xdg.dataFile but unconsumed by any
script. Likely vestigial from a pre-stylix templating system.
Logged as a separate row to decide deletion vs documentation as
user-reference assets.
Found during Pillar 8 audit of features/apps.
Two clusters of documented-but-non-functional options surfaced during
the Pillar 8 audit, both setting toggles that have zero runtime effect.
1. `nomarchy.toggles.skipVsCodeTheme` was declared in
core/home/options.nix, defaulted from lib/state-schema.nix, and
surfaced as `NOMARCHY_TOGGLE_SKIP_VSCODE_THEME` env var in
features/scripts/default.nix — but `features/apps/vscode.nix` always
sets `workbench.colorTheme` unconditionally, and no script reads the
env var. Setting the toggle to true did nothing. Removed from
options, schema, state, env-var export, and OPTIONS.md.
2. `nomarchy.themeLoader.apps.{waybar,mako,kitty,alacritty}` were
declared in themes/engine/loader.nix but only `btop` is actually
wired (line 87 gates the per-theme btop.theme deploy). The other
four had no consumer. The actual theming pipeline for those apps is
elsewhere: waybar themes inline from `colorScheme` in waybar.nix;
kitty and alacritty are themed by stylix targets in
themes/engine/stylix.nix; mako has no theme integration at all.
Removed the four dead options + updated OPTIONS.md to list only
btop with a note about where the other apps' theming lives.
`themes/engine/sddm.nix` defaulted `services.displayManager.autoLogin`
to `enable = true; user = "nomarchy";` (both mkDefault). The installer
flow overrode both with the real username at normal priority, so this
was invisible there — but a hand-migrated user (per docs/MIGRATION.md)
who imported `nomarchy.nixosModules.system` without setting
`autoLogin.user` would auto-login as a nonexistent "nomarchy" user and
SDDM would error. `docs/MIGRATION.md` even documented the override as a
post-import chore.
Flipped the default to `enable = lib.mkDefault false`. Installer
generates `enable = true` directly so its flow is unchanged. Migration
flow now gets the safe default — opt-in instead of opt-out — and the
docs row is updated to reflect the new shape.
The hardcoded "nomarchy" username fallback for `autoLogin.user` is the
same class of bug as the impermanence persistence block was. A future
roadmap row to consolidate "primary user" across impermanence,
autoLogin, and any future modules might be worthwhile, but it's
deferred — this commit is the immediate fix.
Found during Pillar 8 audit of first-boot UX.