Skip to content

cmux NEXT: Update Channel setting picks a release ring (Stable/Nightly/Canary/Dev) - #22781

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
cmux/release-rings
Oct 21, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
cmux/release-rings

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Adds the updates.channel setting (Settings > General > Updates > "Update Channel"): Stable, Nightly (default), Canary or Dev. This is the client half of release rings. The design is cmuxterm-hq docs/release-rings.md (manaflow-ai/cmuxterm-hq#2694, merged), with the sources it draws on in knowledge/inspiration/.

  • A ring is a set of sparkle:channel tags in the one cmux NEXT appcast (files-next.cmux.com/nightly-next/next/appcast-arm64.xml). The rings form a ladder, and each accepts its own tag plus every slower ring's: cmux-next-stable < cmux-next < cmux-next-canary < cmux-next-dev. There are no new feeds, bundle ids or keys.
  • Nightly is today's behaviour exactly. cmux-next is the tag every published item carries now, and allowedSparkleChannels for the Nightly ring is the same set as before. Canary and Dev get exactly what Nightly gets until CI publishes ring-tagged items. Stable gets nothing until soaked items are tagged, and its help text says so.
  • Sparkle's allowedChannels(for:) reads the ring from UpdateDriver.ring (UpdateController.ring). The read-only probe (updates.check, tagged DEV builds) now parses sparkle:channel and skips items the ring doesn't accept, so it never reports an update Sparkle won't install. Untagged items are still offered on every ring.
  • updates.status reports ring. Agents can't change the setting (.userOnly): which builds a Mac installs is the person's call.
  • Feeds other than cmux-next (stable, NIGHTLY, RC) still accept no tagged item on any ring.

Not in this PR:

  • CI publishing canary/dev/stable-tagged items. That belongs to the nightly-train owners. The design doc notes that sparkle_generate_appcast.sh and the rollback workflow must keep each item's tag first.
  • The App Store row.
  • The palette and CLI choice. The existing "Switch Update Channel" still swaps between the cmux and NIGHTLY apps.
  • web-ota's updates.web (cmux NEXT: signed web UI updates between app updates (every merge on NIGHTLY) #22777), whose default will follow this setting.

Generated exports (settings-schema.json, schemas/defaults/cmux-next.json, docs/mdm/*) are left to the autofix, per CLAUDE.md.

Risk

risk:high, because this is the updater. The default (Nightly) leaves the accepted Sparkle tags exactly as they are, so nothing changes for anyone unless they pick another ring. A non-default ring only changes which items of the existing signed feed are offered. Sparkle's EdDSA check and its never-downgrade rule are unchanged.

Changelog

  • Added: Settings > Updates > Update Channel picks Stable, Nightly, Canary or Dev builds of cmux NEXT (Nightly is unchanged; the other rings fill in as CI publishes them).

Observed / Not run

  • Ran: python3 scripts/cmux-next/gen-settings-sources.py --check passed. python3 scripts/cmux-next/prepush-gate.py reported no new violations. scripts/localization_catalog.py check reported no errors for the 6 new keys (all 9 required locales; its other errors are already on base).
  • Not run: Swift build and tests (UpdateRingTests, UpdateRingProbeTests). Agents don't compile on this host, so these run on CI. I haven't regenerated the settings exports.
    Agent session: huge-blue

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Adds the updates.channel setting (Settings > Updates > Update Channel) so users choose which release ring of cmux NEXT they get: Stable, Nightly (default), Canary, or Dev.

  • Rings are a ladder of sparkle:channel tags in the one cmux NEXT appcast; each ring accepts its own tag plus every slower ring's (stable < nightly < canary < dev), so a faster ring always gets at least what a slower ring gets and switching to a slower ring never downgrades.
  • Nightly is today's behavior exactly: it accepts the one tag every published item carries now, so nothing changes until CI publishes ring-tagged items. Stable gets nothing until items soak for a week; Canary and Dev get Nightly's builds for now.
  • Sparkle's allowedChannels, the read-only updates.check probe, and updates.status all follow the ring; the probe filters by the baked feed's allowed tags, like Sparkle does, so it never reports an update Sparkle won't install even on a test feed.
  • configure takes the ring as an optional String so the App needs no CmuxUpdater type in its public API, and a call without it keeps the current ring. Agents can't change the setting (.userOnly).
  • Feeds other than cmux NEXT still accept no tagged items on any ring. All 21 catalog locales are translated, and the settings exports (settings-schema.json, defaults, docs/mdm/*) are regenerated.

Not included: CI publishing ring-tagged items, the App Store row, and the existing palette/CLI channel switch.

Written for commit dc92954. Summary will update on new commits.

View guided diff Turn on auto-fix

…anary/Dev) in the one cmux NEXT appcast

Each ring accepts its own sparkle:channel tag and every slower ring's
(cmux-next-stable < cmux-next < cmux-next-canary < cmux-next-dev).
Nightly, the default, is the one tag every published item carries today,
so nothing changes until CI publishes ring-tagged items. Sparkle's
allowedChannels and the read-only probe both follow the ring;
updates.status reports it. Design: cmuxterm-hq docs/release-rings.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c1c-9365-71b3-b73b-dc961610d618&host=huge-blue
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review dc92954: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr22781 -f ref=cmux/release-rings -f platform=macos -f backend_mode=local

Not verified: macOS jobs did not run: compile and app tests were skipped on dc92954cdd; ci-status is green without them.

CI passes on dc92954cdd (run 39537896308 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

Tour of dc92954cdd (run): no media. The tour job failed before the tour ran (build or setup); the run log has the output.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-bqhpe created for this PR by the cmux coordinator.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

cmux-next guards / defaults-snapshot is red on 10 of 12 fresh feat-cmux-next PR heads in the last 2:00:00, so it is most likely a base red, not this PR's. The base-reds lane has it; a base merge picks up the fix once it lands.

…t; probe filters by the baked feed like Sparkle)

configure's ring is an optional String so the public default needs no
CmuxUpdater type, and a call without it keeps the ring. The probe takes
the allowed tags computed from the baked feed, as Sparkle's
allowedChannels does, so a test feed is filtered the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15c1c-9365-71b3-b73b-dc961610d618&host=huge-blue
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

owner: 01a15c1c-9365-71b3-b73b-dc961610d618

@teamleaderleo
teamleaderleo marked this pull request as ready for review October 21, 2026 02:26
@blacksmith-sh

blacksmith-sh Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@cursor

cursor Bot commented Oct 21, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@teamleaderleo
teamleaderleo temporarily deployed to cmux-tui-merge-tree October 21, 2026 03:19 — with GitHub Actions Inactive
@teamleaderleo
teamleaderleo merged commit 9882568 into feat-cmux-next Oct 21, 2026
@teamleaderleo
teamleaderleo deleted the cmux/release-rings branch October 21, 2026 03:52
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Human approval after the fact: Leo (teamleaderleo) approved this PR in the coordinator chat on 2026-10-20 ("I approved the 22781 ... this is not that bad"). It had merged through next-autoland without approval; no revert needed.

Agent session: cosmic-gray

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…high (#23371)

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

Leo, after #22781: a settings-only channel toggle that reuses the signed
feeds is not high-risk. UpdateTrack.swift and UpdatePreferences.swift (the
channel and preference values) are now normal. Parsing, probing, installing
and verifying an update stay high.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15bf1-fdac-78a0-ac2e-a3aef81402c7&host=cosmic-gray

* ci(risk): the channel setting is UpdateRing, not UpdateTrack

Review of #23371: UpdateTrack is the build's release line and decides whether
Sparkle runs, so it stays high (now pinned by the test). The user's ring is
UpdateRing in the CmuxUpdater package.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15bf1-fdac-78a0-ac2e-a3aef81402c7&host=cosmic-gray

* ci(risk): the CmuxUpdater package is the update path

Signature verification, the feed resolver, the Sparkle driver and the install
code graded normal because no high rule named the package. Only UpdateRing
stays normal; each file is pinned by a test that fails on base.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15bf1-fdac-78a0-ac2e-a3aef81402c7&host=cosmic-gray

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
teamleaderleo added a commit that referenced this pull request Oct 21, 2026
…2974)

* ci: run the feat-cmux-next risk tier gate from main, enforced now

GitHub runs pull_request_target workflows from the default branch, so
feat-cmux-next's risk-tier.yml never ran: no feat pull request got a risk
label or a risk evidence check, and risk:high ones (updater, nightly.yml,
signing) merged with no person looking (#22781, 2026-10-21). This copy on
main grades feat-cmux-next pull requests with the classifier at the pull
request's base commit (scripts/ci/risk_tier.py lives on feat-cmux-next),
never the pull request's code, and holds high from now instead of after the
feat copy's advisory window (2026-10-24).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15bf1-fdac-78a0-ac2e-a3aef81402c7&host=cosmic-gray

* ci(risk): grade with the classifier at the tip of feat-cmux-next, not the pull request's stale base commit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?harness=claude&session=01a15bf1-fdac-78a0-ac2e-a3aef81402c7&host=cosmic-gray

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch had an error being deployed

1 failed and 2 inactive deployments
sentry-dsyms — dc92954c Deployed Oct 21, 2026 by teamleaderleo
artifacts — dc92954c Deployed Oct 21, 2026 by teamleaderleo
cmux-tui-merge-tree — dc92954c Deployed Oct 21, 2026 by teamleaderleo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant