Files
moonix/DECISIONS.md
T
nevaforget ec881f6401 feat: drop moonlock and moonset
The power menu is a Quickshell popout in the moonarch config now, and it
was the last caller of moonlock. Inputs, package entries and both build
recipes are gone, together with the generated /etc configs and the
moonlock PAM stack — swaylock's comes from programs.niri.enable.
2026-08-14 17:48:52 +02:00

12 KiB
Raw Blame History

Decisions

2026-08-14 moonset and moonlock dropped; the power menu is a Quickshell popout

  • Who: Dominik, ClaudeCode
  • Why: The power menu became PowerPopout.qml in the moonarch Quickshell config (see moonarch/DECISIONS.md, same date), and moonset was the last thing invoking moonlock. Both packages therefore leave this flake with nothing to replace them: the popout ships inside the config tree that is already deployed.
  • Tradeoffs: The flake keeps the ability to package a moonarch program — stasis and sweet-cursors still use that path — so nothing was generalised away. What is lost is the pinning discipline for two programs that no longer exist here; the tags in flake.nix were the only record of which version was deployed, and that record now lives in the retired repos' own history.
  • How: Inputs moonlock and moonset removed, moonarchPackages entries with them, pkgs/moonlock.nix and pkgs/moonset.nix deleted, flake.lock regenerated. modules/desktop.nix drops both packages from systemPackages, the generated environment.etc."moonlock/moonlock.toml" and "moonset/moonset.toml", and the moonlock PAM stack — swaylock's comes from programs.niri.enable.

2026-08-14 regreet and swaylock from nixpkgs, autologin after LUKS

  • Who: Dominik, ClaudeCode
  • Why: moongreet and moonlock were dropped as self-maintained projects; the reasoning is in moonarch/DECISIONS.md for the same date. Here the change is mostly subtraction: two flake inputs, two build recipes and a generated config disappear in favour of a nixpkgs module and a nixpkgs package. Since LUKS already asks for a passphrase at boot, the greeter was also asking for a second one for no gain, so autologin replaces it on both hosts.
  • Tradeoffs: (1) Greeter host — the regreet module sets services.greetd.settings.default_session.command only as mkDefault (dbus-run-session cage -- regreet), so the existing unconditional niri line keeps winning. Taking cage would have meant one Wayland compositor fewer in the greeter path, but niri-greeter.kdl is where layout "de" and numlock live, and nothing in nixpkgs 26.11 exports XKB_DEFAULT_LAYOUT from services.xserver.xkb.layout — verified. A greeter on a US layout rejects every password with an affected character, so niri stays and Arch and NixOS keep sharing that one file. (2) regreet.toml — the module writes /etc/greetd/regreet.toml itself, so the committed file from defaults/etc/greetd/ is deliberately not deployed verbatim; declaring the same path in environment.etc would collide. The values are duplicated into module options, which is the price for the wallpaper store path. (3) swaylock config — nixpkgs passes only --prefix to meson, so swaylock's SYSCONFDIR sits inside the store and /etc/swaylock/config is never read. The config is therefore seeded into $HOME with the same C tmpfiles rule waypaper uses, which also means later user edits survive but updates do not propagate. (4) Colloid overrides — desktop and greeter need the same derivation, and two module files cannot share a let. Moved into flake.nix and passed as _module.args.moonarchThemes rather than duplicating the override, which would drift.
  • How: moongreet input, moonarchPackages.moongreet and pkgs/moongreet.nix removed. modules/greetd.nix now configures services.displayManager.regreet (background, GTK, commands, theme, icon theme, cursor theme, font, extraCss pointing at the CSS in the moonarch input) and keeps the niri default_session. modules/desktop.nix gains swaylock, the seeded ~/.config/swaylock/config and — moved out of greetd.nix, next to the package it belongs to — the moonlock PAM stack. initial_session is set per host, because the accounts are named differently.
  • Remaining exception: moonlock stays packaged and installed. moonset/src/power.rs spawns it by name and has no lock_command option, so its Lock action would otherwise fail. Idle and lid-close already go through swaylock. Two lockers coexist until moonset is released with that call changed; then the input, the recipe, the PAM stack and environment.etc."moonlock/moonlock.toml" all go.
  • Consequence: With autologin, the greeter no longer forces an account to have a password, but swaylock still needs one — passwd after installing stays mandatory, and hosts/testvm has no password declared at all.

2026-08-11 Disk layout via disko after all, as a shared module

  • Who: Dominik, ClaudeCode
  • Why: The Calamares route decided below turned out to be six manual steps, one of which — copying hardware-configuration.nix into the repo — fails silently unless the file is also git added, because Nix only sees tracked files in a git repository. It also does not scale: there will be more machines than this one, and each would repeat the whole procedure.
  • Tradeoffs: The argument against disko was that no target machine existed and device paths would have to be guessed. That has expired. Keeping Calamares would avoid writing a layout module, but leaves partitioning, encryption and subvolumes outside version control, where they cannot be reviewed or repeated.
  • How: modules/disk.nix defines moonarch.disk.{enable,device,encrypt, espSize,swapSize} and builds disko.devices from it, so a new machine is a device path rather than a new layout. Installation is a single disko-install --flake … --disk main <device> from the ISO. hardware-configuration.nix is not needed: nvme, ahci, sd_mod and the USB HID modules are in the initrd by default via boot.initrd.includeDefaultModules, and nixpkgs.hostPlatform comes from nixosSystem. hosts/testvm uses the same module against /dev/vda; its generated file was deleted, having described the UUIDs of a qcow2 that no longer exists.
  • Consequence: The user password no longer arrives with the installer. users.users.dkressler declares none, so it is set once via nixos-enter after installing rather than committing a hash to the repository.

