DSH / Atlas
2026-09-08proposedfeature

Deferred Desktop update extensions

Desktop 更新后续扩展

Frequent releases may eventually benefit from independently revised Desktop packages, a stable subscription, next-launch installation, or replacing an older pending update. These choices introduce additional release and installer states that are not needed to ship the initial fixed-Nightly, explicitly approved installation flow.

English

Problem

Frequent releases may eventually benefit from independently revised Desktop packages, a stable subscription, next-launch installation, or replacing an older pending update. These choices introduce additional release and installer states that are not needed to ship the initial fixed-Nightly, explicitly approved installation flow.

Proposal

Keep these candidates separate from the initial update design. None is an initial acceptance requirement or authorization to change dependencies. Product approval and platform qualification are required before implementation. The mandatory-update API remains independent; automatic installation does not add installer fields to it.

Independent revisions

If Desktop-only fixes become necessary on a prerelease line, evaluate the reserved .dsk.N format. Keep full SemVer comparison so introducing it does not require a custom version parser. The intended ordering is:

0.1.3-rc.2
< 0.1.3-rc.2.dsk.1
< 0.1.3-rc.2.dsk.2
< 0.1.3-rc.3

Such a release would record Desktop 0.1.3-rc.2.dsk.1 separately from bundled dsh 0.1.3-rc.2. Introduce independent desktopVersion, bundledDshVersion, and releaseChannel records only with corresponding build, runtime descriptor, profile reconciliation, publisher, and backend-policy validation. The initial build continues to require equal versions.

Do not use 0.1.3-dsk.1 to repair stable 0.1.3: SemVer orders it below the stable release. Stable fixes require a higher shared dsh/Desktop patch version, such as 0.1.4. Independent prerelease revisions are an exceptional release path, not a routine per-build counter.

Stable subscription and channel switching

User optionFeedRelease contents
Stablelatest.yml / latest-mac.ymlStable only
Nightlynightly.yml / nightly-mac.ymlAlpha, rc, and stable

The initial publication rule adds the stable feed when shared stable releases exist, without switching fixed-Nightly clients. A user-facing stable subscription and selector remain deferred. If enabled, persist the selected channel; never infer it from the installed version. Preserve allowDowngrade = false when assigning the updater channel. Moving from Nightly to stable keeps a higher installed Nightly until a higher stable version exists, without downgrading Desktop or bundled dsh.

Channel switching may immediately check; download behavior must follow the approved setting. Ignore old-channel responses and reconfirm downloaded artifacts against the new channel before installation. A channel change does not clear mandatory blocking without a valid policy response for the new conditions. Display a persistent Nightly explanation under the selector, with candidate Chinese copy “提前体验新功能,版本可能不稳定。”; hide it after selecting stable, while separately explaining any wait for a higher stable version.

Design compatibility only for Desktop packages actually distributed. If a future migration has real clients reading alpha.yml or rc.yml, publish a higher bridge version to the old feed and Nightly until the old entry can be retired. No such bridge is required initially.

Automatic-installation setting

The candidate setting is automatic installation, potentially enabled by default only after product approval and measured platform behavior. Candidate Chinese helper text is “关闭后仍会提示更新,需手动升级。” If next-launch installation is not acceptable, evaluate a download-only setting and retain explicit installation confirmation.

SettingNewer version discoveredLater complete app launch
EnabledDownload and prepare automatically, including discovery from a manual checkApply a valid pending update when installation conditions hold
DisabledContinue checking and prompting; wait for explicit downloadDo not install automatically; keep the manual path

Automatic download and installation in this table are deferred product choices; the initial release requires user action for every download and separate installation approval. Turning a future automatic setting off prevents new automatic downloads and installations; an active download may complete without a new cancel button. Determine whether platform-staged installation can be cancelled before promising immediate effect. Never proactively exit a running app or bypass task-impact approval. Preserve initial check triggers and feedback, without adding network-recovery checks or unsolicited global indicators.

Next-launch installation

Target a complete process launch, not reopening a window or reloading the renderer. Prefer installation before restoring business tasks or starting local dsh; surviving managed resources require explicit shutdown approval. A cached ZIP or installer is not proof of completed native preparation. Surface extraction, verification, and preparation honestly without fabricated progress.

