Fix the six most common macOS hang patterns from Sentry

AU
2d ago
+2524-375

This PR fixes the six most common macOS app-hang patterns in Sentry over the last 14 days (0.65.x). Each pattern has its own issue, its own commits, and a regression test.

PatternIssueFix
P1 SwiftUI update storm (largest; about 27% of 0.65.2 devices)https://github.com/manaflow-ai/cmux/issues/22703The Bonsplit split root kept one withObservationTracking registration per SwiftUI update. After 25 updates, one change re-rendered the tree 26 times. It now keeps one live registration (https://github.com/manaflow-ai/bonsplit/pull/291, carried by https://github.com/manaflow-ai/bonsplit/pull/292).
P2 session checkpoint and autosave on mainhttps://github.com/manaflow-ai/cmux/issues/22704Per-candidate settings paths, UserDefaults reads, process-table lookups and file removal are hoisted or moved off the main thread.
P3 terminal portal re-attachhttps://github.com/manaflow-ai/cmux/issues/22705Re-attaching an unchanged surface skips geometry, background, blur, accessibility and active-space work.
P4 sidebar rowshttps://github.com/manaflow-ai/cmux/issues/22706The row height cache ignores chrome-only fields, NSTextView is used only for Markdown lines, heights are noted selectively, and WorkstreamItem lookups use a request-id index.
P5 welcome carouselhttps://github.com/manaflow-ai/cmux/issues/22708https://github.com/manaflow-ai/cmux/pull/25585 already landed the cached playhead on main. What remains here takes the pager's duration from the loaded asset instead of the player.
P6 small blocking calls on mainhttps://github.com/manaflow-ai/cmux/issues/22709Fixes in activation policy, hotkey keyboard layout, PaneMemoryGuardrail defaults, socket marker write, remote feature flags, and the browser history merge (was O(n²)). Skipped: 3WW9 (scrubber; moving capture off main is a policy decision, https://github.com/manaflow-ai/cmux/issues/12790) and 20CS (the time is AppKit's own icon redraw; no safe fix without measuring).

Related: https://github.com/manaflow-ai/cmux/issues/21260, https://github.com/manaflow-ai/cmux/pull/20250, https://github.com/manaflow-ai/cmux/issues/21352, https://github.com/manaflow-ai/cmux/issues/12790. This does not cover https://github.com/manaflow-ai/cmux/pull/21451, which landed separately and does not fix P1.

Merge order:

  1. https://github.com/manaflow-ai/bonsplit/pull/292, with a real merge commit, so 2803bcc stays reachable from Bonsplit main. It contains https://github.com/manaflow-ai/bonsplit/pull/291 and the pointer main pins today (58b73fd), which is not on Bonsplit main either.
  2. This PR, after checking that vendor/bonsplit (2803bcc) is reachable from Bonsplit main. If https://github.com/manaflow-ai/bonsplit/pull/292 is squashed, re-pin to the landed SHA first.

Complements https://github.com/manaflow-ai/cmux/pull/22748, which also targets https://github.com/manaflow-ai/cmux/issues/22703. That PR stops the idle agent-index reload bursts that re-render every pane. This PR's Bonsplit change stops each of those renders from multiplying through leaked observation registrations. No files overlap.

Testing

Current head 5025858, P1 against today's code:

  • Red: Bonsplit run 41941235173 at 35f9009, which is cmux main's pointer 58b73fd plus only the test. SplitTreeObservationTests failed: 26 and 53 tree renders where 1 and 2 are expected.
  • Green: Bonsplit run 40420806256 at 2803bcc, the pointer on this PR. SplitTreeObservationTests passed.
  • Fleet build job 28d32972c71b59dec9a5a246 at 5025858 (tag 22703-swiftui-graph-update-hang): built and installed, and the app's CMUXCommit is 5025858db.
  • PR CI run 41974550264 at 5025858: compile admission, swift-package-tests and all CLI regression shards passed, and so did five of the seven app-host shards. Shards 1/7 and 6/7 are red only on suites main also fails: Cloud Machines header count (fix: https://github.com/manaflow-ai/cmux/pull/35974) and RemoteTmuxMirrorCloseDetachTests. Both are in main run 41915901489, and this PR changes neither.
  • Focused run 41952355399 at 33902b3, one test-only change set before this head: 54 tests in 3 suites passed, covering WorkspaceContentViewVisibilityTests, WorkspaceProcessWideObserverRetirementTests and CloudWelcomeTests.

The receipts below are from older heads, kept as history.

P1, Bonsplit CI, SplitTreeObservationTests:

P2 review fixes, cmuxTests/SessionScrollbackCheckpointCoordinatorTests (15 tests):

P2–P6 focused suites at 3d0a81e, on owned Macs:

Observed / Not run

  • Observed:
    • Bonsplit red and green runs.
    • P2 red and green runs.
    • P2–P6 focused app-host suites, all green on the head commits above.
    • cmux-ci package steps.
    • Fleet build of 3d0a81e (compiled, signed, packaged).
    • Correctness reviews (comments below).
    • Base-red checks on main for AgentLaunchEnvironmentPolicy and SettingsRowAnchorResolution (comment below).
  • Not run:
    • P2-P6 focused suites were not rerun individually on 5025858; PR CI on the head covers them.
    • Field proof: no release contains this fix, so Sentry can't show its effect yet.
    • Live-app dogfood of the render storm; the regression test hosts real SwiftUI in a window instead.
    • Per-pattern red runs for P3-P6; those regression tests were committed alongside each fix.
    • P5 changes a carousel's timing source; no visual change is intended.

No visible UI change is intended.

Changelog

Fixed: fewer app hangs from split-view re-render storms, session checkpoints, terminal re-attach, sidebar rows, the Cloud welcome carousel and blocking main-thread calls.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of session restoration, scrollback checkpoints, agent status tracking, and terminal visibility.
    • Preserved existing sidebar row heights during presentation-only updates, while still resizing rows when their content changes.
    • Prevented unnecessary rewrites of unchanged socket markers and redundant preference updates.
    • Improved browser history merging and shortcut key resolution.
  • Performance

    • Reduced unnecessary work when updating terminal surfaces, sidebar content, and session snapshots.
    • Made request identity lookups and agent liveness checks more efficient.