Skip to content

Bump Sparkle to 2.9.3 to fix auto-update agent kill on macOS 26 - #6678

Merged
lawrencecchen merged 1 commit into
mainfrom
fix-sparkle-2.9.3-updater-sdk
Jun 23, 2026
Merged

lawrencecchen merged 1 commit into
mainfrom
fix-sparkle-2.9.3-updater-sdk

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes in-app auto-update failing with SUSparkleErrorDomain(4005) / underlying (10) "agent connection was never initiated" on macOS 26 for a subset of users.

Root cause (full investigation in #5123): cmux ships the Sparkle 2.8.1 prebuilt binary, whose Autoupdate/Updater.app are built against the macOS 15.5 SDK (Runtime Version 15.5.0), while the cmux app is built against the macOS 26 SDK (26.4.0). On macOS 26 the kernel's AppleSystemPolicy rejects the SDK-mismatched progress agent at launch:

kernel (AppleSystemPolicy) ASP: Validation category (6) does not match top-level policy match (8)
   for process: .../Caches/com.cmuxterm.app/.../Launcher/<id>/Updater.app/Contents/MacOS/Updater
loginwindow ... appDeath for org.sparkle-project.Sparkle.Updater
launchd failed lookup: name = com.cmuxterm.app-spkp, requestor = Updater, error = 3: No such process

The progress agent dies, -spkp never registers, the host times out (~19s) and surfaces 4005. It is machine-state-gated, so it reproduces for some users and not others on the same OS. Controls: Helium ships the same Sparkle 2.8.1 but built from source against the 26 SDK (Updater RV 26.0.0) and is immune; Codex ships 2.9.1 (RV 26.2.0) and is immune.

Fix

Bump Sparkle 2.8.1 -> 2.9.3. Sparkle 2.9.3's prebuilt helpers are built against the macOS 26.2 SDK (Runtime Version 26.2.0), matching the host, which clears the validation-category mismatch. Floor raised to 2.9.0 in both updater packages and the xcodeproj so resolution can't drop back below the SDK-fixed line; three lockfiles refreshed.

Verification

  • Confirmed the Sparkle 2.9.3 SPM artifact's Updater.app/Autoupdate report Runtime Version=26.2.0 / sdk 26.2 (vs 2.8.1's 15.5.0).
  • Local build resolves Sparkle @ 2.9.3 and compiles/links cmux against it with no Sparkle errors (no API breakage 2.8 -> 2.9).
  • Final artifact check: confirm the signed cmux DEV bundle's Sparkle.framework/.../Updater.app reports Runtime Version 26.x from the CI release-build.