Use the already prepared target instead of delaying launch for a fresh package download. A bounded check may discover a newer candidate and defer this installation while the current app opens, but only if the platform still permits abandoning the staged target. Native installer handoff may prevent cancellation or retargeting; never simulate it by deleting native staging directories. Measure download-to-ready, click-to-exit, replacement, and new-version profile reconciliation and Host startup separately.

Updater dependency qualification

The initial dependency declaration remains in Desktop package metadata. A coordinated electron-builder 27 / electron-updater 7 migration is an evaluation candidate, not a dependency bump authorized here. The following API and platform items require verification against the selected release and real packages; this proposal does not claim they have been exercised locally.

Candidate itemRequired qualification
autoInstallEventVerify manual, onQuit, and onNextLaunch; migration alone must retain manual installation
Object-form quitAndInstallVerify isSilent and isForceRunAfter, plus macOS-specific semantics
Next-launch cacheRe-fetch metadata and validate artifact hashes and platform signatures before installing
Windows per-user NSISVerify next-launch behavior without UAC; do not assume per-machine installs are silent
Windows session endingVerify shutdown/restart/logoff does not launch unsafe on-quit installation; NSIS is not assumed atomic
macOS Squirrel stagingVerify native preparation, quit/relaunch replacement, signing, notarization, and both architectures
Metadata and security defaultsInspect modern files[], legacy path/sha512 consumers, sha2 retirement, and NSIS Web Installer defaults
Build-tool migrationVerify Node engine requirements, including the candidate 22.12 floor, native ESM, configuration, signing hooks, and publisher compatibility
Distributed old clientsExercise their real feeds and payloads before changing metadata; do not infer compatibility from dependency version alone

Multiple pending versions

The candidate policy follows the latest eligible version without exposing a package collection to users. Own only one effective download/install target; temporary files do not promise an older installable fallback.

SituationCandidate behavior
A downloading when C is foundDo not repeatedly cancel A; handle newer candidates in a subsequent check
A ready, automatic setting enabled, C foundPrepare C and replace A's install entry with C progress
A ready, automatic setting disabled, C foundShow C; start its download only on user action
D appears during C downloadDo not interrupt C; consider D later
Installation and task shutdown approvedLock the chosen target against background replacement
C preparation fails after replacing AKeep running the installed app, show error/retry, and do not promise installation of A

Reconfirm platform support before abandoning a prepared target. Cache identity includes artifact metadata and hashes, not just a version string. Replacement after readiness is application coordination, not an assumed automatic capability of the updater library. It must be separately tested with channel changes, new releases, retries, and installer handoff.

Cache invalidation and revocation

Reuse verified complete cache; do not promise partial-download resumption or preservation of an older installable package. Publish a higher fix for a defective release and update the feed. Metadata mismatch may invalidate some cache but is not strict revocation: already staged or installing artifacts may still apply. Continuing to run the installed app after failure is different from installing an older cache. Do not implement an independent artifact revocation list or pre-install revocation interception. The mandatory API decides whether upgrading is required, not which updater artifact to install or invalidate.

Alternatives considered

Enable every extension in the first release. This adds unqualified installer and release paths before a Desktop distribution exists. Fixed Nightly and explicit installation provide the smaller initial scope.

Treat changing a setting as cancellation. Native staging may already own installation. Product wording and state transitions must reflect verified cancellation capability.

Acceptance criteria

  • Approve each extension independently; retain initial behavior until its acceptance criteria are satisfied.
  • Test independent revision ordering and all consumers of split versions before releasing .dsk.N.
  • Verify both channel publication, persistent selection, stale-response rejection, cache revalidation, and no downgrades.
  • Measure real Windows per-user and macOS x64/arm64 update preparation, termination, next launch, native staging, profile reconciliation, and Host startup.
  • Prove the disabled setting's effect on active and staged updates before promising immediate revocation.
  • Cover A-to-C replacement, C failure, intervening D, channel switching, and locked installation targets.
  • Preserve task approval, honest progress, silent automatic-check failures, and recovery to the usable installed app; do not block normal startup on network failure.

Risks

Native installer ownership limits cancellation and replacement. Faster startup cannot be guaranteed from API availability alone, and metadata replacement is not a universal rollback mechanism. Library API candidates, security defaults, build-tool engines, and old-client compatibility need release-specific verification; none is a verified product capability merely because it appears in this proposal.

中文

问题

高频发布后续可能需要 Desktop 独立修订、稳定版订阅、下次启动安装或替换较旧待安装更新。这些选择引入额外发布与安装器状态,初期固定 Nightly、明确确认安装的流程并不需要它们。

提案

将这些候选与一期更新设计分开。它们不是一期验收要求,也不授权修改依赖;实现前需要产品批准与平台验证。强制更新接口继续独立,自动安装不向其中增加安装器字段。

独立修订

预发布线上确有 Desktop 独立修复需求时,评估预留的 .dsk.N 格式。保持完整 SemVer 比较,使引入该格式不需要自定义版本解析器。预期排序为:

0.1.3-rc.2
< 0.1.3-rc.2.dsk.1
< 0.1.3-rc.2.dsk.2
< 0.1.3-rc.3

这类发布将 Desktop 0.1.3-rc.2.dsk.1 与内置 dsh 0.1.3-rc.2 分别记录。只有同时补齐构建、运行时描述、profile 校准、发布工具与后端策略校验,才引入独立的 desktopVersion、bundledDshVersion 和 releaseChannel 记录。一期构建继续要求版本相等。

不能用 0.1.3-dsk.1 修复稳定版 0.1.3,因为 SemVer 将其排在稳定版之前。稳定版修复需要更高的共用 dsh/Desktop 补丁版本,例如 0.1.4。独立预发布修订是特殊发布路径,不是每次构建的常规计数器。

稳定版订阅与通道切换

用户选项Feed发布内容
稳定版latest.yml / latest-mac.yml仅稳定版本
Nightlynightly.yml / nightly-mac.ymlalpha、rc 和稳定版本

一期发布规则在共用稳定版本出现时增加稳定 feed,不切换固定 Nightly 客户端。面向用户的稳定版订阅与选择器仍延后。启用后持久化所选通道,不从已安装版本反推。设置 updater 通道时保持 allowDowngrade = false。从 Nightly 切到稳定版时,较高的已安装 Nightly 持续运行,直到出现更高稳定版;不得降级 Desktop 或内置 dsh。

切换通道可以立即检查,下载行为必须遵循获准设置。忽略旧通道响应,安装前按新通道重新确认已下载产物。通道改变不能在缺少新条件有效策略响应时解除强制阻断。选择器下方常驻 Nightly 说明,候选中文为“提前体验新功能,版本可能不稳定。”;选择稳定版后隐藏,必要时另行说明需等待更高稳定版。

仅为实际分发过的 Desktop 安装包设计兼容。后续迁移若存在读取 alpha.yml 或 rc.yml 的真实客户端,应向旧 feed 与 Nightly 发布更高桥接版本,直到可淘汰旧入口。一期不需要这类桥接。

自动安装设置

候选设置为自动安装;仅在产品批准与平台实测后考虑默认开启。候选中文辅助文案为“关闭后仍会提示更新,需手动升级。” 若下次启动安装体验不满足要求,则评估仅自动下载的设置,并保留明确安装确认。

设置发现更高版本后续完整启动应用
开启自动下载与准备,包含手动检查发现的版本安装条件满足时应用有效待安装更新
关闭继续检查与提示,等待明确下载操作不自动安装,保留手动入口

表中的自动下载与安装是后续产品选择;一期每次下载都需要用户操作,安装另行确认。关闭未来的自动设置后不发起新的自动下载与安装;在途下载可以完成,不新增取消按钮。承诺立即生效前需确认能否取消平台已暂存安装。不得主动退出使用中的应用或绕过任务影响确认。沿用一期检查触发与反馈,不新增网络恢复检查或未经确认的全局提示。

下次启动安装

目标是完整进程启动,不是重开窗口或刷新渲染层。优先在恢复业务任务或启动本地 dsh 前安装;仍存活的受管资源需要明确关闭确认。已缓存 ZIP 或安装器不证明原生准备完成。如实展示解压、校验和准备,不伪造进度。

使用已经准备好的目标,不为下载新包延迟启动。限时检查若发现更高候选,且平台仍允许放弃暂存目标,可以推迟本次安装并打开当前应用;原生安装器接管后可能无法取消或改换目标,不得通过删除原生暂存目录模拟。分别测量下载到就绪、点击到退出、应用替换,以及新版本 profile 校准与 Host 启动耗时。

updater 依赖验证

一期依赖声明仍由 Desktop 包元数据负责。electron-builder 27 / electron-updater 7 配套迁移是评估候选,不是本文授权的依赖升级。以下 API 与平台项目需针对选定版本和真实安装包核验;本提案不宣称已在本机执行验证。

候选项目必需验证
autoInstallEvent核验 manual、onQuit 与 onNextLaunch;仅迁移依赖必须保留手动安装
对象参数形式的 quitAndInstall核验 isSilent、isForceRunAfter 及 macOS 特定语义
下次启动缓存安装前重新读取元数据,校验产物哈希与平台签名
Windows 每用户 NSIS验证无需 UAC 的下次启动行为;不假定每机器安装可静默
Windows 会话结束验证关机/重启/注销不启动不安全的退出安装;不假定 NSIS 原子性
macOS Squirrel 暂存验证原生准备、退出/重启替换、签名、公证与两种架构
元数据与安全默认值检查现代 files[]、旧 path/sha512 消费者、sha2 淘汰与 NSIS Web Installer 默认值
构建工具迁移核验 Node 引擎要求,包括候选 22.12 下限,以及原生 ESM、配置、签名 hook 与发布工具兼容
已分发旧客户端改元数据前实测其真实 feed 与载荷,不仅按依赖版本推断兼容

多个待安装版本

候选策略跟随最新适用版本,不向用户提供安装包集合管理。同一时刻仅持有一个有效下载/安装目标;暂存文件不承诺可安装的旧版本兜底。

场景候选行为
A 下载时发现 C不反复取消 A,后续检查处理更新候选
A 就绪、自动设置开启、发现 C准备 C,用 C 进度替换 A 安装入口
A 就绪、自动设置关闭、发现 C显示 C,仅在用户操作后开始下载
C 下载时出现 D不打断 C,之后再考虑 D
已确认安装与任务关闭锁定所选目标,后台不能替换
替换 A 后准备 C 失败继续运行已安装应用,显示错误重试,不承诺安装 A

放弃已准备目标前重新确认平台支持。缓存身份包含产物元数据与哈希,不仅是版本字符串。就绪后的替换是应用协调逻辑,不是假定 updater 库自动提供的能力;必须结合通道变化、新发布、重试与安装器交接单独测试。

缓存失效与撤回

复用已校验完整缓存,不承诺部分下载续传或保留旧可安装包。问题版本通过发布更高修复版本并更新 feed 处理。元数据不匹配可能使部分缓存失效,但不是严格撤回:已暂存或安装中的产物仍可能被应用。失败后继续运行已安装应用不同于安装旧缓存。不实现独立的安装包撤回清单或安装前撤回拦截。强制 API 判定是否必须升级,不决定安装或作废哪个 updater 产物。

考虑过的替代方案

首版启用全部扩展。 在尚无 Desktop 分发时增加未经验证的安装与发布路径。固定 Nightly、明确确认安装提供较小一期范围。

将修改设置视作取消。 原生暂存可能已经持有安装操作。产品文案与状态转换必须反映经过验证的取消能力。

验收标准

  • 独立批准每项扩展;满足对应验收前保持一期行为。
  • 发布 .dsk.N 前测试独立修订排序及所有版本拆分消费者。
  • 验证两个通道发布、选择持久化、拒绝陈旧响应、重新校验缓存和禁止降级。
  • 实测 Windows 每用户安装与 macOS x64/arm64 的更新准备、终止、下次启动、原生暂存、profile 校准与 Host 启动。
  • 承诺即时撤销前证明关闭设置对在途及暂存更新的实际影响。
  • 覆盖 A 替换为 C、C 失败、期间出现 D、通道切换与安装目标锁定。
  • 保留任务确认、真实进度、自动检查失败静默和恢复到可用已安装应用的行为;不因网络失败阻断正常启动。

风险

原生安装器归属限制取消与替换。API 存在本身不能保证启动更快,元数据替换也不是通用回滚机制。库 API 候选、安全默认值、构建引擎与旧客户端兼容性需要按发布版本核验;写入本提案不代表已验证为产品能力。