952776c4f9
Update PKGBUILD version / update-pkgver (push) Successful in 2s
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.
24 lines
650 B
Desktop File
24 lines
650 B
Desktop File
# ABOUTME: Restores battery charge threshold from saved state on boot.
|
|
# ABOUTME: Only runs on laptops with threshold support and a saved state file.
|
|
|
|
[Unit]
|
|
Description=Restore battery conservation mode threshold
|
|
After=sysinit.target
|
|
ConditionPathExists=/sys/class/power_supply/BAT0/charge_control_end_threshold
|
|
ConditionPathExists=/var/lib/moonarch/batsaver-threshold
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/bin/moonarch-batsaver-restore
|
|
NoNewPrivileges=true
|
|
ProtectHome=true
|
|
PrivateTmp=true
|
|
ProtectKernelModules=true
|
|
ProtectControlGroups=true
|
|
RestrictNamespaces=true
|
|
RestrictRealtime=true
|
|
LockPersonality=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|