Note: scope is the dependency bump only. Inside-out signing (#1962) is complementary hygiene but does not fix this on its own, since the failing helper is validly signed and spctl-accepts.

Follow-up

Consider a post-sign guard that asserts the bundled Sparkle helpers' SDK major matches the host, to prevent a future Sparkle pin from re-introducing the mismatch.

Fixes #5123


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Medium Risk
Touches the auto-update stack (Sparkle helpers bundled in releases); scope is dependency-only with no API changes in app code, but a bad pin could still break updates for all users.

Overview
Upgrades the Sparkle dependency from 2.8.1 to 2.9.3 so in-app auto-update ships updater helpers built against a macOS 26–compatible SDK, addressing failures where the progress agent never connects on macOS 26.

The SPM minimum version floor moves from 2.5.1 to 2.9.0 in CmuxUpdater, CmuxUpdaterUI, and the Xcode project’s remote package reference; Package.resolved pins are refreshed in those packages and the workspace lockfile to 2.9.3. No application or updater source changes—only dependency metadata and lockfiles.

Reviewed by Cursor Bugbot for commit 2ff9f93. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Bumps Sparkle to 2.9.3 to fix macOS 26 auto‑update failures caused by the updater agent being killed at launch due to an SDK mismatch. Sets the minimum Sparkle requirement to 2.9.0 and refreshes lockfiles; fixes #5123.

  • Dependencies
    • Update Sparkle 2.8.1 → 2.9.3; raise floor to 2.9.0 in Packages/macOS/CmuxUpdater, Packages/macOS/CmuxUpdaterUI, and cmux.xcodeproj; refresh related Package.resolved files.

Written for commit 2ff9f93. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Chores
    • Updated Sparkle framework dependency from version 2.5.1 to 2.9.0 across all macOS packages and project configurations, with resolved version 2.9.3. This ensures improved framework compatibility and stability.

cmux shipped the Sparkle 2.8.1 prebuilt helpers, whose Autoupdate/Updater.app
are built against the macOS 15.5 SDK (Runtime Version 15.5.0), while the cmux app
is built against the macOS 26 SDK. On macOS 26 the kernel AppleSystemPolicy rejects
the SDK-mismatched progress agent at launch ("Validation category (6) does not match
top-level policy match (8)"), so Sparkle times out with SUSparkleErrorDomain(4005) /
underlying (10) "agent connection was never initiated" and no update installs.

Sparkle 2.9.3's prebuilt helpers are built against the macOS 26.2 SDK (RV 26.2.0),
matching the host, which clears the validation-category mismatch. Raise the floor to
2.9.0 in both updater packages and the xcodeproj, and refresh the three lockfiles.

Fixes #5123
@vercel

vercel Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 23, 2026 11:52am
cmux-staging Building Building Preview, Comment Jun 23, 2026 11:52am

@coderabbitai

coderabbitai Bot commented Jun 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a29434bb-1763-472c-839a-0cd454952d7e

📥 Commits

Reviewing files that changed from the base of the PR and between 12833f5 and 2ff9f93.

📒 Files selected for processing (6)
  • Packages/macOS/CmuxUpdater/Package.resolved
  • Packages/macOS/CmuxUpdater/Package.swift
  • Packages/macOS/CmuxUpdaterUI/Package.resolved
  • Packages/macOS/CmuxUpdaterUI/Package.swift
  • cmux.xcodeproj/project.pbxproj
  • cmux.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

📝 Walkthrough

Walkthrough

Sparkle is upgraded from the 2.5.1 minimum / 2.8.1 resolved pin to a 2.9.0 minimum / 2.9.3 resolved pin. The change touches both Package.swift manifests, all three Package.resolved lockfiles, and the Xcode project's project.pbxproj.

Changes

Sparkle dependency upgrade to 2.9.x

Layer / File(s) Summary
Sparkle minimum version and resolved pin update
Packages/macOS/CmuxUpdater/Package.swift, Packages/macOS/CmuxUpdaterUI/Package.swift, cmux.xcodeproj/project.pbxproj, Packages/macOS/CmuxUpdater/Package.resolved, Packages/macOS/CmuxUpdaterUI/Package.resolved, cmux.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
Both Package.swift manifests and project.pbxproj raise the Sparkle from:/minimumVersion constraint from 2.5.1 to 2.9.0; all three Package.resolved lockfiles update the pinned revision and version from 2.8.1 to 2.9.3.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐇 Hop hop, the Sparkle shines anew,
From 2.8 we bound to 2.9's view!
The XPC timeout haunts us no more,
A version bump opens the update door.
This rabbit lands patches with a cheerful "Woohoo!" 🌟

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: bumping Sparkle to 2.9.3 to fix a macOS 26 auto-update agent failure.
Description check ✅ Passed The description is comprehensive and well-structured, covering summary, testing verification, and a checklist, though the Testing section uses narrative verification rather than structured testing steps.
Linked Issues check ✅ Passed The PR directly addresses issue #5123 by bumping Sparkle 2.8.1 to 2.9.3, which resolves the SDK mismatch root cause that prevents the progress agent from launching on macOS 26.
Out of Scope Changes check ✅ Passed All changes are focused on the Sparkle dependency update and related lockfile synchronization; no unrelated modifications are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Cmux Swift Actor Isolation ✅ Passed This PR only updates Sparkle dependency versions in config files and lockfiles—no production Swift code changes that could introduce actor isolation issues.
Cmux Swift Blocking Runtime ✅ Passed PR is a Sparkle dependency bump (2.8.1→2.9.3) affecting only configuration and lock files, not production Swift code. No blocking/timing synchronization patterns introduced in updater packages.
Cmux Expensive Synchronous Load ✅ Passed PR contains no production Swift code changes—only Sparkle dependency version bumps in Package.swift manifests and lockfiles. No expensive synchronous loads are introduced or moved to main actor/int...
Cmux Cache Substitution Correctness ✅ Passed PR contains only dependency version updates (Sparkle 2.8.1→2.9.3) in package configuration files; no application source code changes, so cache substitution rules do not apply.
Cmux No Hacky Sleeps ✅ Passed PR contains only dependency version bumps to Swift Package manifests, lock files, and Xcode project configuration. No TypeScript, JavaScript, shell, or non-Swift build/runtime scripts modified. Swi...
Cmux Algorithmic Complexity ✅ Passed PR contains only dependency version updates and lockfile refreshes with no production source code changes, so algorithmic complexity rules do not apply.
Cmux Swift Concurrency ✅ Passed PR only updates Sparkle dependency pins (2.8.1→2.9.3) in manifests and lockfiles; no cmux-owned Swift source code changes introduce or expand legacy async patterns.
Cmux Swift @Concurrent ✅ Passed PR contains only dependency manifest and lock file updates (Package.swift, Package.resolved, project.pbxproj); no Swift source code was modified, so concurrent annotation check is not applicable.
Cmux Swift File And Package Boundaries ✅ Passed PR only modifies Package.swift manifests with single-line dependency version bumps (2.5.1→2.9.0), no production source files changed. Files are 41-45 lines; changes are minimal and focused. This qu...
Cmux Swiftpm Lockfiles ✅ Passed PR includes all required package-local and root Xcode Package.resolved lockfiles for SwiftPM and Xcode project dependency changes; no gitignore violations detected.
Cmux Swift Logging ✅ Passed All logging in the diff complies with swift-logging.md: CLI print() statements are user-facing output (allowed), and NSLog uses are guarded by #if DEBUG (allowed).
Cmux User-Facing Error Privacy ✅ Passed PR only modifies dependency configuration (Package.swift, Package.resolved, project.pbxproj); no user-facing error messages, alerts, or implementation details were added or changed.
Cmux Full Internationalization ✅ Passed PR is a Sparkle dependency version bump (2.8.1→2.9.3) via Package.swift/resolved/pbxproj config changes only. No user-facing strings added or modified, no localization needed. Allowed as literal co...
Cmux Swiftui State Layout ✅ Passed CmuxUpdater/CmuxUpdaterUI SwiftUI code uses modern @Observable pattern with proper @MainActor isolation, no legacy @Published/@StateObject anti-patterns, no problematic GeometryReader/List patterns...
Cmux Architecture Rethink ✅ Passed PR is pure dependency version bump (Sparkle 2.8.1→2.9.3) with no Swift source code changes, no new timing patterns, locks, observers, or architectural violations per swift-architectural-rethink.md...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR is purely a dependency version bump (Sparkle 2.8.1→2.9.3) with no Swift window code additions or material changes; only Package manifests, lockfiles, and Xcode config updated.
Cmux Source Artifacts ✅ Passed All changed files are intentional source/config files: Package.swift manifests, .pbxproj project config, and Package.resolved lockfiles are explicitly part of the repo's source-of-truth model per `...
Cmux No Test Or Debug Seam In Production Source ✅ Passed PR modifies only dependency manifests (Package.swift), lock files (Package.resolved), and Xcode config (project.pbxproj)—no Swift source files under Sources/ directories, so the check is not applic...
Cmux No Ambient Global State ✅ Passed PR only modifies dependency manifests and lockfiles (Package.swift, Package.resolved, project.pbxproj), not production Swift code under Sources/. No new global state, functions, variables, or singl...
Cmux Hot Path Allocating Formatting ✅ Passed This PR only modifies dependency/configuration files (Package.resolved, Package.swift manifests, Xcode project config), not production Swift code. The custom check applies only to production Swift...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-sparkle-2.9.3-updater-sdk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Bumps the Sparkle auto-update framework from 2.8.1 to 2.9.3 across all three lockfiles and raises the minimum version floor to 2.9.0 in both standalone Package.swift manifests and the Xcode project. The fix targets SUSparkleErrorDomain(4005) failures on macOS 26 caused by an SDK-version mismatch between the prebuilt Sparkle helpers and the host OS.

  • Packages/macOS/CmuxUpdater/Package.resolved and CmuxUpdaterUI/Package.resolved: Both standalone package lockfiles bumped to revision d46d456107feacc80711b21847b82b07bd9fb46e (2.9.3).
  • cmux.xcodeproj/…/Package.resolved: Root Xcode workspace lockfile updated to the same 2.9.3 revision, consistent with the standalone packages.
  • Package.swift (both packages) and project.pbxproj: Minimum version floor raised from 2.5.1 → 2.9.0 across all three manifest locations to prevent resolution from falling back below the SDK-fixed release line.

Confidence Score: 5/5

Safe to merge — purely a dependency version bump with no production Swift source changes and no behavioral logic added.

All three cmux-owned Package.resolved lockfiles are updated to the same Sparkle 2.9.3 revision hash, both standalone Package.swift manifests and the Xcode project have the minimum version floor raised to 2.9.0, and no production Swift sources are touched. The change is narrow, internally consistent, and directly traceable to the upstream Sparkle release that ships helpers built against the macOS 26 SDK.

No files require special attention. All six changed files update version pins and lockfile hashes consistently.

Important Files Changed

Filename Overview
Packages/macOS/CmuxUpdater/Package.resolved Sparkle lockfile bumped from 2.8.1 (revision 5581748) to 2.9.3 (revision d46d456). Consistent with the other two lockfiles in this PR.
Packages/macOS/CmuxUpdater/Package.swift Minimum Sparkle requirement raised from 2.5.1 to 2.9.0, preventing resolution from falling back to pre-fix releases.
Packages/macOS/CmuxUpdaterUI/Package.resolved Sparkle lockfile bumped from 2.8.1 to 2.9.3. Revision hash matches CmuxUpdater and the Xcode workspace lockfile.
Packages/macOS/CmuxUpdaterUI/Package.swift Minimum Sparkle requirement raised from 2.5.1 to 2.9.0, matching the CmuxUpdater package manifest.
cmux.xcodeproj/project.pbxproj Xcode project minimum Sparkle version raised from 2.5.1 to 2.9.0, keeping the project reference consistent with the standalone package manifests.
cmux.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved Root Xcode workspace lockfile updated to Sparkle 2.9.3 (revision d46d456), consistent with both standalone package lockfiles.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["cmux.xcodeproj/project.pbxproj\nminimumVersion: 2.5.1 → 2.9.0"] --> B["Xcode workspace\nPackage.resolved\n2.8.1 → 2.9.3"]
    C["CmuxUpdater/Package.swift\nfrom: 2.5.1 → 2.9.0"] --> D["CmuxUpdater/Package.resolved\n2.8.1 → 2.9.3"]
    E["CmuxUpdaterUI/Package.swift\nfrom: 2.5.1 → 2.9.0"] --> F["CmuxUpdaterUI/Package.resolved\n2.8.1 → 2.9.3"]
    B --> G["Sparkle 2.9.3\nUpdater.app built against\nmacOS 26.2 SDK\nRuntime Version 26.2.0"]
    D --> G
    F --> G
    G --> H["✅ Clears AppleSystemPolicy\nvalidation-category mismatch\non macOS 26"]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["cmux.xcodeproj/project.pbxproj\nminimumVersion: 2.5.1 → 2.9.0"] --> B["Xcode workspace\nPackage.resolved\n2.8.1 → 2.9.3"]
    C["CmuxUpdater/Package.swift\nfrom: 2.5.1 → 2.9.0"] --> D["CmuxUpdater/Package.resolved\n2.8.1 → 2.9.3"]
    E["CmuxUpdaterUI/Package.swift\nfrom: 2.5.1 → 2.9.0"] --> F["CmuxUpdaterUI/Package.resolved\n2.8.1 → 2.9.3"]
    B --> G["Sparkle 2.9.3\nUpdater.app built against\nmacOS 26.2 SDK\nRuntime Version 26.2.0"]
    D --> G
    F --> G
    G --> H["✅ Clears AppleSystemPolicy\nvalidation-category mismatch\non macOS 26"]
Loading

Reviews (1): Last reviewed commit: "Bump Sparkle to 2.9.3 to fix auto-update..." | Re-trigger Greptile

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Verification (assembled bundle)

Built the branch locally (tag spark293). The embedded Sparkle helpers in the build product now report the macOS 26 SDK:

Sparkle.framework/Versions/B/Updater.app/.../Updater : Runtime Version=26.2.0  (sdk 26.2)
Sparkle.framework/Versions/B/Autoupdate              : Runtime Version=26.2.0

(was Runtime Version=15.5.0 with Sparkle 2.8.1). codesign re-signing during the release signing pass does not alter LC_BUILD_VERSION, so the signed release bundle carries the same 26.2 SDK helper, which clears the AppleSystemPolicy validation-category mismatch that produced the 4005 timeout.

CI: release-build, tests-build-and-lag, ui-regressions green. autoreview (Codex) clean, cmux Aziz policy clean.

Note: a true end-to-end "in-app update completes instead of 4005" dogfood requires a published build that an affected Mac installs and then updates from (the failing helper is the one in the currently-installed bundle). That validation happens once this lands in a nightly/release.

@lawrencecchen

Copy link
Copy Markdown
Contributor Author

Live dogfood on an affected machine ✅

Reproduced the fix end-to-end on a Mac that deterministically 4005s today (macOS 26.5, arm64, Notarized Developer ID).

Method: took the machine's real notarized nightly (0.64.14-nightly.2706980888901, broken Updater RV 15.5.0), swapped in only the Sparkle 2.9.3 framework (Updater RV 26.2.0), re-signed Developer-ID + notarized + stapled (source=Notarized Developer ID), installed, and triggered an in-app update.

Result: the update to 0.64.17-nightly.2802080286301 downloaded, installed, and relaunched cleanly — no SUSparkleErrorDomain 4005, no AppleSystemPolicy validation-category kill. Same machine, same Gatekeeper policy, same update path; the only changed variable was the Updater's SDK/runtime version (26.2.0 vs 15.5.0).

This confirms the root cause (SDK-mismatched Sparkle 2.8.1 prebuilt helper) and that bumping to 2.9.x resolves it on real affected hardware.

@lawrencecchen
lawrencecchen merged commit 9622193 into main Jun 23, 2026
36 checks passed
@lawrencecchen
lawrencecchen deleted the fix-sparkle-2.9.3-updater-sdk branch June 23, 2026 22:48
azooz2003-bit added a commit that referenced this pull request Jul 4, 2026
…#6678)

The both-diverged merge kept the refactor's stale Sparkle requirement
(minimumVersion 2.5.1) while Package.resolved already pinned 2.9.3 (matching
main's #6678 macOS-26 auto-update-kill fix). Since 2.9.3 satisfies 2.5.1 the
app still built, but the pbxproj remote-package requirement diverged from main
without a Package.resolved diff — check-package-resolved-policy flagged it.
Realign the requirement to main's 2.9.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview – cmux — 2ff9f93c Deployed Jun 23, 2026 by vercel[bot]
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.

Sparkle auto-update fails on macOS (non-sandboxed): SUSparkleErrorDomain(4005) / Timeout: agent connection was never initiated

1 participant