# Decisions ## 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-git` was 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 (see `moonarch-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.sh` and `transform.sh` no longer write `Mode = arp` or a `[moonarch-pkgbuilds]` section to `/etc/paru.conf`, and no longer call `paru -Syu --pkgbuilds`. They run `pacman -Sy` + `paru -S moonarch-git` against the registry. The `moonarch-git` install 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`/`.mo` build-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=pacman` for strings that match upstream msgids (prompts like `Proceed with installation?`, `Do you want to remove these packages?`, `[Y/n]`, `Starting full system upgrade...`), inline `_t()` helper for moonarch-specific strings. - **How**: `moonarch-update` sets `TEXTDOMAIN=pacman`/`TEXTDOMAINDIR=/usr/share/locale`. `_t "en" "de"` picks by `${LANG%%.*}` matching `de_*`. `confirm()` now uses `::` prefix, default Y, accepts `y/Y/j/J`. No PKGBUILD change — `gettext` is in `base`. 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_threshold` support 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, Ragnar - **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.conf` instead of `~/.config/paru/paru.conf` is 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.conf` to system-wide `/etc/paru.conf`. Updated post-install.sh accordingly. ## 2026-04-01 – Replace dunst with swaync as notification daemon - **Who**: Dominik, Ragnar - **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**: Ragnar, 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**: `eval` in 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_DATA` in btnote. (3) `--` guard before `$connection` in vpn nmcli calls. (4) `install -dm700` for moongreet cache dirs in PKGBUILD. (5) `else err` logging in post-install.sh when USER_DEFAULTS missing. ## 2026-03-29 – /opt/moonarch stays root-owned, no chown to user - **Who**: Dominik, Ragnar - **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 git` for 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, Ragnar - **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, Ragnar - **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, Ragnar - **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 `-mesg` flags. 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, Ragnar - **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` / `vpn` type). - **Tradeoffs**: nm-applet adds a tray indicator (mitigated with `--indicator` mode 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 `nmcli` active 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, Ragnar - **Why**: gsettings had `Colloid-Dark-Catppuccin` while config files had `Colloid-Catppuccin` — inconsistent. Grey accent matches the icon theme (Colloid-Grey-Catppuccin-Dark). Explicit `-Dark` variant is more reliable than depending on `prefer-dark` color-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.