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.
36 lines
967 B
Bash
Executable File
36 lines
967 B
Bash
Executable File
#!/usr/bin/bash
|
|
# ABOUTME: Privileged helper invoked via pkexec from moonarch-batsaver-toggle.
|
|
# ABOUTME: Validates the threshold value and writes it to sysfs and the state file.
|
|
|
|
set -eu
|
|
|
|
VAL="${1:-}"
|
|
|
|
case "$VAL" in
|
|
""|*[!0-9]*)
|
|
echo "Invalid argument: '$VAL' (expected integer 1-100)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if [ "$VAL" -lt 1 ] || [ "$VAL" -gt 100 ]; then
|
|
echo "Out of range: $VAL (expected 1-100)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
THRESHOLD_FILE="/sys/class/power_supply/BAT0/charge_control_end_threshold"
|
|
STATE_DIR="/var/lib/moonarch"
|
|
STATE_FILE="$STATE_DIR/batsaver-threshold"
|
|
|
|
[ -f "$THRESHOLD_FILE" ] || { echo "No battery threshold support" >&2; exit 1; }
|
|
|
|
# Skip the kernel write when the value already matches — some Lenovo drivers
|
|
# reject same-value writes with EINVAL.
|
|
CURRENT=$(cat "$THRESHOLD_FILE")
|
|
if [ "$CURRENT" != "$VAL" ]; then
|
|
printf %s "$VAL" > "$THRESHOLD_FILE"
|
|
fi
|
|
|
|
mkdir -p "$STATE_DIR"
|
|
printf %s "$VAL" > "$STATE_FILE"
|