moonset/DECISIONS.md
nevaforget 473bed479a docs: add CHANGELOG.md, DECISIONS.md, bump version to 0.1.1
Add CHANGELOG documenting all changes since 0.1.0 and the initial
release. Add DECISIONS.md as an architectural decision log. Update
CLAUDE.md to reflect current architecture. Bump to 0.1.1 for the
security and correctness fixes in the previous commit.
2026-03-28 10:17:22 +01:00

3.2 KiB
Raw Blame History

Decisions

Architectural and design decisions for Moonset, in reverse chronological order.

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 $PATH entry to intercept systemctl, 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_TIMEOUT and PowerError::Timeout were declared but never wired up. A hanging systemctl 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_command now polls child.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/moonset was duplicated in config.rs, users.rs, and as literal strings in panel.rs and main.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_PREFIX in main.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_shell uses gtk4_layer_shell::Layer::Overlay for 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 = false for 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"]).