ci(risk): an update channel setting is normal; the update path stays high

Merged
TE
16d ago
+57-3

Summary

Asked by claude-sr2 (relayed by held-queue triage), 2026-10-21. Leo approved #22781 after the fact and said that update-channel and dev-build settings changes like it do not feel high-risk to him. The decision: keep the updater's install, signing and feed-verification code at risk:high, and let a settings-only channel toggle that reuses the existing signed feeds be normal. The gate has no "medium" tier; normal is the middle tier.

scripts/ci/risk_tier.py now has a normal rule, ahead of the high update-path rule, for the two files that only hold the channel and preference values:

  • CmuxUpdater/UpdateRing.swift: the user's ring, the updates.channel setting (Stable, Nightly, Canary or Dev) and the Sparkle channels each ring accepts;
  • CmuxNextUpdater/UpdatePreferences.swift: install-on-quit, how to notify, how many versions to keep.

Every other updater code file stays high (the updater's views, share sheet and strings were already normal or low and are unchanged), including:

  • UpdateTrack.swift, the build's own release line, which also decides whether Sparkle runs at all;
  • AppcastParser, AppcastSelector, UpdateProber and UpdaterService+Flow;
  • UpdateInstallPreflight, RollbackSwap and UpdateTransfer.

The settings schema and CmuxNextSettings were already normal or low. docs/ci/risk-tiers.md records the distinction.

#22781 itself would still grade high, since it also changed the appcast parser and the prober.

The CmuxUpdater package is now high too (coord-deputy, 2026-10-21: in this PR, so the risk gate changes once). Before this PR no high rule covered Packages/macOS/CmuxUpdater/, so these files graded normal:

  • the channel switch's AppSignatureVerification and SecurityAppSignatureInspector;
  • UpdateFeedResolver;
  • the Sparkle driver (UpdateDriver*);
  • the install code (UpdateController+InstallAttempt, +BackgroundInstall, InstallWatchdog).

The high update-path rule now includes Packages/macOS/CmuxUpdater/*. UpdateRing.swift stays normal, because the channel rule sits above it, and the package's Tests/ stay low.

Nothing else changes: no other path changes tier.

Testing

python3 tests/test_risk_tier.py on huge-blue: 31 tests OK. On the base risk_tier.py, both new tests fail (12 failures).

test_an_update_channel_setting_is_normal_and_the_update_path_stays_high checks two things:

  • a channel PR made only of these files and the settings schema grades normal;
  • adding any one of eight update-path files (UpdateTrack.swift among them) grades it high.

test_the_cmux_updater_package_is_the_update_path checks that each of these grades high on its own: the signature check, the signature inspector, the channel switcher, the feed resolver, the three Sparkle driver files, the two install-attempt files, InstallWatchdog and Package.swift. It also checks that UpdateRing.swift is normal and that the package's tests are low.

Observed / Not run

Observed: the test runs above, and prepush-gate.py with no new violations. Not run: the risk-tier workflow on a real channel-only PR.

Changelog

none

Agent session: cosmic-gray

🤖 Generated with Claude Code