All checks were successful
Update PKGBUILD version / update-pkgver (push) Successful in 1s
- Add [profile.release] with LTO, codegen-units=1, strip - Add compressed="true" to GResource CSS/SVG entries - Inherit moonlock stderr instead of /dev/null (errors visible in journal) - Add SYNC comments to duplicated blur/background functions
6.6 KiB
6.6 KiB
Decisions
Architectural and design decisions for Moonset, in reverse chronological order.
2026-03-31 – Fourth audit: release profile, GResource compression, lock stderr, sync markers
- Who: Ragnar, Dom
- Why: Fourth triple audit found missing release profile (LTO/strip), uncompressed GResource assets, moonlock stderr suppressed (errors invisible), and duplicated code without sync markers.
- Tradeoffs: moonlock stderr now inherited instead of null — errors appear in moonset's journal context. Acceptable for debugging, no security leak since moonlock logs to its own journal identifier.
- How: (1)
[profile.release]with LTO, codegen-units=1, strip. (2)compressed="true"on GResource entries. (3)Stdio::inherit()for moonlock stderr in lock(). (4) SYNC comments on duplicated blur/background functions.
2026-03-28 – Remove wallpaper from GResource bundle
- Who: Ragnar, Dom
- Why: All three Moon projects (moonset, moongreet, moonlock) embedded a 374kB fallback wallpaper in the binary via GResource. Moonarch already installs
/usr/share/moonarch/wallpaper.jpgat system setup time, making the embedded fallback unnecessary dead weight (~2MB in binary size). - Tradeoffs: If
/usr/share/moonarch/wallpaper.jpgis missing and no user config exists, moonset shows a solid CSS background instead of a wallpaper. Acceptable — the power menu is functional without a wallpaper image. - How: Removed
wallpaper.jpgfrom GResource XML and resources directory.resolve_background_pathreturnsOption<PathBuf>. All wallpaper-related functions handleNonegracefully. Binary size dropped from ~3.2MB to ~1.3MB.
2026-03-28 – Switch from env_logger to systemd-journal-logger
- Who: Ragnar, Dom
- Why: moonlock and moongreet already use systemd-journal-logger. moonset used env_logger which writes to stderr — not useful for a GUI app launched via keybind. Journal integration enables
journalctl -t moonsetand consistent troubleshooting across all three Moon projects. - Tradeoffs: Requires systemd at runtime. Graceful fallback to eprintln if journal logger fails. Acceptable since Moonarch targets systemd-based Arch Linux.
- How: Replace
env_loggerdep withsystemd-journal-logger, addsetup_logging()withMOONSET_DEBUGenv var for debug-level output. Same pattern as moonlock/moongreet.
2026-03-28 – Replace action name dispatch with quit_after field
- Who: Hekate, Dom
- Why: Post-action behavior (quit the app or not) was controlled by comparing
action_name == "lock"— a magic string duplicated from the action definition. Renaming an action would silently break the dispatch. - Tradeoffs: Adds a field to
ActionDefthat most actions set tofalse. Acceptable because it makes the contract explicit and testable. - How:
ActionDef.quit_after: bool—truefor lock and logout,falsefor hibernate/reboot/shutdown.
2026-03-28 – GPU blur via GskBlurNode replaces CPU blur
- Who: Ragnar, Dom
- Why: CPU-side Gaussian blur (
imagecrate) blocked startup and added caching complexity. moonlock already migrated to GPU blur. - Tradeoffs: GPU blur quality is slightly different (box-blur approximation vs true Gaussian), acceptable for wallpaper backgrounds. Removes
imagecrate dependency entirely. No disk cache needed. - How:
Snapshot::push_blur()+GskRenderer::render_texture()onconnect_realize. Blur happens once on the GPU when the widget gets its renderer. Symmetric with moonlock and moongreet.
2026-03-28 – Use absolute paths for system binaries
- Who: Hekate, Dom
- Why: Security audit flagged PATH hijacking risk — relative binary names allow a malicious
$PATHentry to interceptsystemctl,loginctl, etc. - Tradeoffs: Hardcoded paths reduce portability to non-Arch distros where binaries may live elsewhere (e.g.
/sbin/). Acceptable because Moonarch targets Arch Linux exclusively. - How: All five power action wrappers now use
/usr/bin/prefixed paths.
2026-03-28 – Implement power action timeout via try_wait polling
- Who: Hekate, Dom
- Why:
POWER_TIMEOUTandPowerError::Timeoutwere declared but never wired up. A hangingsystemctl hibernate(e.g. blocked NFS mount) would freeze the power menu indefinitely. - Tradeoffs: Polling with
try_wait()+ 100ms sleep is slightly less efficient than a dedicated timeout crate, but avoids adding a dependency for a single use case. - How:
run_commandnow pollschild.try_wait()against a 30s deadline, kills the child on timeout.
2026-03-28 – Centralize GRESOURCE_PREFIX
- Who: Hekate, Dom
- Why: The string
/dev/moonarch/moonsetwas duplicated inconfig.rs,users.rs, and as literal strings inpanel.rsandmain.rs. Changing the application ID would require edits in 4+ locations. - Tradeoffs: Modules now depend on
crate::GRESOURCE_PREFIX— tighter coupling to main.rs, but acceptable for an internal constant. - How: Single
pub(crate) const GRESOURCE_PREFIXinmain.rs, referenced everywhere else.
2026-03-28 – Remove journal.md
- Who: Hekate, Dom
- Why: One-time development notes from the Rust rewrite, never updated after initial session. Overlapped with memory system and git history.
- Tradeoffs: Historical context lost from the file, but the information is preserved in git history and the memory system.
- How: Deleted. Useful technical learnings migrated to persistent memory.
2026-03-27 – OVERLAY layer instead of TOP
- Who: Hekate, Dom
- Why: Waybar occupies the TOP layer. The power menu must appear above it.
- Tradeoffs: OVERLAY is the highest layer — nothing can render above moonset while it's open. This is intentional for a session power menu.
- How:
setup_layer_shellusesgtk4_layer_shell::Layer::Overlayfor the panel window.
2026-03-27 – Lock without confirmation
- Who: Hekate, Dom
- Why: Lock is immediately reversible (just unlock). All other actions (logout, hibernate, reboot, shutdown) are destructive or disruptive.
- Tradeoffs: One less click for the most common action. Risk of accidental lock is negligible since unlocking is trivial.
- How:
ActionDef.needs_confirm = falsefor lock; all others require inline confirmation.
2026-03-27 – Niri-specific logout via niri msg action quit
- Who: Hekate, Dom
- Why: Moonarch is built exclusively for the Niri compositor. Generic Wayland logout mechanisms don't exist — each compositor has its own.
- Tradeoffs: Hard dependency on Niri. If the compositor changes,
power::logout()must be updated. - How:
Command::new("/usr/bin/niri").args(["msg", "action", "quit"]).