Stasis ignores /etc/xdg/ and only reads ~/.config/stasis/stasis.rune (primary) or /etc/stasis/stasis.rune (fallback). On first start with no user config it writes its own hardcoded default, so Moonarch's tuned idle plans were never active on fresh installs. Seed the template from /etc/xdg/stasis/stasis.rune into the user home before stasis ever starts, only if the user file is missing. See DECISIONS.md for verification against upstream v1.1.0.
19 KiB
19 KiB
Decisions
2026-04-22 – Seed Stasis user config from post-install.sh
- Who: Dominik, ClaudeCode
- Why: Moonarch shipped
defaults/xdg/stasis/stasis.rune(deployed to/etc/xdg/stasis/stasis.runeby the PKGBUILD) on the assumption that stasis honors the XDG system config hierarchy. It does not. Verified against upstream source (v1.1.0,src/config/mod.rs:30+src/config/bootstrap.rs): stasis only reads~/.config/stasis/stasis.rune(primary) or/etc/stasis/stasis.rune(fallback, noxdg/). On every start with no user config,ensure_user_config_exists()writes its own hardcoded default (laptop/desktop template compiled into the binary) to~/.config/stasis/stasis.rune. Net effect: Moonarch's Idle-Manager tuning (AC/battery plans, moonlock integration, inhibit apps, niri DPMS commands) was never active on fresh installs — users got the upstream defaults withswaylockas locker. - Tradeoffs: Three options were considered. (A) Service drop-in with
--config /etc/stasis/stasis.rune— cleanest, upgrades propagate via package, no user-home touching; rejected because it takes stasis out of the standard config path users expect when they want to customize, and requires packaging a drop-in unit. (B) Seed once from post-install.sh into~/.config/stasis/stasis.rune— chosen: user-owned file, immediately editable, no magic. Cost: package updates to the template never reach users who already ran post-install; they have to merge manually. (C) Recurring systemd user service that keeps seeding — ruled out, too clever, user edits would race with it. Stasis has no config hierarchy / merging, so "system default + user override" cannot be modeled at all. - How: Added a block to
scripts/post-install.shbefore the user-services-enable step: if~/.config/stasis/stasis.runedoes not exist and/etc/xdg/stasis/stasis.runedoes,install -Dm644copies the template into the user home. Order is correct — moonarch-git is installed earlier in the script (deploys/etc/xdg/…), and stasis.service is only enabled (not started) later, so the seed is in place before stasis ever runs. The/etc/xdg/stasis/payload stays as the canonical template source inside the package.
2026-04-21 – post-install.sh pulls aur.txt, rust for paru build, rustup out of official
- Who: Dominik, ClaudeCode
- Why: Three related gaps uncovered while fixing the paru bootstrap: (1)
moonarch-gitcannot depend on AUR packages, so every AUR package inaur.txt(walker-bin, elephant-*-bin, awww's theme, waypaper, stasis, …) was silently never installed by post-install.sh — a fresh install would have a working pacman but no launcher, no idle manager, no theming. (2)makepkg -siforparu(AUR source build) needsrustas makedep; neither archinstall nor post-install.sh installed it, so the restored paru bootstrap would have crashed on rust-less systems. (3)rustupsat inofficial.txt"for something we don't remember" — turned out to be a leftover;rustsuffices for the paru build, and rustup is only needed for dev toolchain management which is a per-user concern, not a Moonarch default. - Tradeoffs: Installing
rust(~350MB) just to bootstrap paru feels heavy. Alternativeparu-binavoids the compile step entirely; rejected because Dominik's documented workflow usesparu(source) and consistency with that matters more than ~30s of build time. rustup can be re-added to official.txt if the dev workflow grows that demand. - How: (1) post-install.sh now runs
read_packages "$AUR_PACKAGES" | paru -S --neededafterparu -S moonarch-git. (2)sudo pacman -S base-devel rustbefore the paru git-clone. (3)rustupremoved fromofficial.txt(remains in PKGBUILDoptdependsfor discoverability).
2026-04-21 – Restore AUR bootstrap for paru in post-install.sh
- Who: Dominik, ClaudeCode
- Why: Commit
0726451(2026-03-29) replaced the workinggit clone https://aur.archlinux.org/paru.git && makepkg -sibootstrap withsudo pacman -S paru, on the (wrong) assumption that paru had landed in[extra]. Verified against archlinux.org API: paru and paru-bin are AUR-only, not in any official repo. Fresh installs have been silently broken since — the command fails, the installer aborts before the moonarch registry is configured. - Tradeoffs: Bootstrap builds paru from source, which needs
base-devel(already pulled by archinstall). Alternativeparu-binwould skip the compile step; choseparuto match the upstream recommendation the user follows. Alternative "bundle paru in the Moonarch registry" would be internally consistent but adds a dependency on a running Gitea during install. - How: Replaced the
pacman -S paruline inpost-install.shwith the original bootstrap —mktemp -d,git clone,makepkg -si --noconfirm,rm -rf. Wrapped in an EXIT trap so the tempdir gets cleaned up even on failure.
2026-04-21 – Drop transform.sh and legacy update.sh shim
- Who: Dominik, ClaudeCode
- Why: transform.sh was added 2026-03-29 to onboard users from existing Arch+Wayland systems, but was never actually used — Moonarch is installed fresh via archinstall. Maintaining it meant duplicated paru/repo/key setup, a second entry point with its own backup/pre-flight logic, and a second reason for the
/opt/moonarchclone. scripts/update.sh was a deprecation shim from before moonarch-update moved into the moonarch-git package; obsolete now that the package ships moonup/moondoc. - Tradeoffs: Existing Arch+Wayland users now have to install paru, add the
[moonarch]repo + key manually, thenparu -S moonarch-git. That's three commands instead of one script — acceptable since nobody actually uses that path. If the need returns, transform can be resurrected from git history. - How: Deleted
scripts/transform.shandscripts/update.sh.lib.shstays (still sourced by post-install.sh). README "Transform" section removed, project-structure listing trimmed. Fresh-install flow via archinstall + post-install.sh is unchanged.
2026-04-20 – Registry-only install: drop paru --pkgbuilds from setup scripts
- Who: Dominik, ClaudeCode
- Why: Two parallel paths for finding moonarch packages (Arch registry via
[moonarch]in pacman.conf, and paru's PKGBUILD-repo via[moonarch-pkgbuilds]in paru.conf) caused ambiguity during debugging:paru -S moonarch-gitwas resolving against the registry's stale DB (zombie r99 entry) while the PKGBUILD source would have had r105. Also: the PKGBUILD-repo path triggered a local build on every client, while the registry ships prebuilt binaries. With the registry DB now stable (seemoonarch-pkgbuilds/DECISIONS.md, same date), the second mechanism is redundant. - Tradeoffs: If the registry is down or broken, clients have no local-build fallback. Acceptable — a broken registry is a server-side bug to fix, not something to mask with a parallel mechanism that complicates diagnostics.
- How:
post-install.shandtransform.shno longer writeMode = arpor a[moonarch-pkgbuilds]section to/etc/paru.conf, and no longer callparu -Syu --pkgbuilds. They runpacman -Sy+paru -S moonarch-gitagainst the registry. Themoonarch-gitinstall hook now strips the legacy paru.conf entries on upgrade (see moonarch-pkgbuilds repo).
2026-04-19 – moonup i18n: reuse pacman gettext catalog + inline fallback
- Who: Dominik, ClaudeCode
- Why: moonup prompts looked foreign next to pacman/paru output (
[y/N]vs[J/n], English strings on a German system). User wanted consistency with the rest of the pacman UX. - Tradeoffs: Full
.po/.mobuild-chain for moonarch was overkill for ~15 strings. gettext-only approach misses most moonarch-specific strings (no matching msgids in pacman catalog). Chose hybrid:TEXTDOMAIN=pacmanfor strings that match upstream msgids (prompts likeProceed with installation?,Do you want to remove these packages?,[Y/n],Starting full system upgrade...), inline_t()helper for moonarch-specific strings. - How:
moonarch-updatesetsTEXTDOMAIN=pacman/TEXTDOMAINDIR=/usr/share/locale._t "en" "de"picks by${LANG%%.*}matchingde_*.confirm()now uses::prefix, default Y, acceptsy/Y/j/J. No PKGBUILD change —gettextis inbase. pacman msgids with trailing\n(e.g.Starting full system upgrade...\n) require ANSI-C quoting$'...\n'to match.
2026-04-08 – Battery conservation mode: udev + sysfs + Waybar toggle
- Who: Dominik, ClaudeCode
- Why: Laptops with
charge_control_end_thresholdsupport benefit from limiting charge to 80% to extend battery lifespan. Needed a user-friendly toggle without requiring sudo. - Tradeoffs: udev RUN approach for permissions (group wheel gets write access) vs polkit/pkexec (password prompt on every toggle). Chose udev for seamless UX. State persisted in
/var/lib/moonarch/(system-wide, not per-user) — acceptable since charge threshold is a hardware setting, not a user preference. Fixed 80% threshold instead of configurable — KISS, matches industry standard. - How: udev rule grants wheel group write on
charge_control_end_threshold. Toggle script writes sysfs + state file. systemd oneshot service restores on boot. Waybar shows ♥ icon when active, hidden when inactive. Click on battery module toggles.
2026-04-07 – Walker theme: gtk-inherit → moonarch with fixed colors
- Who: Dominik, ClaudeCode
- Why: gtk-inherit theme relied on GTK4 color inheritance which works but doesn't update live when switching GTK themes (Walker service needs restart). Explicit color definitions make the theme self-contained and predictable.
- Tradeoffs: Colors no longer auto-follow GTK theme changes. Acceptable since moonarch uses a fixed Catppuccin Mocha palette anyway.
- How: Renamed theme to moonarch, added @define-color with Colloid-Grey-Dark-Catppuccin values, reduced border/shadow weight.
2026-04-07 – Migrate archinstall config to v4 format
- Who: Dominik, ClaudeCode
- Why: archinstall v4.1 introduced new canonical key names. Old keys (audio_config, bootloader, custom-commands) are soft-deprecated and auto-mapped, but custom-commands (hyphen) vs custom_commands (underscore) was risky.
- Tradeoffs: Config now requires archinstall v4+. Older ISOs with v2/v3 may not parse the new keys.
- How: Migrated audio_config into app_config, bootloader into bootloader_config, custom-commands to custom_commands, gfx_driver value updated.
2026-04-07 – kanshi config: no ABOUTME, no overwrite on transform
- Who: Dominik, ClaudeCode
- Why: ABOUTME comments in kanshi config broke the profile parser in wdisplays-persistent store.c, preventing config saves. Additionally, transform.sh was overwriting user display profiles on every run.
- Tradeoffs: kanshi default template is now empty (no comments). Users get no guidance in the seed file, but wdisplays-persistent provides the GUI for config management.
- How: Removed ABOUTME from defaults/xdg/kanshi/config. Added skip logic in transform.sh to preserve existing kanshi user configs.
2026-04-07 – Move paru repo config into moonarch.install hook
- Who: Dominik, ClaudeCode
- Why: paru PKGBUILD repo config was only set up by post-install.sh and transform.sh. If paru updated and overwrote /etc/paru.conf, or the config was missing on existing systems, moonarch-git couldn't update itself — bootstrap loop where the fix requires the package that delivers the fix.
- Tradeoffs: Config setup is now in two places: moonarch.install (for updates) and post-install.sh (for first install before moonarch-git exists). Acceptable duplication to break the circular dependency.
- How: Added paru repo config (Mode=arp + [moonarch-pkgbuilds] section) to moonarch.install post_install/post_upgrade hook. Kept post-install.sh setup for bootstrap. Removed redundant setup from transform.sh.
2026-04-02 – Rename paru PKGBUILD repo, move config to /etc/paru.conf
- Who: Dominik, ClaudeCode
- Why: paru PKGBUILD repo and pacman package registry both used
[moonarch]as section name. When pkgver-bot pushed version bumps, paru tried to resolve PKGBUILD targets (moongreet-git, moonlock-git) against the pacman repo — which only contains moonarch-git — causing "nicht alle benötigten Pakete gefunden" errors. - Tradeoffs: Renaming the PKGBUILD repo section means existing installations need a one-time manual fix. Using
/etc/paru.confinstead of~/.config/paru/paru.confis consistent with moonarch's system-wide config philosophy. - How: Renamed PKGBUILD repo section from
[moonarch]to[moonarch-pkgbuilds]. Moved paru config (Mode + repo) from user-level~/.config/paru/paru.confto system-wide/etc/paru.conf. Updated post-install.sh accordingly.
2026-04-01 – Replace dunst with swaync as notification daemon
- Who: Dominik, ClaudeCode
- Why: Dunst lacks wp_fractional_scale_v1 support, causing aliased/jagged font rendering on external monitors in mixed-DPI setups (laptop eDP-1 at 2.5x, externals at 1x). Confirmed by testing: removing fractional scaling fixed the issue. swaync uses GTK4 which handles fractional scaling natively.
- Tradeoffs: swaync is heavier than dunst (GTK4 + libadwaita dependency). Loses dunstctl CLI (replaced by swaync-client). Gains notification center panel with DnD toggle, grouping, MPRIS widget support. Waybar already had swaync-client integration with exec-if guard.
- How: Replaced dunst with swaync in packages/official.txt and archinstall config. Niri spawn-at-startup updated. Waybar dunstctl widget removed (swaync-client widget already present). New swaync config.json and style.css based on catppuccin/swaync upstream theme with Lavender accent instead of Blue.
2026-03-31 – Audit: shell script quoting fixes, PKGBUILD permissions
- Who: ClaudeCode, Dom
- Why: Security audit found command injection risk in moonarch-cpugov (unquoted array expansion with pkexec), word-splitting in moonarch-btnote (upower output from Bluetooth devices), and nmcli argument injection in moonarch-vpn. PKGBUILD for moongreet had world-readable cache dir.
- Tradeoffs:
evalin cpugov is safe because COMMANDS values are hardcoded string literals, not user input. Alternative (function dispatch) would be cleaner but over-engineered for 3 fixed entries. moonarch-btnote switched from for-loop to while+read with process substitution to avoid subshell. - How: (1)
eval "${COMMANDS[$choice]}"in cpugov. (2)while IFS= read -r+ process substitution + quoted$DEVICE_DATAin btnote. (3)--guard before$connectionin vpn nmcli calls. (4)install -dm700for moongreet cache dirs in PKGBUILD. (5)else errlogging in post-install.sh when USER_DEFAULTS missing.
2026-03-29 – /opt/moonarch stays root-owned, no chown to user
- Who: Dominik, ClaudeCode
- Why: Multi-user system — chown to UID 1000 locks out other users from moonarch-update
- Tradeoffs: sudo required for git operations in update.sh vs. simpler user-owned repo
- How: Repo stays at /opt/moonarch owned by root:root. update.sh uses
sudo gitfor fetch/pull. All scripts already use sudo for system-level operations, so this is consistent.
2026-03-29 – Add transform.sh for existing Arch+Wayland systems
- Who: Dominik, ClaudeCode
- Why: Users with existing Arch+Wayland setups should be able to adopt Moonarch without reinstalling
- Tradeoffs: Hard overwrite of all configs (user + system) vs. selective/merge approach — chose hard overwrite for simplicity and consistency
- How: New transform.sh with pre-flight summary, backup, DM conflict resolution, and --dry-run flag. Shared helpers extracted to lib.sh.
2026-03-29 – Package moonarch as moonarch-git PKGBUILD
- Who: Dominik, ClaudeCode
- Why: System artifacts (XDG configs, helper scripts, zsh config, wallpaper) should be managed by pacman for clean deployment, versioning, rollback, and deinstallation
- Tradeoffs: /etc/xdg/ configs NOT in backup= (moonarch philosophy: system defaults flow through, users override in ~/.config/). /etc/greetd/ and /etc/moongreet/ NOT owned by package (owned by greetd/moongreet-git, overwritten via .install hook). Helper scripts move from /usr/local/bin/ to /usr/bin/ (FHS for package-managed files)
- How: moonarch-git PKGBUILD in moonarch-pkgbuilds repo. sweet-cursors-git as separate package. moonarch-update simplified (no git-sync, pacman handles file deployment). Installer scripts (post-install.sh, transform.sh) remain for orchestration, will be refactored in a follow-up to delegate file deployment to
paru -S moonarch-git
2026-03-30 – Replace Rofi with Walker as application launcher
- Who: Dominik, ClaudeCode
- Why: Walker is Wayland-native (GTK4 + gtk4-layer-shell), has built-in providers for clipboard, bluetooth, audio (wireplumber), and Niri integration. Reduces custom shell scripts from 8 to 3. Rofi required a Wayland fork (rofi-lbonn-wayland-git) and every applet was a custom bash script.
- Tradeoffs: Walker is newer/less battle-tested than Rofi. Requires separate Elephant daemon with per-provider packages. Dmenu mode lacks Rofi's
-a/-u(active/urgent) and-mesgflags. Settings menu (moonarch-setmen) dropped entirely — apps are findable via Walker's app search. - How: Walker + Elephant as systemd user services. Native providers replace 5 rofi scripts (launcher, clipboard, bluetooth, volume, sink-switcher). 3 scripts ported to walker dmenu (vpn, cpugov, sink-switcher). Walker theme inherits GTK4 system theme colors (gtk-inherit). Old rofi configs preserved in
legacy/rofi/.
2026-03-30 – Use nm-applet as VPN secret agent, add WireGuard support
- Who: Dominik, ClaudeCode
- Why: VPN auth previously spawned a foot terminal for
nmcli --ask, which was fragile and ugly. WireGuard connections were invisible to the VPN script and Waybar indicator because both only checked for OpenVPN (tun0/vpntype). - Tradeoffs: nm-applet adds a tray indicator (mitigated with
--indicatormode which is minimal). Requires nm-applet running at session start. Alternative was gnome-keyring or a custom secret agent — nm-applet is simpler and handles all NM secret types. - How: nm-applet started via niri spawn-at-startup. moonarch-vpn rewritten to support both vpn and wireguard types, uses nm-applet for auth instead of foot terminal, sends notify-send for connect/disconnect results. Waybar VPN module uses
nmcliactive connection check instead of/proc/sys/net/ipv4/conf/tun0, plus RTMIN+9 signal for instant updates after toggle.
2026-03-30 – Standardize GTK theme to Colloid-Grey-Dark-Catppuccin
- Who: Dominik, ClaudeCode
- Why: gsettings had
Colloid-Dark-Catppuccinwhile config files hadColloid-Catppuccin— inconsistent. Grey accent matches the icon theme (Colloid-Grey-Catppuccin-Dark). Explicit-Darkvariant is more reliable than depending onprefer-darkcolor-scheme setting. - Tradeoffs: Explicit dark locks out light mode toggle — acceptable since Moonarch is dark-only by design.
- How: Updated transform.sh, post-install.sh, gtk-3.0/settings.ini, and gsettings to
Colloid-Grey-Dark-Catppuccin. GTK4 symlinks updated accordingly.