The wheel-write-via-udev approach for charge_control_end_threshold has
been broken since 2026-04-08: the audit-remediation commit added
ACTION=="add" to the rule, but the threshold attribute doesn't exist
yet at the add event on Lenovo, so chmod fails silently and permissions
are never set. moonarch-batsaver-toggle has been returning Permission
denied since.
Replace the udev-rule approach with a pkexec helper:
defaults/bin/moonarch-batsaver-apply privileged: validate + write
defaults/bin/moonarch-batsaver-toggle user: read sysfs, dispatch via pkexec
defaults/bin/moonarch-batsaver-restore boot-time root restore (extracted
from inline ExecStart for clarity)
Default Standard-pkexec prompt — password cached per session for the
~5min auth window; no polkit no-password rule, no privilege escalation
surface from misvalidated input. Same pattern Battery-Health-Charging
GNOME extension uses.
The boot-time restore service now skips the kernel write when the
sysfs value already matches the saved state (Lenovo drivers reject
same-value writes with EINVAL).
DECISIONS.md documents the failure analysis and trade-offs.
CLAUDE.md updated to describe the new flow.
moonarch-doctor: udev-effectiveness check removed.
Laptops with charge_control_end_threshold support get a click-to-toggle
on the battery module (80% ↔ 100%). A ♥ icon appears when conservation
is active, hidden when inactive. State persists across reboots via
systemd oneshot service. udev rule grants wheel group write access
so no sudo is needed for toggling.