fix(cloud): keep renamed workspace projections in lockstep
What changed
Cloud workspace names now have one authoritative propagation path. SurfaceCatalog owns the
cloud workspace identity/name graph and fans a rename out to machine metadata, every nested
resource view, restored projections, the Cloud tree, and local right-sidebar workspaces.
The provider submits renames with a generation/revision compare-and-swap fence and serializes
requests per stable (machine id, workspace id). Accepted snapshots/deltas are reconciled as
complete graphs; older generations, regressive revisions, malformed snapshots, and equal-cursor
payload mismatches are rejected. Cursorless provider metadata cannot restore an older name, and a
stale equal-cursor read after a mutation receipt is rejected.
Cloud and local projected workspaces persist the exact cmux-tui workspace id through session
restore. Local workspace title edits, the Cloud sidebar Rename action, socket
vm.workspace_rename, and cmux vm workspace rename all call the same provider/catalog path.
Duplicate names remain addressable by stable ids; ambiguous or detached placements fail closed.
Related context: https://github.com/manaflow-ai/cmux/issues/11762
Regression coverage
Behavior-level coverage includes:
- immediate fan-out to machine metadata, resource views, and the right-sidebar projection;
- stale generations, regressive/equal cursors, reconnects, and uncertain failures;
- queued rename ordering and rollback fencing;
- duplicate-name/id resolution, malformed graph handling, stable binding persistence;
- cursorless metadata writes and stale equal-cursor payloads after a rename receipt;
- cmux-tui argument/parser behavior and the existing workspace/tree projection suites.
The regression history is intentionally split into test-only commits followed by fixes so CI can
prove the tests catch the race.
Verification
swiftc -parseon every changed Swift file: passed../scripts/lint-pbxproj-test-wiring.sh: passed (764 test files).python3 scripts/check-workspace-package-groups.py --check: passed.python3 scripts/check-package-resolved-policy.py: passed../scripts/check-pbxproj.shandgit diff --check: passed.- Focused fleet test run on a GUI-capable Mac (cmux-unit, 45 tests in
CloudWorkspaceRenameReconciliationTestsandSurfaceCatalogTests): 45 passed, 0 failed.
Command used the remotecmuxaccount with the app-host wrapper because the generic xctest
helper currently selectscmuxvnc*accounts that are not authorized in this inventory. - A broader four-suite fleet run reached 117 tests; the three rename/catalog/provider suites
passed. The upstreamWorkspaceGroupTests.staleGroupReferenceInsideGroupRunRendersAsRootRow
assertion from origin/main failed independently of this change. - Tagged merged-HEAD build/launch:
CMUX_SKIP_ZIG_BUILD=1 CMUX_DEV_BACKEND_MODE=local CMUX_DEV_WEB_PORT_OVERRIDE=4515 /Users/austinwang/manaflow/cmuxterm-hq/scripts/reload-cloud.sh --tag issue-11762-cloud-rename-sidebar --launch(fleet build succeeded).
Live verification
OrbStack is running and the isolated local web server is persistent in tmux session
cmux-web-issue-11762:
orb status→Running; Docker context →orbstack.http://localhost:4515/→ HTTP 200;/api/vm→ HTTP 401 without auth (expected).- Authenticate the tagged build, create two workspaces in one Freestyle machine, rename one
from the Cloud workspace row, and confirm the renamed label in both the Cloud Workspaces group
and the right-sidebar local projection. - Refresh/reconnect/reopen the machine/workspace and verify the renamed workspace remains changed
and the second workspace is unchanged; repeat withcmux vm tree --jsonand
cmux vm workspace renamefor CLI parity.
The live two-workspace UI run is blocked in this environment: the local 4515 database has a
machine row, but Freestyle already owns the deterministic tunnel slug for this Mac in the
separate all-agents backend (port 9170). The safe API response is HTTP 502 conflict; I did not
revoke or overwrite the active tunnel. The existing production tunnel is also for a different
VPC. Exact retry path: point the tagged app/backend at the account backend that owns the tunnel,
or have an operator reconcile the local dev tunnel record, then run the four steps above.
Trade-offs / limitations
- The fan-out remains model-owned in
SurfaceCatalog; no view keeps an optimistic duplicate. - A legacy cursorless daemon remains readable but cannot be safely renamed until a versioned
snapshot is observed. - When a concurrent writer wins a CAS race, the request reports a user-safe conflict and keeps
the newer canonical name rather than guessing or retrying over it. - No local
xcodebuild testor XCUITest was run, per repository policy; tests used the shared Mac
fleet. The repository'sscripts/swift_file_length_budget.pyand
.github/swift-file-length-budget.tsvare absent on this branch, so that requested check could
not be executed; no budget files were modified. - No production tunnel or cloud VM was deleted or overwritten while diagnosing the local server.
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.
Summary by cubic
Cloud workspace renames previously left machine metadata, resource views, the Cloud tree, and right-sidebar projections out of sync. Renames now route through SurfaceCatalog with a generation/revision compare-and-swap fence, serialized per (machine id, workspace id), so every projection stays in lockstep.
Stale generations, regressive revisions, malformed snapshots, and equal-cursor payload mismatches are rejected. All rename paths (local title edit, Cloud sidebar Rename, vm.workspace_rename socket, cmux vm workspace rename CLI) share the same provider/catalog path, and the stable cmux-tui workspace id persists through session restore. Addresses issue #11762.
Migration
workspace.cloud_vm_bindnow accepts an optionalremote_workspace_idso renames stay addressable after restore.- Legacy cursorless daemons remain readable but cannot be renamed until a versioned snapshot is observed.
- When a concurrent writer wins a CAS race, the request fails with a user-safe conflict and keeps the newer canonical name.
Summary by CodeRabbit
- Tests
- Added coverage for cloud workspace rename synchronization across related views and metadata.
- Verified that confirmed names are protected from stale, delayed, or cursorless updates.
- Added checks ensuring newer rename changes remain intact when older updates are rolled back.