Problem statement
LG Buddy already detects newer GitHub releases and sends low-frequency desktop notifications, but release-bundle users still have to open GitHub, download and extract the archive, and run the installer manually.
Add a user-initiated upgrade path that performs those mechanical steps for a host installation that passes the release-bundle upgrade compatibility checks:
This is an assisted upgrade, not an unattended updater. The user chooses when to run it and approves the existing privilege escalation needed to update system-owned files.
Unified update-channel preference
updates.channel is the sole authority for manual checks, background checks, notifications, and installation.
The public UX should be:
lg-buddy updates check
lg-buddy updates check --notify
lg-buddy updates install
lg-buddy settings set updates.channel stable
lg-buddy settings set updates.channel prerelease
Remove the per-command --channel override from updates check, and do not add one to updates install.
Selection semantics:
stable considers stable releases only and selects the latest stable release.
prerelease considers both stable and prerelease releases and selects whichever has the highest semantic version.
- Draft releases and legacy non-version tags remain excluded.
- The default preference is
stable.
- The installed binary's own stable/prerelease identity does not implicitly override the saved preference.
- Installation preserves the preference.
This guarantees that the release reported by updates check, shown in a notification, and installed by updates install is selected by one persistent policy.
Desired UX
When a newer release is available:
LG Buddy 1.4.0 is available.
Run `lg-buddy updates install` to upgrade.
The notification should include that command in its body regardless of whether notification actions are supported. Keep the existing View Release and Never Notify Again actions.
Manual updates check output should provide the same install-command next step when an update is available. There is no channel-dependent command variant in either surface.
A terminal-driven install should:
- Show the current and target versions and ask for confirmation.
- Download the matching release archive and checksum metadata without opening a browser.
- Verify the artifact before executing anything from it.
- Apply the upgrade without re-running interactive setup or TV pairing.
- Request sudo only for system-owned installation steps.
- Restart/reload the affected integration and verify the installed version.
Functional scope
Host upgrade compatibility
- Perform an installed-state preflight before release discovery, downloading, confirmation, sudo, or mutation.
- Inspect observable runtime and installation facts such as executable location, filesystem topology, path containment, configuration discovery, integration state, service-manager availability, and detectable conflicting ownership.
- Refuse incompatible hosts with actionable check failures rather than declared installation provenance or distribution classification.
- After verifying the candidate bundle, run a second candidate-specific non-mutating preflight before privileged mutation.
- Treat the initial check set as a conservative, evolving safety boundary that can be refined after the updater ships.
The detailed compatibility model and its ongoing refinement are tracked in #100.
Release discovery and artifact selection
- Make manual and background release discovery load the same
updates.channel preference.
- For
prerelease, select the highest semantic version across eligible stable and prerelease releases.
- Extend the release model with asset metadata.
- Select the exact supported target archive, initially
x86_64-unknown-linux-musl.
- Require the expected archive and
sha256sums.txt; reject missing or ambiguous assets.
- Refuse equal-version installs and downgrades.
- Restrict production downloads to the LG Buddy GitHub repository and HTTPS release assets.
Download and verification
- Stage downloads under the user's LG Buddy cache with restrictive permissions.
- Prevent concurrent upgrade attempts.
- Verify the GitHub-provided asset digest and the published checksum entry.
- Validate archive paths before extraction.
- Verify that the bundled binary reports the expected version, release channel, and tagged commit before invoking the installer.
- Clean up incomplete staging after failures.
This matches the trust boundary of the current manual GitHub release-bundle flow. Stronger independent release signing or attestations may be added separately.
Installer upgrade mode
Add an explicit non-interactive upgrade mode to the release-bundle installer.
It must:
- load and preserve the existing configuration, including
updates.channel
- preserve native webOS credentials
- avoid interactive discovery, configuration, or pairing
- avoid unnecessary Python environment recreation for native-only installations
- update the runtime and owned system/user integration files
- reload/restart affected services in a defined order
- verify the final installed version and report partial failures clearly
Notification behavior
Update the existing notification and manual-check rendering only after updates install exists:
- include
lg-buddy updates install when an update is available
- retain the release URL
- retain
View Release
- retain
Never Notify Again
- preserve the current once-per-release notification policy
- render no per-command channel choice
Testing scope
- the default update preference is stable
- stable preference selects only the latest stable release
- prerelease preference selects the highest semantic version across stable and prerelease releases
- manual check, background check, notification, and install resolve the same candidate
- stable/prerelease binary identity does not override the saved preference
- public help and parsing expose no per-command
--channel option
- missing, duplicate, wrong-target, or malformed release assets
- interrupted downloads and cache cleanup
- digest and checksum mismatch
- archive traversal and unexpected bundle layout
- bundled version/channel/commit mismatch
- equal-version and downgrade refusal
- concurrent-upgrade exclusion
- compatible mutable host acceptance and refusal of incompatible layouts before network or mutation
- candidate-specific compatibility refusal before sudo or mutation
- non-interactive in-place upgrade preserving config, update preference, and native credentials
- service/unit/hook replacement and restart behavior
- post-install version verification
- cross-version release smoke from a pinned previous updater-capable bundle to the candidate bundle
- notification and manual-check output include the unconditional install command
Explicit non-goals
- per-command release-channel overrides
- unattended or timer-triggered installation
- a graphical
Install Update notification action
- opening a terminal or Polkit flow from a notification action
- GUI progress or cancellation UX
- host- or distribution-specific upgrade branches
- publishing or updating
.deb/.rpm repositories
- treating the initial host compatibility check set as permanent or exhaustive
- arbitrary-version installation or downgrade support
The existing user timer remains detection-and-notification only.
Relationships
Problem statement
LG Buddy already detects newer GitHub releases and sends low-frequency desktop notifications, but release-bundle users still have to open GitHub, download and extract the archive, and run the installer manually.
Add a user-initiated upgrade path that performs those mechanical steps for a host installation that passes the release-bundle upgrade compatibility checks:
This is an assisted upgrade, not an unattended updater. The user chooses when to run it and approves the existing privilege escalation needed to update system-owned files.
Unified update-channel preference
updates.channelis the sole authority for manual checks, background checks, notifications, and installation.The public UX should be:
Remove the per-command
--channeloverride fromupdates check, and do not add one toupdates install.Selection semantics:
stableconsiders stable releases only and selects the latest stable release.prereleaseconsiders both stable and prerelease releases and selects whichever has the highest semantic version.stable.This guarantees that the release reported by
updates check, shown in a notification, and installed byupdates installis selected by one persistent policy.Desired UX
When a newer release is available:
The notification should include that command in its body regardless of whether notification actions are supported. Keep the existing
View ReleaseandNever Notify Againactions.Manual
updates checkoutput should provide the same install-command next step when an update is available. There is no channel-dependent command variant in either surface.A terminal-driven install should:
Functional scope
Host upgrade compatibility
The detailed compatibility model and its ongoing refinement are tracked in #100.
Release discovery and artifact selection
updates.channelpreference.prerelease, select the highest semantic version across eligible stable and prerelease releases.x86_64-unknown-linux-musl.sha256sums.txt; reject missing or ambiguous assets.Download and verification
This matches the trust boundary of the current manual GitHub release-bundle flow. Stronger independent release signing or attestations may be added separately.
Installer upgrade mode
Add an explicit non-interactive upgrade mode to the release-bundle installer.
It must:
updates.channelNotification behavior
Update the existing notification and manual-check rendering only after
updates installexists:lg-buddy updates installwhen an update is availableView ReleaseNever Notify AgainTesting scope
--channeloptionExplicit non-goals
Install Updatenotification action.deb/.rpmrepositoriesThe existing user timer remains detection-and-notification only.
Relationships