Skip to content

ADR 0022: Application Update Delivery ​

  • Status: Accepted (amended by D364 / D603 / ADR 0197, D450 / ADR 0289)
  • Date: 2026-07-26
  • Deciders: PI-Desktop core
  • Related: D120, D126, D364, D603, D010, D450, ADR 0021, ADR 0197, ADR 0289

Context ​

PI-Desktop needs a release-update path that preserves the renderer sandbox, does not expose feed configuration to untrusted UI code, and reflects each platform's actual installer capabilities. A single automatic-install policy is not appropriate: unsigned macOS packages cannot provide a qualified in-app upgrade lane, while Windows NSIS and Linux AppImage support electron-updater's download-and-install flow.

Decision ​

  1. Electron Main exclusively owns electron-updater, the fixed GitHub Releases feed, update polling, and install lifecycle. Renderer IPC exposes only allowlisted check, state, release-link, and install operations; callers cannot supply a feed URL.
  2. Development builds keep updates disabled. Packaged macOS, Windows NSIS, and Linux AppImage use in-app download and quit-and-install delivery. Non-AppImage Linux (deb/rpm) and Windows ZIP builds (piDistribution = "zip") use notify-and-link delivery so an NSIS installer cannot replace a no-install run. Legacy portable executables remain manual when PORTABLE_EXECUTABLE_FILE is present. (Packaged macOS was notify-and-link until D450 / ADR 0289 qualified the signed in-app channel.)
  3. The updater always sets allowPrerelease = false. electron-updater would otherwise pin prerelease installs (for example 0.2.0-rc.6) to the same custom channel (rc) and never offer a newer stable GitHub latest release. Prerelease-channel policy remains an operational follow-up if a dedicated RC feed is needed later.
  4. Automatic checks run after startup and periodically. Automatic failures remain ambient; explicit checks expose status and errors through the menu and Settings -> Info. A downloaded update remains actionable until install or normal shutdown.
  5. Feed manifests and artifact hashes are generated by electron-builder. The client ships no GitHub credential and fails closed when the feed or package cannot be validated.
  6. D126 later lifts D010's macOS-only publication scope and publishes all platform artifacts and update manifests produced by the release matrix. D450 / ADR 0289 qualifies the signed macOS in-app channel on that same feed.
  7. Dual-locale product "what's new" text (D164) is maintained in packages/shared as EN + zh-CN catalogs. Main formats notes for the discovered version using the product UI locale and attaches them as optional UpdateState.releaseNotes on the existing updates path. GitHub auto-generated release bodies remain web-only; the renderer never supplies a notes URL.

Consequences ​

  • Update state is process-owned and consistent across the application menu, Settings, and the ambient banner.
  • The sandboxed renderer cannot redirect update traffic or install arbitrary packages.
  • Windows NSIS, Linux AppImage, and packaged macOS can update in-app from published tag feeds; Linux deb and Windows ZIP users install from the release page after extracting the archive.
  • Prerelease installs graduate to newer stable releases through the same latest feed; a dedicated RC channel is not active.
  • In-app bilingual release highlights ship with the build and follow the product locale without a second network surface.
  • Rollback, staged rollout, and optional prerelease-channel policy remain operational follow-ups rather than renderer capabilities.

Alternatives ​

  • Renderer-owned updater: rejected because it violates the process and sandbox boundary.
  • Caller-provided feed URLs: rejected because it creates an arbitrary package installation path.
  • Force one delivery mode on every platform: rejected because installer and signing guarantees differ by target.

Amendment (D450 / ADR 0289) ​

Official GitHub tag macOS artifacts are Developer ID-signed, notarized, and stapled. Packaged macOS therefore uses the same in-app electron-updater lane as Windows NSIS and Linux AppImage. Local unsigned packaging without a certificate remains available (D078).

Amendment (D603) ​

The Windows no-install lane now publishes a normal ZIP archive instead of electron-builder's self-extracting portable executable. The release helper builds NSIS and ZIP separately and stamps the ZIP app metadata with piDistribution = "zip"; the updater uses that marker to keep the ZIP manual even though ordinary ZIP launches do not set PORTABLE_EXECUTABLE_FILE. Users extract the archive and run PI-Desktop.exe; the NSIS lane and existing data directory remain unchanged.

Local-first · Model-agnostic · Plugin-powered. AIUO.NET