Skip to content

Make battery cutoff fail-safe across app and privilege failures #4

Description

@sshykvlv

Problem

Lidless currently polls the battery once per minute from the menu-bar process and invokes privileged pmset changes directly. App Nap, a crash or force-quit, an unavailable admin prompt, or a failed pmset command can leave SleepDisabled=1 after the configured battery floor has been reached. The app also has no durable ownership record from which to restore a pre-existing system value.

Goal

Make the battery floor a fail-safe safety boundary, including when the UI process is throttled, disconnected, crashed, or quit. Remove recurring password prompts without granting arbitrary pmset access. Harden update and release validation in the same safety release.

Definition of done

  • A narrow, signed privileged helper owns pmset disablesleep mutations and authenticates the Lidless client.
  • The helper restores the value that existed before Lidless armed when the app disarms, quits, disconnects, crashes, misses its heartbeat, or the helper restarts.
  • Battery evaluation is event-driven with a timed fallback and runs immediately on arm, launch/reconnect, power-source change, and battery-floor change.
  • The exact threshold is covered: on battery, percent <= floor cannot remain armed.
  • Every privileged mutation checks exit status and verifies the observed SleepDisabled value.
  • The UI reports setup, cutoff, and mutation failures; operational events are logged without secrets.
  • Legacy Lidless/KeepAwake sudoers grants are migrated only after the helper is proven working.
  • Update staging verifies signature, Team ID, bundle ID, and version before replacing the app and never deletes an unrelated Downloads copy.
  • Build/release fails closed on signing, Gatekeeper, notarization, universal-binary, helper, or test failure.
  • Unit tests cover the cutoff decision matrix, ownership preservation, disconnect/timeout recovery, command failure, and update validation.
  • Live smoke tests confirm arm/disarm, simulated cutoff, quit cleanup, and forced app termination cleanup on macOS 13+.
  • README, CHANGELOG, STATUS, uninstall/Homebrew cleanup, and release notes describe the helper and migration accurately.

Non-goals

No UI redesign, telemetry, thermal-management feature, minimum-macOS change, or silent installation of privileged components.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions