prior-art.md
c139 Phase 0: prior art
- 1. Zed
- 2. VS Code
- 3. Firefox
- 4. 1Password
- 5. Slack
- 6. The Claude desktop app
- 7. Raycast
- 8. VS Code Insiders
- 9. Chrome's channels
- 10. TestFlight
- 11. Staged percentages: Sparkle, the App Store, Google Play
- 12. Early access in B2B: Slack's desktop beta and Microsoft 365 Frontier
- What the reading says about our model
- What we copy
- What we refuse
- Open questions, each with a default
- Sources (all read 2026-11-11)
Use this file to check the update model in plan.md (its states, three-value preference, trace and two eras) against how twelve others show and stage updates. Part A covers seven desktop apps' update settings: Zed, VS Code, Firefox, 1Password, Slack, the Claude desktop app and Raycast, each in the same eight rows. Part B covers five ways of giving some people a build before everyone: VS Code Insiders, Chrome's channels, TestFlight, staged percentages (Sparkle, the App Store, Google Play) and B2B early access (Slack's beta, Microsoft 365 Frontier), each in the same six rows. Every section ends with what we copy and what we refuse, in the plan's terms: rules R1 to R7, decisions D1 to D12 and dependencies T1 to T6. The last four sections test the model, list what we copy and refuse, and give each open question a default.
Every source was read on 2026-11-11. This session reached GitHub, developer.apple.com, developer.android.com, support.claude.com and code.claude.com. So Zed, VS Code, Firefox, Chromium and Sparkle are quoted from their own repositories (exact UI strings, main as of today), and Apple, Android and Anthropic from their pages. Other vendor hosts were blocked; claims from them rest on search excerpts and are marked "(search excerpt)". Zed's updater internals are in c130 platform §5 and are not repeated. Linear, Arc and Figma were too thin for a table. Linear's app turns off updates only with a defaults write … AutoUpdateDisabled key; Figma shows an in-app message when behind and ships a separate "Figma Beta" app; nothing citable was found for Arc. Firefox takes the seventh slot.
https://linear.app/docs/get-the-app.md (search excerpt, 2026-11-11)
https://help.figma.com/hc/en-us/articles/4406787442711-Beta-features (search excerpt, 2026-11-11)
Part A. Desktop apps' update settings
1. Zed
What it is. An editor built on GPUI, qnative's toolkit, so its updater is the nearest code to ours. The update lives in a title-bar button whose label is the state, a menu item, and one setting.
| Update model | Zed |
|---|---|
| Where it lives | A title-bar button shown with the state; "Check for Updates" in the app menu; "Restart to update Zed" in the user menu. No Settings pane. |
| Versions shown | The new version in the tooltip; "Updated to Zed 1.3.0" afterwards. No commit or date. |
| Channel | Stable, Preview (a week ahead), Nightly: separate apps with separate data. |
| Preference | auto_update, default true. On or off. |
| Release notes | A page per version and channel; Nightly links to the commit list; a local Markdown view. The PR author writes each line. |
| Restart prompt | The button reads "Restart to Update". No dialog, no deadline. |
| Silent behaviour | Hourly check (15 minutes on Nightly), install in place, one toast on next launch with "View Release Notes". |
| Managed elsewhere | ZED_UPDATE_EXPLANATION stops the checks; Check then says "Zed was installed via a package manager." with the explanation. |
The facts behind the table.
- The button's labels: "Checking for Zed Updates…", "Downloading Zed Update…", "Installing Zed Update…", "Up to Date", "Restart to Update", "Failed to Update"; the tooltip, "Update to Version: {version}".
https://raw.githubusercontent.com/zed-industries/zed/main/crates/ui/src/components/collab/update_button.rs (read 2026-11-11)
https://raw.githubusercontent.com/zed-industries/zed/main/crates/title_bar/src/title_bar.rs (read 2026-11-11) - The poll is
60 * 60seconds, or15 * 60on Nightly. With telemetry on, the asset query also carries the metrics id, system id andis_staff. The notes URL is/releases/{channel}/{version}for Stable and Preview, andgithub.com/zed-industries/zed/commits/nightly/for Nightly. On reachingUpdated, Zed sets a flag; the next launch shows "Updated to {app_name} {version}" with "View Release Notes".
https://raw.githubusercontent.com/zed-industries/zed/main/crates/auto_update/src/auto_update.rs (read 2026-11-11)
https://raw.githubusercontent.com/zed-industries/zed/main/crates/auto_update_ui/src/auto_update_ui.rs (read 2026-11-11) - The setting's comment: "Automatically update Zed. This setting may be ignored on Linux if installed through a package manager."
https://raw.githubusercontent.com/zed-industries/zed/main/assets/settings/default.json (read 2026-11-11) - With the explanation set, Check opens "Zed was installed via a package manager." with the explanation as detail and one "OK". Nix sets it to "Zed has been installed using Nix. Auto-updates have thus been disabled."
https://raw.githubusercontent.com/zed-industries/zed/main/crates/auto_update/src/auto_update.rs (read 2026-11-11)
https://github.com/zed-industries/zed/blob/main/nix/build.nix (read 2026-11-11, via code search) - Every PR ends in "Release Notes:" with "- N/A or Added/Fixed/Improved …". Preview is weekly and promoted to Stable; each channel has its own database.
https://raw.githubusercontent.com/zed-industries/zed/main/.github/pull_request_template.md (read 2026-11-11)
https://zed.dev/docs/development/releases (search excerpt, 2026-11-11)
Copy.
- The label is the state (R4). The six labels map onto our states, in the tray line and the footer.
- The packager's sentence, verbatim (T5). One string set at build or run time covers Homebrew, Nix or MDM with no code change.
- Notes that follow the channel, written at the change (D6, D7): a page for a release, the commit trail for a nightly, the line drafted in the PR.
Refuse.
- On or off. We need three values.
- The toast after a quiet install. D2 and c137 row 24 put the trace in the footer.
- Channels as separate apps (see section 8).
2. VS Code
What it is. An Electron editor whose title bar now carries an update indicator. Its tooltip is the closest thing in this document to our Updates page: both versions with commits, the date, notes, one action, and a sentence for every reason updates are off.
| Update model | VS Code |
|---|---|
| Where it lives | Title-bar indicator and tooltip (update.titleBar, on); the Manage menu; Help › Check for Updates; the update.mode setting. |
| Versions shown | "Current Version: 1.x (commit)", "Latest Version: 1.y (commit)", "Released {date}", "Copy". |
| Channel | Stable and Insiders as separate installs; an in-app switch exists only on the web. |
| Preference | update.mode: default · start · manual · none, default default. Windows: "Enable Background Updates". |
| Release notes | Opened after an update (update.showReleaseNotes, on); an experiment shows a tooltip instead. One page per weekly release. |
| Restart prompt | "Restart to Update"; an experimental macOS restart when idle, under strict conditions. |
| Silent behaviour | Background download (and Windows install); a reminder when the build is two months old. |
| Managed elsewhere | UpdateMode policy; "Updates are disabled by your organization." and a sentence per other cause. |
The facts behind the table.
- The
update.modevalues read: "Disable updates." · "Disable automatic background update checks. Updates will be available if you manually check for updates." · "Check for updates only on startup." · "Enable automatic update checks."update.showPostInstallInfo(experiment): "Show a post-install update tooltip in the title bar instead of opening the release notes editor."update.showOutdatedBuildReminder: "once this version of VS Code is two months old … at most once a month."
https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/platform/update/common/update.config.contribution.ts (read 2026-11-11) update.restartWhenIdle(off, experimental, macOS) restarts after the screen has been locked a minute on power, "only if every window can be restored exactly as it was, for example when no terminal process, task, debug session, chat request, or agent session is running, and it does not take focus from another application."
https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/platform/update/common/update.config.contribution.ts (read 2026-11-11)- The tooltip's titles include "Update Available" (Download), "Update is Ready to Install" (Install), "Update Installed" (Restart) and "Updates Disabled". The disabled reasons include "Updates are disabled by your organization." and "Updates are manually disabled. Change the "update.mode" setting to enable."
https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/contrib/update/browser/updateTooltip.ts (read 2026-11-11) - An organisation can require a version: "Update required by your organization", "Your organization requires {0} {1} or later to use AI features."
https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/services/policies/common/managedSettingsUpdate.ts (read 2026-11-11) - The enterprise page (approved 11/11/2026): VS Code "releases weekly updates"; with
none, "users cannot update … through the application".
https://raw.githubusercontent.com/microsoft/vscode-docs/main/docs/enterprise/updates.md (read 2026-11-11)
Copy.
- The tooltip as the Updates page's skeleton: current and latest with commits, release date, notes, one button naming the next step, Copy (D5, Copy version info).
- A sentence per reason updates are off (D10): never just "disabled".
- The idle-restart guard (D3): everything restorable, no agent session running, no focus taken (question 11).
- The age reminder and the organisation's minimum version (questions 10 and 15).
Refuse.
- A notes tab that opens itself. VS Code is testing a quieter tooltip; D2's footer mark is that.
- A preference named after check timing. Ours names the outcome for the person.
3. Firefox
What it is. A browser with a full Settings section for updates, a history of installs, public enterprise policies and an escalation clock. Its strings are the most exact here.
| Update model | Firefox |
|---|---|
| Where it lives | Settings, "Firefox updates"; the About dialog; an app-menu banner. |
| Versions shown | "Version 1xx What's new"; Nightly adds its build date. |
| Channel | Shown, not switched: "You are currently on the {channel} update channel." Each channel is its own build (cited from memory, not re-read today). |
| Preference | "Automatically install updates (recommended)" · "Check for updates, but choose when to install". |
| Release notes | "What's new" per version, written by Mozilla. |
| Restart prompt | "Update and restart" · "Dismiss": "Open tabs and windows will be restored." Badge after 4 days, full prompt after 8. |
| Silent behaviour | Checks every 6 hours; a background service installs while closed (Windows); "Update History". |
| Managed elsewhere | DisableAppUpdate, AppAutoUpdate, ManualAppUpdateOnly, AppUpdatePin; "Updates disabled by your organization". |
The facts behind the table.
- Settings adds "When Firefox is not running", "Show fewer update reminders" and "Updates are managed by your operating system" to the two choices in the table.
https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/preferences/preferences.ftl (read 2026-11-11) - About: "Restart to update Firefox", "Update failed. Download the latest version", "Updates disabled by your organization". The banner: "Get the latest version of Firefox. Open tabs and windows will be restored."
https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/aboutDialog.ftl (read 2026-11-11)
https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/appMenuNotifications.ftl (read 2026-11-11) - Update History: "The following updates have been installed", columns Update Name, Install Date, Type, State.
https://raw.githubusercontent.com/mozilla-firefox/firefox/main/toolkit/locales/en-US/toolkit/updates/history.ftl (read 2026-11-11) - Timing: check every 21600 seconds; badge after 345600 ("4 days"); "the big UI" after 691200 ("192 hours"); a build may go unchecked for 63 days.
https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/branding/official/pref/firefox-branding.js (read 2026-11-11) AppAutoUpdatefalse: updates "are downloaded but the user can choose when to install".ManualAppUpdateOnly: "The user will never be prompted to install updates".AppUpdatePinprevents updates "beyond the specified version".
https://raw.githubusercontent.com/mozilla/policy-templates/master/docs/index.md (read 2026-11-11)
Copy.
- "(recommended)" on the default (D1).
- The restart sentence that says what survives (R2): "qcontrol keeps watching while the app restarts."
- Update History with a state column, so failures show too (R5).
- Two managed sentences: by your organisation, by your operating system (D10); and the pin as an organisation's policy (R6).
Refuse.
- "The big UI" after eight days. R1 has no modal at any age; the age is said instead (question 9).
4. 1Password
What it is. A security tool on work laptops, managed by employers: the closest in kind to us. The channel is a setting in the one app, and the organisation can limit it. Most facts are search excerpts.
| Update model | 1Password |
|---|---|
| Where it lives | Settings › Advanced ("Release channel"); "Install updates automatically"; "Check for updates" in the menu bar and About. |
| Versions shown | Full build numbers, e.g. "8.12.44-24" for a beta. |
| Channel | Production · Beta · Nightly in place; a new channel applies at its next newer release; Nightly to Production needs a reinstall. |
| Preference | "Install updates automatically" on or off; off means no checks until "Check for updates" (community answer). |
| Release notes | releases.1password.com per platform and channel, with RSS. |
| Restart prompt | Not verified today. |
| Silent behaviour | Windows: weekly check, install only while the app is locked (community answer). |
| Managed elsewhere | MDM keys; a 1Password.com channel policy ("Production only") that overrides MDM; a policy requiring the latest version. |
The facts behind the table.
- "Install updates automatically" governs installs; the release channel is under Advanced.
https://support.1password.com/betas/ (search excerpt, 2026-11-11) - Switching: "until a version is available that is both in the selected release channel, and newer than the current version installed, 1Password will not update." Users report staying on Nightly with Production selected.
https://1password.community/discussion/comment/640977 (search excerpt, 2026-11-11)
https://www.1password.community/1password-at-home-31/the-advanced-setting-release-channel-is-not-respected-23433 (search excerpt, 2026-11-11) - A 1Password.com channel policy "overrides these MDM settings for automatic updates and the release channel"; "Production only" moves Beta and Nightly members to Production; a separate policy requires the latest version.
https://support.1password.com/mobile-device-management/ (search excerpt, 2026-11-11)
https://1password.com/blog/browser-auto-lock-release-channel-policies (search excerpt, 2026-11-11) - Windows installs automatically only when the app is locked (community reply).
https://www.1password.community/1password-at-work-58/update-concern-on-windows-app-v8-12-0-23924 (search excerpt, 2026-11-11)
Copy.
- The channel inside the one install, and "newer in the chosen channel, or nothing" when leaving Beta (later era; no downgrade).
- The organisation limits the channels, overriding the device (plan §Two eras).
- Install while nobody is using it (D3): for us, the window closed to the tray.
Refuse.
- Off means no checks. The plan checks whatever the preference (D10).
- A channel kept in two places. The reported drift is why D12 keeps it in the feed.
5. Slack
What it is. A B2B Electron app with no preference for the person: updates arrive automatically, show as a badge, and apply on restart. Administrators turn them off by configuration.
| Update model | Slack |
|---|---|
| Where it lives | A badge on the help icon, then an update card; Help › Check for updates. |
| Versions shown | Per-version notes pages; nothing more verified. |
| Channel | A desktop beta (section 12). |
| Preference | None. |
| Release notes | Pages per OS, stable and beta. |
| Restart prompt | "Restart Slack"; "Restart to apply update" after a manual check. |
| Silent behaviour | Automatic download; applies at the next restart. |
| Managed elsewhere | AutoUpdate (4.31 and later, enforceable); store installs update through the store. |
The facts behind the table.
- "The help icon in Slack will be badged"; the person opens the card and selects "Restart Slack"; or "Click Check for updates, then click Restart to apply update." Store installs are updated by the store.
https://slack.com/help/articles/360048367814-Update-the-Slack-desktop-app (search excerpt, 2026-11-11) AutoUpdate"enables or disables automatic updates of the desktop app", is enforceable, from version 4.31.
https://slack.com/help/articles/11906214948755-Manage-desktop-app-configurations (search excerpt, 2026-11-11)
Copy.
- A badge on something the person already opens (D4): our tray dot and footer mark.
- Say where updates come from when a store or manager owns them (D10).
Refuse.
- No preference at all. Mark's prompt asks for one.
6. The Claude desktop app
What it is. Anthropic's Electron app: automatic updates, a menu item, an MDM key and a forced-restart window. Public issues describe what happens when an app hosting long-running agent sessions restarts itself. That is the nearest thing in this document to our own risk.
| Update model | Claude desktop |
|---|---|
| Where it lives | "Claude › Check for Updates…" (macOS), "Help › Check for Updates…" (Windows); an in-app "Relaunch to update". |
| Versions shown | Numbers like v1.2581.0; the docs gate features by version. |
| Channel | None visible. |
| Preference | None for the person; an organisation toggle. |
| Release notes | A running article across the Claude apps; none at the restart control. |
| Restart prompt | "Relaunch to update" applies at once. |
| Silent behaviour | A "stealth update" relaunch after an idle timeout; only a log line. |
| Managed elsewhere | disableAutoUpdates; autoUpdaterEnforcementHours 1 to 72, default 72. |
The facts behind the table.
autoUpdaterEnforcementHours: "Hours before forcefully restarting Claude to apply a prepared update". With the organisation's toggle off, "Claude Desktop stops checking for and downloading updates", but "Users can still update from the app menu, and a downloaded update still installs."
https://support.claude.com/en/articles/12622667-enterprise-configuration (read 2026-11-11)- Installed in
~/Applications, "Users can update without administrator privileges"; in/Applicationsthey need administrator access.
https://support.claude.com/en/articles/12611117 (read 2026-11-11) - The menu items, "Claude > Check for Updates…" and "Help > Check for Updates…".
https://code.claude.com/docs/en/desktop-changelog (read 2026-11-11; the URL now serves the desktop reference) - Issue #61582: "Relaunch to update" "applies the update immediately, with no changelog, no confirmation, and no option to defer". The stale bot closed it as not planned.
https://github.com/anthropics/claude-code/issues/61582 (read 2026-11-11) - Issue #92207:
[stealth-update] Triggering stealth update after idle timeout, then a relaunch that closed every Remote Control bridge for 75 minutes to four hours; "no notification or 'restart to update' banner", onlymain.log. Closed as a duplicate of #95364.
https://github.com/anthropics/claude-code/issues/92207 (read 2026-11-11)
Copy.
- Policy can stop the automatic path and keep Check now (question 7).
- A per-user install updates without an administrator: the app's half of T4.
Refuse.
- A forced restart on a timer (R1). If an organisation wants a deadline later, it is a window shown in advance (section 9).
- An idle relaunch traced only in a log (R3), and one that cuts live sessions (R2).
- A restart control with no notes and no "later". Each complaint in #61582 is a row of our model.
7. Raycast
What it is. A menu-bar launcher, a tray app like ours. It ships weekly, checks daily, offers updates inside its own search, and shows notes after the relaunch.
| Update model | Raycast |
|---|---|
| Where it lives | Settings › About; the menu bar icon; a Check for Updates command; the update at the top of root search. |
| Versions shown | The version in About; a dated changelog per version. |
| Channel | The v2 beta was a separate app until v2 replaced v1. |
| Preference | None found. |
| Release notes | Changelog per version, shown after the relaunch. |
| Restart prompt | Offered in root search; the new build starts when the old one quits. |
| Silent behaviour | Daily check; on Windows, background updates "without interrupting your work". |
| Managed elsewhere | Not found. |
The facts behind the table.
- About shows the version and changelog links, "You can also check for updates here"; on Windows, "Raycast will notify you directly in root search".
https://manual.raycast.com/settings (search excerpt, 2026-11-11)
https://manual.raycast.com/windows/product-updates (search excerpt, 2026-11-11) - The 2020 post: weekly releases made the old pop-up an interruption "in the middle of some action"; the update now sits "on the top of the root search", and notes show "after the app is relaunched".
https://medium.com/raycastapp/how-we-built-an-app-update-flow-our-users-love-89820602e8fe (search excerpt, 2026-11-11)
Copy.
- The update where the person already is (D4, D11): the tray menu.
- Notes on the first open after any restart, not only after a quiet install.
Refuse.
- No "not now" and no "only when I click".
Part B. Early access against staged general release
8. VS Code Insiders
What it is. A second VS Code built nightly, installed beside Stable with its own settings: the open-door fast track.
| Track | VS Code Insiders |
|---|---|
| Who is in the track | Anyone who installs it. |
| How they join and leave | Install the second app; leave by using Stable. On the web only, a switch with a reload. |
| What they see | Nightly builds; separate settings, extensions and sync. |
| Cadence | Nightly; Stable weekly. |
| How rollout is controlled and halted | Not documented to users. |
| How the mature version differs | Stable: weekly, per-version notes, UpdateMode policy. |
The facts behind the table.
- Insiders "installs side by side to your stable VS Code install and has isolated settings, configurations, and extensions … updated nightly so you'll get the latest bug fixes and feature updates from the day before."
https://raw.githubusercontent.com/microsoft/vscode-docs/main/docs/supporting/faq.md (read 2026-11-11) - The web switch confirms "Changing the version requires a reload to take effect" and offers a separate Insiders sync service.
https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/contrib/update/browser/update.ts (read 2026-11-11)
Copy. Say what the track gives: "the fixes from the day before" is the honest first line of our partner notes.
Refuse. The second app. For us it means a second inbox and footer over one sensor (question 13).
9. Chrome's channels
What it is. Canary, Dev, Beta and Stable, plus Extended Stable for enterprises, on a fixed calendar, with a staged Stable rollout and the most detailed restart policy here.
| Track | Chrome |
|---|---|
| Who is in the track | Canary, Dev, Beta: anyone. Stable: everyone. Extended Stable: enterprises, by policy. |
| How they join and leave | Install the channel's build, side by side; going back can mean deleting a profile. |
| What they see | Each channel's builds; Stable rolls out as two identical builds that differ only in build number. |
| Cadence | A milestone to Stable every two weeks, weekly refreshes, two weeks in Beta, Extended Stable every eight weeks. |
| How rollout is controlled and halted | Early Stable to "a small percentage"; all users "within one to two weeks unless major issues arise". |
| How the mature version differs | Enterprise policy: Extended Stable, RelaunchNotification recommended or required, with a period. |
The facts behind the table.
- "Chrome ships a new milestone … to the stable channel every two weeks"; "weekly updates (called refreshes)"; Extended Stable is "only available to enterprises"; the rollout uses "two separate builds which are identical, except for the build number".
https://raw.githubusercontent.com/chromium/chromium/main/docs/process/release_cycle.md (read 2026-11-11) - Restart strings: "A Chrome update has been available for # days"; "Your administrator asks that you relaunch Chrome to apply this update"; "Relaunch Chrome within # days"; "Chrome will update when your screen is unused"; "You can relaunch now, or set Chrome to update the next time your screen remains on and unused for 5 minutes."
https://raw.githubusercontent.com/chromium/chromium/main/chrome/app/google_chrome_strings.grd (read 2026-11-11) - Channels "may be run in parallel" with their own user data. After a downgrade, "You'll have to delete your profile data." Canary is daily (cited from memory, not re-read today).
https://www.chromium.org/chrome-release-channels (search excerpt, 2026-11-11)
https://www.pcworld.com/article/2463916/how-to-switch-chrome-channels-to-test-new-features-before-theyre-cool.html (search excerpt, 2026-11-11)
Copy.
- "Available for # days" (question 9).
- "Update when your screen is unused" as the person's choice (question 6).
- A calendar, and the organisation's relaunch window, later: shown with the days counting down.
Refuse.
- Required relaunch. Nothing restarts Qpoint on our say-so (R1).
10. TestFlight
What it is. Apple's beta service, and the model for a small, named early cohort: an internal team, invited external testers, a note per build, builds that expire.
| Track | TestFlight |
|---|---|
| Who is in the track | Internal: up to 100 App Store Connect users. External: up to 10,000 by invitation or public link. |
| How they join and leave | Accept an invitation or link; the developer removes testers or expires builds. |
| What they see | The group's builds, with test information and a "What to Test" note per build. |
| Cadence | Per upload; internal groups can receive every build automatically. |
| How rollout is controlled and halted | By group; the first external build needs App Review; any build can be expired; all stop after 90 days. |
| How the mature version differs | The App Store, with phased release (section 11). |
The facts behind the table.
- "You can test a build for up to 90 days"; "external testers (up to 10,000 people) and internal testers (up to 100 App Store Connect users …)"; for external groups "A review is required only for the first build"; test information includes "an explanation of features to test".
https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview (read 2026-11-11) - "Enable automatic distribution" sends every build to an internal group; "Builds marked as internal can only be added to internal tester groups."
https://developer.apple.com/help/app-store-connect/test-a-beta-version/add-internal-testers (read 2026-11-11) - The "What to Test" note shows with the build; no official length limit found.
https://helm-app.com/guides/write-what-to-test/ (search excerpt, 2026-11-11)
Copy.
- "What to try" with each partner build, added to D6's three parts.
- Audiences as groups:
notes.audiencecan grow frompartners | publictoteam | partners | public.
Refuse.
- Expiry as a hard stop. A sensor that stops is a hole in governance (question 14).
- Third-party review before the cohort sees a build. The gate is the person who cuts it (D7).
11. Staged percentages: Sparkle, the App Store, Google Play
What it is. Three ways of offering one version to a growing share of installs. Sparkle does it in the client, Apple over seven fixed days, Google by percentage with a halt.
| Track | Sparkle | App Store phased release | Google Play staged rollout |
|---|---|---|---|
| Who is in the track | Seven groups; a random id kept on the install, never sent. | "A random sample of users with automatic updates on", not told. | A percentage the developer sets. |
| How they join and leave | Assigned; a manual check skips the wait. | Assigned; anyone can download it manually. | Assigned; test tracks first (internal, up to 100). |
| What they see | An alert with notes; Skip This Version, except for critical updates. | The update and its notes. | The update; an in-app prompt by priority, 0 to 5. |
| Cadence | One group per phasedRolloutInterval. | 1, 2, 5, 10, 20, 50, 100% on days 1 to 7. | As the developer raises it. |
| How rollout is controlled and halted | Edit the feed; critical and manual checks bypass. | Pause up to 30 days in total; Release to All Users. | Halt: nobody new gets it; those who have it keep it. |
| How the mature version differs | This is it; channels branch off the default and return. | This is it. | This is it, with priority and staleness. |
The facts behind the table.
- Sparkle "hardcodes the number of groups to 7"; the group id "is not transmitted to servers"; phases "do not take effect for updates that are marked critical or for when the user manually checks"; critical updates "do not let the user skip them"; "an updater cannot exclude itself from the default channel".
https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/publishing/index.md (read 2026-11-11) - Sparkle's alert: "%@ %@ is now available—you have %@.", "Install Update", "Remind Me Later", "Skip This Version", "Install on Quit"; first-run, "Check for updates automatically?"
https://raw.githubusercontent.com/sparkle-project/Sparkle/2.x/Sparkle/Base.lproj/Sparkle.strings (read 2026-11-11) - Sparkle asks for automatic checks "on second launch"; automatic installs default to off. For apps without a Dock icon, a scheduled alert never steals focus, and gentle reminders use a badge instead.
https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/customization/index.md (read 2026-11-11)
https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/gentle-reminders/index.md (read 2026-11-11) - Apple: 1%, 2%, 5%, 10%, 20%, 50%, 100% over 7 days, "without any notification of their participation"; "pause the release for up to 30 days"; it "can be manually downloaded … by anyone at any time".
https://developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases (read 2026-11-11) - Play: after a halt, "no additional users will receive the app version … Users who already received it will remain on that version." Priority runs "between 0 and 5"; it "cannot be changed later".
clientVersionStalenessDays()lets the app wait "a few days before notifying".
https://support.google.com/googleplay/android-developer/answer/6346149 (search excerpt, 2026-11-11)
https://developer.android.com/guide/playcore/in-app-updates/kotlin-java (read 2026-11-11)
Copy.
- The share drawn on the install and never sent (Sparkle): the plan's stable number per install, with the privacy sentence.
- A manual check bypasses the stage (Apple, Sparkle), as the plan says.
- Apple's curve from
published_at, so CI never edits the feed daily. - Halt as "nobody new" (Play): the plan's
pulled. - Priority set once per release; critical unskippable and unstaged (Play, Sparkle): question 12 and
min_version.
Refuse.
- Skip This Version (R6, D8).
- The second-launch question. A default with a setting instead (D1).
12. Early access in B2B: Slack's desktop beta and Microsoft 365 Frontier
What it is. Two ways a business product lets some people go first. Slack's is personal: anyone opts in. Microsoft's is organisational: the administrator chooses who is in Frontier, and the rest stay on Standard or Deferred. Frontier replaces Targeted release, which retires in January 2027. No design-partner update track was found to cite; c62's partner era is our own.
| Track | Slack desktop beta | Microsoft 365 Frontier · Standard · Deferred |
|---|---|---|
| Who is in the track | Anyone who opts in. | The users an admin enrols; others Standard or Deferred. |
| How they join and leave | "Opt into beta" on slack.com/beta; leave in Preferences › Advanced. | The admin centre's release preferences. |
| What they see | Beta builds; separate beta notes per OS. | Features early (Frontier); major updates held about 30 days (Deferred). |
| Cadence | The latest beta within 6 hours. | Per feature; Deferred about 30 days behind. |
| How rollout is controlled and halted | By Slack; not documented to users. | By the tenant's preferences. |
| How the mature version differs | The stable app with AutoUpdate. | This is it: a speed per group. |
The facts behind the table.
- Beta members "receive new builds … before they become available to the general public"; the app will "install the latest beta within 6 hours"; opt out in Preferences › Advanced.
https://slack.com/help/articles/226192087-Join-Slack%E2%80%99s-desktop-app-beta-program (search excerpt, 2026-11-11) - Administrators "manage enrollment centrally, choosing users for early access, while others remain on Standard or Deferred"; Deferred holds major updates about 30 days; "Standard release should be the primary release channel for most customers."
https://mc.merill.net/message/MC1490899 (search excerpt, 2026-11-11)
https://learn.microsoft.com/microsoft-365/admin/manage/release-options-faq (search excerpt, 2026-11-11)
Copy.
- Leaving early access is a setting in the app, beside the preference (D11, D12).
- A speed per group, chosen by the organisation: first, with everyone, a month later.
- The default stated in the policy's own words, so early access stays a choice.
Refuse.
- Early access as an opt-in download. In the partner era every install is a partner's; the one channel is theirs.
The reading against the model
What the reading says about our model
Each part of the model against what the precedents do. "Stricter" means ours asks more; "thinner" means a precedent carries something ours does not yet.
| Part of the model | What the precedents do | Ours |
|---|---|---|
| The states (up to date · checking · available · downloading · ready to restart · installed · failed · offline · managed) | Zed six, VS Code over a dozen, Firefox about ten, each with its own label; VS Code, Firefox and Zed name the managed cause. | Equal on states, stricter on sentences (R4). Thinner: no state column in the history (Firefox). |
| The preference (Automatically · Ask me first · Only when I click) | On or off (Zed, 1Password), two values (Firefox), check timing (VS Code), none (Slack, Claude, Raycast). Default automatic everywhere but Sparkle. | Stricter: three outcomes, checks always run. |
| Installed silently, then what's new | Zed: a toast. VS Code: a notes tab, or a title-bar tooltip under test. Raycast: notes after the relaunch. Firefox: history only. Claude: a log line. | Between VS Code's experiment and Firefox's history (D2). Stricter than Claude. |
| Restart | "Restart to Update" everywhere. Escalation by clock: Firefox (4 and 8 days), Sparkle (a week), Claude (72 h, forced), Chrome (a period). Idle restarts: VS Code (guarded), Chrome (chosen), Claude (unguarded). | Stricter: no modal, no deadline (R1). Thinner: D3 has no guard; Ask me first has no age. |
| Notes and version | VS Code: version, commit, date, Copy. Zed: a page per version, commits for Nightly. TestFlight: a note per build. | Equal (D5, D6). Thinner: no "what to try". |
| Managed elsewhere | A sentence per cause (VS Code, Firefox); the packager's sentence (Zed); an organisation minimum (VS Code); Check now kept (Claude). | Equal now (D10, T5). |
| Now: one channel, internal notes, trail, no skip | Fast tracks are separate apps (Insiders, Canary, Zed Preview, Raycast Beta, Slack beta) or groups (TestFlight). Skip only in Sparkle. | Stricter: one install, one channel, no skip (R6). |
| Later: channels, staged %, public notes, policy | In-place channels (1Password, Sparkle); a 7-day curve, pause and halt (Apple, Play); priority (Play); organisation limits, pins, minimums, windows, speeds (section 12). | Equal in shape (rollout, pulled, min_version). Thinner: no priority, no curve, no "wait 30 days". |
Where ours is stricter: no restart while the window is open or on a timer (R1); the restart says the sensor keeps watching (R2); a quiet install leaves a visible trace (R3); no skip (R6); the channel in one place (D12). No precedent does all five. VS Code is nearest, and its two experiments move the way the plan points.
Where ours is thinner, and should not stay so:
- No guard on the idle relaunch (VS Code names one; the Claude issues show the cost). Question 11.
- No age line for an install that has stopped updating (VS Code two months, Firefox 63 days, Chrome "for # days"). Question 10.
- No clock in Ask me first. It should not escalate, but it can say how long the update has waited. Question 9.
- No state in the history (Firefox).
- No priority per release (Play, Sparkle), to map onto c137's modes. Question 12.
- No "what to try" in partner notes (TestFlight).
- No organisation "wait" beside the pin (Microsoft's Deferred). Question 15.
What we copy
- The Updates page as VS Code's tooltip: both versions with commits, release date, notes, one button naming the next step, Copy (VS Code).
- The label is the state (Zed, VS Code, Firefox).
- A sentence per reason updates are managed (VS Code, Firefox), and the packager's sentence verbatim (Zed's
ZED_UPDATE_EXPLANATION). - The restart sentence that says what survives (Firefox's "Open tabs and windows will be restored").
- "(recommended)" on the default (Firefox).
- Notes per version with the trail behind them, written at the change (Zed's notes page, commit list and PR line).
- "What to try" with each partner build (TestFlight).
- Update history with a state (Firefox).
- The idle-restart guard (VS Code's
restartWhenIdle, Sparkle's background-app rule), and "restart when I'm away" as a choice (Chrome). - The update where the person already is: the tray menu and a badge, not a window (Raycast, Slack, Sparkle's gentle reminders).
- An age line, at most monthly (VS Code, Firefox, Chrome).
- The channel inside the one install; newer-or-nothing when leaving Beta (1Password, Sparkle).
- A local, unsent rollout share; manual checks bypass it; Apple's seven-day curve (Sparkle, Apple).
- Halt as "nobody new" (Play); priority set once; critical unskippable and unstaged (Play, Sparkle).
- The organisation's controls, later: allowed channels (1Password), a pin (Firefox), a minimum (VS Code), a relaunch window shown in advance (Chrome), a speed per group (Microsoft), Check now kept when automatic is off (Claude).
What we refuse
- A forced restart on a timer (Claude, Chrome's required relaunch).
- An idle relaunch traced only in a log (Claude's stealth update).
- A restart control without notes or "later" (Claude).
- Skip This Version (Sparkle).
- A modal at any age (Firefox's "big UI", Sparkle's second-launch question, Play's immediate flow).
- A notes tab or toast that opens itself after a quiet install (VS Code's default, Zed).
- Channels as separate apps (Insiders, Chrome, Zed Preview, Raycast Beta, Figma Beta, Slack beta).
- A boolean preference, or none (Zed; Slack, Claude, Raycast).
- Off meaning no checks (1Password, VS Code
none). - A channel stored in two places (1Password's reported drift).
- Build expiry as a hard stop (TestFlight); a downgrade that costs data (Chrome).
- A Terminal key as the only off switch (Linear, Slack's legacy key).
Open questions, each with a default
The plan's decisions are in its §Decisions. These are the questions the reading raised, with the plan's default where it has one and what the reading adds.
- The preference's default. Automatically, labelled "(recommended)", with no first-run question (D1). Zed, VS Code, Firefox, Slack and Claude update automatically by default. Sparkle asks on the second launch and leaves automatic installs off.
- Silent: no notice, or a quiet trace? A quiet trace (D2): the footer mark for seven days, the Updates page leading with what's new, the history. The precedents range from a toast (Zed) to a log line (Claude); ours sits beside VS Code's tooltip experiment and Firefox's history.
- Internal notes inline, or behind a link? Inline, with the trail one link away (D6). VS Code, Sparkle, Zed's local view and TestFlight all show notes in the app. Add "what to try".
- Skip this version. None; "Not now" defers (D8). Only Sparkle offers a skip, and it withdraws it for critical updates. In a product whose sensor is the evidence, a skipped version is a gap the organisation did not choose. Holding a version is the organisation's pin, later.
- Who owns release notes. The person who cuts the release owns the facts and the gate; the draft comes from the record; design owns the template and the voice (D7). Zed's PR line and TestFlight's note put the writing at the change.
- Restart timing. Automatically: at quit, at the machine's restart, or idle with the window closed (D3, guarded by question 11). Ask me first: Restart now · When I quit · When I'm away (Chrome). No prompt and no deadline.
- What "managed elsewhere" says. Who manages it and how to update there: "Updates are managed by Homebrew." with the command. Later: "Updates are managed by your organization." with what the policy allows. The preference is shown disabled with the reason (D10). If policy stops only the automatic path, Check now stays (Claude).
- Semver tag or SHA in the partner era. The tag, with the 7-char SHA beside it (D5), every partner build tagged (T3). VS Code shows "1.x (commit)" for both versions. Later, the tag alone, with the SHA in Copy version info.
- Does Ask me first escalate? No prompt, ever; the age is said instead. After three days the tray line and the footer read "ready since Tuesday" (Chrome's "available for # days").
- What does an install that has stopped updating say? After 60 days, one tray line at most once a month ("Qpoint 0.1.0 is 2 months old"), under any preference, managed included (VS Code, Firefox). The Updates page always shows the age.
- What guards the idle relaunch? Only when everything comes back as it was: no developer stream (c138), no mechanic session (c136), no open
requiredmessage (c137), no tour or capture running, the window closed, no focus taken (VS Code, Sparkle). The history records "while you were away". T6 may narrow D3 to quit and restart only. - Does a release carry a priority mapped to c137's modes? Not now. Later, a field set once per release (Play, Sparkle):
quietfor a normal release (the trace),normal(the tray dot) when it fixes a sharp edge the person reported, neverpriority. The floor ismin_version. - Channels later: a setting, or a second app? A setting in the same install, under Updates. Leaving Beta waits for Stable to pass it; the organisation can limit the channels (1Password, Sparkle, Slack's opt-out). A second app puts a second inbox over one sensor.
- Does a partner build expire? No (against TestFlight's 90 days). The age line (question 10) and, later,
min_versiondo the work. - What does the organisation's policy hold, later? Allowed channels, a pin, a minimum, a wait of about 30 days, an update window shown in advance, and who goes first (1Password, Firefox, VS Code, Microsoft, Chrome). Designed with c134; the native page leaves a slot for each.
- Does the staged rollout tell the person anything? No. An update not yet offered to this install is not shown, and Check now gets it (Apple, Sparkle), so nothing is hidden from someone who asks. The share is drawn locally and never sent.
Sources (all read 2026-11-11)
Read directly: the GitHub repositories of Zed, VS Code and vscode-docs, Firefox and its policy templates, Chromium, and Sparkle; developer.apple.com; developer.android.com; support.claude.com; code.claude.com; two anthropics/claude-code issues. Read as search excerpts, the pages being blocked: zed.dev, 1Password's support, blog and community, slack.com, manual.raycast.com, medium.com, support.google.com, chromium.org, learn.microsoft.com and a Microsoft 365 message-centre mirror, help.figma.com, linear.app, helm-app.com, pcworld.com. Cited from memory: Firefox's channel list and Chrome Canary's daily cadence.
To re-read from a laptop before the mocks are final: 1Password's Settings labels and restart prompt; Slack's update card; Raycast's macOS behaviour today (the post is from 2020); TestFlight's "What to Test" limit; Play's halt at 100%; Microsoft 365 Frontier's group rules; whether VS Code's two experiments have shipped.
https://raw.githubusercontent.com/zed-industries/zed/main/crates/ui/src/components/collab/update_button.rs · https://raw.githubusercontent.com/zed-industries/zed/main/crates/title_bar/src/title_bar.rs · https://raw.githubusercontent.com/zed-industries/zed/main/crates/auto_update/src/auto_update.rs · https://raw.githubusercontent.com/zed-industries/zed/main/crates/auto_update_ui/src/auto_update_ui.rs · https://raw.githubusercontent.com/zed-industries/zed/main/assets/settings/default.json · https://github.com/zed-industries/zed/blob/main/nix/build.nix · https://raw.githubusercontent.com/zed-industries/zed/main/.github/pull_request_template.md · https://zed.dev/docs/development/releases · https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/platform/update/common/update.config.contribution.ts · https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/contrib/update/browser/updateTooltip.ts · https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/contrib/update/browser/update.ts · https://raw.githubusercontent.com/microsoft/vscode/main/src/vs/workbench/services/policies/common/managedSettingsUpdate.ts · https://raw.githubusercontent.com/microsoft/vscode-docs/main/docs/enterprise/updates.md · https://raw.githubusercontent.com/microsoft/vscode-docs/main/docs/supporting/faq.md · https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/preferences/preferences.ftl · https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/aboutDialog.ftl · https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/locales/en-US/browser/appMenuNotifications.ftl · https://raw.githubusercontent.com/mozilla-firefox/firefox/main/toolkit/locales/en-US/toolkit/updates/history.ftl · https://raw.githubusercontent.com/mozilla-firefox/firefox/main/browser/branding/official/pref/firefox-branding.js · https://raw.githubusercontent.com/mozilla/policy-templates/master/docs/index.md · https://support.1password.com/betas/ · https://support.1password.com/mobile-device-management/ · https://1password.com/blog/browser-auto-lock-release-channel-policies · https://1password.community/discussion/comment/640977 · https://www.1password.community/1password-at-home-31/the-advanced-setting-release-channel-is-not-respected-23433 · https://www.1password.community/1password-at-work-58/update-concern-on-windows-app-v8-12-0-23924 · https://slack.com/help/articles/360048367814-Update-the-Slack-desktop-app · https://slack.com/help/articles/11906214948755-Manage-desktop-app-configurations · https://slack.com/help/articles/226192087-Join-Slack%E2%80%99s-desktop-app-beta-program · https://support.claude.com/en/articles/12622667-enterprise-configuration · https://support.claude.com/en/articles/12611117 · https://code.claude.com/docs/en/desktop-changelog · https://github.com/anthropics/claude-code/issues/61582 · https://github.com/anthropics/claude-code/issues/92207 · https://manual.raycast.com/settings · https://manual.raycast.com/windows/product-updates · https://medium.com/raycastapp/how-we-built-an-app-update-flow-our-users-love-89820602e8fe · https://raw.githubusercontent.com/chromium/chromium/main/docs/process/release_cycle.md · https://raw.githubusercontent.com/chromium/chromium/main/chrome/app/google_chrome_strings.grd · https://www.chromium.org/chrome-release-channels · https://www.pcworld.com/article/2463916/how-to-switch-chrome-channels-to-test-new-features-before-theyre-cool.html · https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview · https://developer.apple.com/help/app-store-connect/test-a-beta-version/add-internal-testers · https://helm-app.com/guides/write-what-to-test/ · https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/publishing/index.md · https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/customization/index.md · https://raw.githubusercontent.com/sparkle-project/sparkle-project.github.io/master/documentation/gentle-reminders/index.md · https://raw.githubusercontent.com/sparkle-project/Sparkle/2.x/Sparkle/Base.lproj/Sparkle.strings · https://developer.apple.com/help/app-store-connect/update-your-app/release-a-version-update-in-phases · https://support.google.com/googleplay/android-developer/answer/6346149 · https://developer.android.com/guide/playcore/in-app-updates/kotlin-java · https://mc.merill.net/message/MC1490899 · https://learn.microsoft.com/microsoft-365/admin/manage/release-options-faq · https://linear.app/docs/get-the-app.md · https://help.figma.com/hc/en-us/articles/4406787442711-Beta-features