Skip to content

Keep workspace customization scoped to workspace identity - #9270

Merged
austinywang merged 4 commits into
mainfrom
issue-9267-workspace-directory-sticky-title
Jul 31, 2026
Merged

austinywang merged 4 commits into
mainfrom
issue-9267-workspace-directory-sticky-title

Conversation

@austinywang

@austinywang austinywang commented Jul 31, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replace authoritative directory-keyed workspace customization with a recovery journal keyed by Workspace.stableId.
  • Keep each session snapshot as the per-workspace baseline while preserving title and color mutations made before the next autosave, including explicit clears.
  • Treat workspaceDirectoryCustomizations.v1 as migration-only. Promote a legacy directory record only when exactly one restored workspace owns that directory, then remove ambiguous and orphaned legacy data.
  • Cover both full-session restore and closed-workspace history restore with same-directory title and color behavior tests.

Regression provenance

Version 0.64.20 predates this regression. #8841 introduced the directory-keyed record in commit f5af960e01 and made it authoritative on restore in commit 25a1ed8ba4. #9027 later stopped applying the record to fresh workspaces but retained the colliding write and restore paths.

Verification

  • Commit 69087f964e adds the failing same-directory restore regressions first.
  • Commit 9f586e4574 adds the stable-ID implementation and migration coverage separately.
  • The tagged cloud Debug build passed and launched from merged HEAD d47c1fe0c0.
  • ./scripts/lint-pbxproj-test-wiring.sh
  • ./scripts/check-pbxproj.sh
  • python3 scripts/check-workspace-package-groups.py --check
  • python3 scripts/check-package-resolved-policy.py
  • git diff --check
  • No local xcodebuild tests or XCUITests were run. CI is the test execution gate.
  • Current origin/main does not contain .github/swift-file-length-budget.tsv or scripts/swift_file_length_budget.py. Every new Swift file is under 500 lines, and neither budget TSV is changed.

Closes #9267

@coderabbitai

coderabbitai Bot commented Jul 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@austinywang, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 1 minute

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 72941348-0f9b-40c1-bafb-efdd535d8618

📥 Commits

Reviewing files that changed from the base of the PR and between e06745b and 32f17a0.

📒 Files selected for processing (18)
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Coordinators/WorkspaceGroupCoordinator.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Coordinators/WorkspaceGroupHosting.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceCustomization.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceCustomizationPersistence.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceCustomizationStore.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomization.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationPersistenceEntry.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationPersistenceSnapshot.swift
  • Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationStore.swift
  • Packages/macOS/CmuxWorkspaces/Tests/CmuxWorkspacesTests/Customization/WorkspaceCustomizationStoreTests.swift
  • Sources/AppDelegate.swift
  • Sources/TabManager+DetachedWorkspace.swift
  • Sources/TabManager+WorkspaceCustomizationPersistence.swift
  • Sources/TabManager.swift
  • Sources/cmuxApp.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift
  • cmuxTests/WorkspaceRecoveryTests.swift
📝 Walkthrough

Walkthrough

The PR adds regression tests for session and closed-workspace restoration. The tests verify that workspaces sharing a directory retain distinct custom titles and colors.

Changes

Workspace recovery customization

Layer / File(s) Summary
Same-directory workspace snapshots
cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift
The distinctWorkspaceSnapshots helper creates two workspaces for one directory and assigns distinct titles and colors.
Restoration assertions
cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift
Session and closed-workspace restoration tests verify that each workspace retains its own title and color.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • manaflow-ai/cmux-dev-artifacts#7073 — Tracks the regression test for preserving distinct titles during same-directory session restoration.
  • manaflow-ai/cmux-dev-artifacts#7072 — Covers the same-directory workspace recovery behavior for distinct titles and colors.

Possibly related PRs

  • manaflow-ai/cmux#9260 — Fixes the same-directory workspace title and color restoration behavior tested by this PR.
  • manaflow-ai/cmux#9031 — Changes the session and closed-workspace restoration logic covered by these tests.
  • manaflow-ai/cmux#8695 — Implements workspace restoration identity behavior validated by these regression tests.
🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The tests cover same-directory restore regressions, but the summarized changes do not implement stable-ID persistence or legacy migration. Add the implementation that keys recovery by workspace stable identity, preserves independent title and color clears, and migrates legacy data only for unambiguous mappings.
✅ Passed checks (24 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The added helper and regression tests directly target same-directory workspace restoration and customization isolation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Cmux Swift Actor Isolation ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; its @MainActor test suite is explicitly allowed, and no production actor-isolation declarations were added.
Cmux Swift Blocking Runtime ✅ Passed The commit changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; added test scaffolding uses no semaphores, waits, sleeps, delayed dispatch, polling, main-queue sync, or manual locks.
Cmux Browser Automation Off-Main ✅ Passed The PR changes only workspace recovery tests; no browser.* socket commands or rule-scoped browser automation files changed, so no off-main routing violation is introduced.
Cmux Expensive Synchronous Load ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; it adds no production loader, agent-history I/O, or synchronous parsing call.
Cmux Cache Substitution Correctness ✅ Passed The commit changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift and adds regression tests; it makes no production Swift, TypeScript, or JavaScript cache substitution.
Cmux No Hacky Sleeps ✅ Passed The diff changes only a Swift test file; it adds no non-Swift runtime code or fixed sleep/timer delay.
Cmux Algorithmic Complexity ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; it adds regression-test setup and tiny two-workspace scans, which the rule explicitly exempts.
Cmux Swift Concurrency ✅ Passed The 87 added lines are synchronous test setup and assertions; they add no Dispatch, Task, Combine, completion-handler, or fire-and-forget patterns. Existing async test code is unchanged.
Cmux Swift @Concurrent ✅ Passed The diff adds only synchronous throws tests and a synchronous helper under @MainActor; it adds no async, @concurrent, or nonisolated code.
Cmux Swift Package Boundaries ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift and adds regression tests/helper; the boundary rule explicitly allows test code.
Cmux Swiftpm Lockfiles ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; it changes no Package.swift, Package.resolved, .gitignore, workflow, or Xcode package references.
Cmux Swift Logging ✅ Passed The commit changes only a Swift test file; added tests and fixtures contain no print, debugPrint, dump, NSLog, Logger, or file/stdout logging.
Cmux User-Facing Error Privacy ✅ Passed The diff only adds Swift regression tests and a test helper; it adds no production user-facing errors, alerts, command output, API bodies, or recovery copy.
Cmux Full Internationalization ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; its test fixture strings are explicitly exempt by the internationalization rule.
Cmux Swiftui State Layout ✅ Passed The diff only adds AppKit-based regression tests and a helper; it introduces no SwiftUI views, ObservableObject/@published state, GeometryReader, lazy rows, or render-time state mutation.
Cmux Architecture Rethink ✅ Passed The commit adds only 87 lines of regression tests; it introduces no timing, blocking, observer, cache, side-channel, or lifecycle-owner changes.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The diff only adds workspace recovery tests and a helper; it introduces no standalone user-visible window. The existing makeMainWindow fixture is test-only and explicitly allowed.
Cmux Source Artifacts ✅ Passed The only changed path is the tracked Swift test source cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; its additions are regression tests and a test fixture helper, not artifacts.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The pull request changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift; no production Swift file under a Sources path is modified.
Cmux No Ambient Global State ✅ Passed The diff changes only cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift. Added helpers are private instance methods, with no new production global state, static namespace, or singleton.
Title check ✅ Passed The title clearly describes the main change: scoping workspace customization to each workspace identity.
Description check ✅ Passed The description explains the change, rationale, migration behavior, regression coverage, and verification steps in sufficient detail.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-9267-workspace-directory-sticky-title

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.

@austinywang
austinywang marked this pull request as ready for review July 31, 2026 06:05
@cursor

cursor Bot commented Jul 31, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@austinywang
austinywang force-pushed the issue-9267-workspace-directory-sticky-title branch from 98b763e to e06745b Compare July 31, 2026 06:06
@austinywang
austinywang force-pushed the issue-9267-workspace-directory-sticky-title branch from e06745b to 69087f9 Compare July 31, 2026 06:25
…directory-sticky-title

# Conflicts:
#	Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomization.swift
#	Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationPersistenceEntry.swift
#	Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationPersistenceSnapshot.swift
#	Packages/macOS/CmuxWorkspaces/Sources/CmuxWorkspaces/Customization/WorkspaceDirectoryCustomizationStore.swift
#	Sources/AppDelegate.swift
#	Sources/TabManager+DetachedWorkspace.swift
#	Sources/TabManager.swift
#	Sources/cmuxApp.swift
#	cmux.xcodeproj/project.pbxproj
#	cmuxTests/WorkspaceRecoveryReviewRegressionTests.swift
#	cmuxTests/WorkspaceRecoveryTests.swift
@austinywang
austinywang merged commit 9e3e324 into main Jul 31, 2026
6 checks passed
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.

Renaming one workspace renames every workspace in the same folder after session restore (directory-keyed sticky title clobbers per-workspace title)

1 participant