2026-08-11 Swapfile without hibernation

  • Who: ClaudeCode, on Dominik's request for a recommendation
  • Why: The layout module needs a swap default.
  • Tradeoffs: Hibernation needs swap at least the size of RAM plus a resume_offset kernel parameter. On btrfs that offset changes whenever the swapfile is recreated, which is a standing source of breakage. Avoiding it means LUKS → LVM → btrfs LV plus a swap LV, one layer more. A swap partition cannot be resized later without repartitioning; a swapfile can.
  • How: 8G swapfile in a /.swapvol subvolume, no hibernation, no LVM. Sized as a safety valve against memory pressure, not as a replacement for the 30 GiB of RAM. Revisit by growing the swapfile and adding resume_offset — neither needs a reinstall.

2026-08-07 Separate repo instead of Nix files in the application repos

  • Who: Dominik, ClaudeCode
  • Why: The Nix build recipes had to live somewhere without disturbing the existing repos.
  • Tradeoffs: Files inside each project repo would keep version, code and build recipe in one commit — no drift between PKGBUILD pkgver and flake input. A separate repo keeps the Arch repos untouched, at the cost of one extra commit per version bump (tag in flake.nix, then nix flake update).
  • How: New repo moonix, consuming the application repos as flake inputs pinned to release tags.

2026-08-07 Configs deployed as files, not translated to Nix options

  • Who: Dominik
  • Why: One set of config files should stay valid on NixOS and Arch alike.
  • Tradeoffs: Native Nix options (programs.niri.settings) are idiomatic and type checked, but every config would exist twice and drift on each change.
  • How: environment.etc.<path>.source pointing into the moonarch flake input. Only files containing FHS paths are generated instead of copied.

2026-08-07 No Home Manager

  • Who: Dominik
  • Why: Initially proposed for the three home-directory tasks in post-install.sh (GTK4 symlinks, gsettings, seeding the stasis config).
  • Tradeoffs: None in favour, as it turned out. Every one of those tasks is equally doable with ln, gsettings and install; the argument for Home Manager was convention, not need. Two of the three cases disappeared entirely: dconf defaults can be set system-wide via programs.dconf.profiles.user.databases, and stasis reads /etc/stasis/stasis.rune as a documented fallback.
  • How: Rejected. For files that genuinely have no system-wide fallback, systemd.user.tmpfiles with the C directive seeds a copy into $HOME without overwriting later edits.
  • Who: Dominik
  • Why: moonlock, moongreet and moonset invoked systemctl, loginctl and moonlock through absolute /usr/bin paths, and moongreet scanned /usr/share/{wayland-,x}sessions. All of it fails on NixOS.
  • Tradeoffs: systemd.tmpfiles symlinks would have avoided touching the code, but they recreate an FHS layout under NixOS and only cover the paths known at the time — a new one surfaces at runtime, when the user presses the button.
  • How: Programs resolve via PATH, session directories walk XDG_DATA_DIRS with /usr/share as fallback. Behaviour on Arch is unchanged. Released as moonlock 0.6.21, moongreet 0.10.2, moonset 0.9.2.
  • Remaining exception: the polkit agent is spawned by its FHS path from defaults/xdg/niri/config.kdl, which is shared with Arch, where the binary lives outside PATH. That one stays a symlink.

2026-08-07 waybar and swaync not installed

  • Who: Dominik
  • Why: Quickshell provides both the bar and the notifications. The config source still carries waybar and swaync, marked "kept as a reserve" — a note left over from an earlier migration.
  • Tradeoffs: Installing them would mirror the config source exactly, at the price of carrying two unused implementations.
  • How: Neither package, config nor the waybar-only helper scripts are installed. That also retires moonarch-cpugov, moonarch-sink-switcher and moonarch-nightlight: the waybar config was their only caller, and the Quickshell popouts cover the same ground.

2026-08-07 QEMU/KVM as the test host, with a caveat

  • Who: Dominik, ClaudeCode
  • Why: VirtualBox was the first choice, but its 3D acceleration is documented as broken with Wayland compositors.
  • Tradeoffs: QEMU needs no DKMS module on linux-zen and virtio-gpu carries Wayland. However, passing the guest through to the host GPU triggered an amdgpu hard recovery twice, killing the QEMU process. Software rendering is not an alternative: without a 3D capable virtio GPU, niri's TTY backend fails every buffer import with Error::DeviceMissing and never creates an output.
  • How: virtio-vga-gl with gl=on, and the VM is shut down when not in use. The underlying amdgpu problem is a host issue, unrelated to Moonarch.

2026-08-07 Disk layout via Calamares, not disko

  • Who: Dominik
  • Why: Stage 3 targets bare metal, but no target machine exists yet — neither the number of disks nor their device paths are known.
  • Tradeoffs: disko would put partitioning and encryption under version control, which pays off when reinstalling often or setting up several machines alike. For a single machine it is extra work without return, and it would require guessing device paths. Calamares already covers partitioning, LUKS and hardware detection, and produces hardware-configuration.nix — the one file that cannot be written in advance.
  • How: hosts/moonarch/ holds only machine independent settings. Installation runs through Calamares, then the generated hardware file is copied into the host directory. See README.md.