Skip to content

Fix tab moves while terminals reconnect after restart - #27243

Merged
cmux-bot[bot] merged 20 commits into
feat-cmux-nextfrom
issue-25999-tab-move-adoption
Nov 1, 2026
Merged

cmux-bot[bot] merged 20 commits into
feat-cmux-nextfrom
issue-25999-tab-move-adoption

Conversation

@austinywang

@austinywang austinywang commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Terminal tabs can be moved or reordered immediately after a daemon restart, while their terminal hosts are still being adopted. Both tab.move and the move-tab socket command used by dragging now require a committed placement rather than a runtime surface. Layout validation includes the tab's durable content identity before that surface exists.

Fixes #25999.

Verification

The regression covers same-pane reorder and cross-pane movement without a runtime surface, checks for invariant rejection, and compares durable layout with memory. A second regression exercises the move-tab wire command and retains rejection of unknown IDs.

The same focused fleet command failed before the fix at f3b9eb6f3d1a566ac2939208613ac258bca1244b (1 failed) and passed after the fix at 23ff5996d35c42bbcfdb1ba2f924357ae70cc569 (1 passed):

cmux-ci run --class isolated --script scripts/ci/cmux-tui-rust-check.sh \
  --ref SHA --arg test \
  --arg moves_of_a_tab_without_a_runtime_surface_follow_the_reducer \
  --key issue25999-proof-SHA --no-supersede --timeout 3600

Observed / Not run

Verified head: fde79e2fac12ca95e12e24844e3b4a254254cc5e, with base 3cf858d6e06c599c88b45182b81d014906cd5ea8 merged. GitHub reports it mergeable. All pushes were ordinary pushes, with no force or verification bypass.

  • 29 focused tests passed on rbx at this exact head, with Ghostty checked out at its committed pin. They include both regressions, layout properties and actual daemon restart/adoption recovery:

    rbx --lane issue-25999-tab-move-adoption -- \
      cargo nextest run --locked --workspace --exclude acpmux --no-fail-fast \
      -E 'test(layout_invariants::tests) | test(cmux_next_move_tab_moves_a_tab_without_a_runtime_surface) | test(adoption)'

    The unrelated acpmux package is excluded because its test-list harness requires Node on rbx.

  • The exact head passed the executed CI static checks, fleet Release compiler and app compile gateway, same-tree daemon tests, and fast gates. No current failing check remains. Skipped jobs are not counted as executed coverage.

  • Fresh independent correctness review of this exact head found no blockers. It covered both move entrypoints, durable staging/rollback, current adoption insertion, locking, reaping and undo. The reviewer performed source review, not independent runtime testing.

  • Tagged fleet build succeeded and is published: job 6f3d5455f597185cb87e5098, tag issue-25999-tab-move-adoption9, explicit local backend. Artifact SHA-256 34e0eab2e4ee6728534a4eada33863bb82d9313838975b73e161ed9f984a0425; workspace cleanup, Tag Opener health, tag registration and matching artifact manifest verified.

  • git diff --check and the scoped prepush gate passed. The CI static job above also executed on this head. No native build or heavy test ran on the person's Mac.

  • The regressions simulate pending adoption by removing the runtime surface; the recovery suite separately exercises actual daemon restarts. The tagged app was not launched: no GUI interaction, live GUI restart or shared Cloud backend verification is claimed. No UI strings or localization catalogs changed.

Try it

The rbx command above deterministically exercises the adoption window and real restart recovery. The tagged build issue-25999-tab-move-adoption9 is available for local daemon/layout dogfood; shared Cloud behavior is unverified. Use CMUX_TAG=issue-25999-tab-move-adoption9 scripts/cmux-debug-cli.sh for isolated automation. Immediately after a daemon restart, move or reorder a terminal tab: the move should commit while the terminal reconnects, without layout-conservation-violation.

Changelog

Fixed: Terminal tabs can be moved immediately after reconnecting to a restarted daemon.

No capture: daemon layout behavior with no native UI changes.


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


Summary by cubic

Fixes #25999: terminal tabs can now be moved or reordered immediately after a daemon restart, while their terminals are still being adopted.

Two causes made the live move disagree with the layout reducer: move_tab_in_state returned early for a tab without a runtime surface, and the layout projection built tab content only from runtime surfaces. The move path — both tab.move and the move-tab socket command the app's drag sends — now requires only a placement, and the projection describes unmaterialized tabs by their durable content identity with no runtime.

  • Adds regression tests covering same-pane reorder, cross-pane move, and the move-tab wire command for a tab without a runtime surface.
  • Adds release notes linking the fix to CLI instructions.

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

View guided diff Turn on auto-fix

austinywang and others added 4 commits October 27, 2026 20:18
After a daemon restart a placed tab can lack its runtime surface while
its terminal adopts (R41). tab.move of such a tab is rejected with
layout-conservation-violation. Regression test for
#25999.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
After a daemon restart a tab is placed in its pane before its terminal
adopts, so it has no runtime surface yet (R41; a host-lost tab is the
same). tab.move of such a tab was rejected with
layout-conservation-violation:

- move_tab_in_state returned early for a tab missing from
  state.surfaces, so the live move did nothing while the reducer moved
  the tab, and the placements disagreed.
- The layout projection built tab content only from runtime surfaces,
  so the reducer saw the pane list a tab without content and rejected
  a move into another pane.

move_tab_in_state now needs only a placement, and the projection
describes an unmaterialized tab by its durable content identity with no
runtime.

Fixes #25999

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang austinywang added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 5482f28: 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=pr27243 -f ref=issue-25999-tab-move-adoption -f platform=macos -f backend_mode=local

web and size checks: green

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator

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

@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Found 3 test failures on Blacksmith runners:

Failures

Test View Logs
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)/
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)
View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)/
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)
View Logs

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

@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at cad12a1

Fresh independent review against aec7054d44b06cc61e792d7c173eca5188e62b4b found no correctness blockers. The reviewer read the full seven-file patch and current wire validation, shared move mutation, durable plans, reducer staging/rollback, adoption completion and undo caller. Adoption and moves remain serialized and runtime insertion uses the current placement.

On this exact head I ran the focused layout, wire and real restart/adoption recovery suites on rbx: 26 passed. The pre-push gate, normal push hook and whitespace check passed. Tagged fleet build 857393d0f69136811a8f0a34 succeeded and is published as issue-25999-tab-move-adoption4; artifact digest 210a4f2bc45582ac2aac52fbba046c3497ddec4028132ac1f2b59b3dd83895c6, cleanup, opener health and tag registration are verified. The CI app-compile check now passes. No live GUI interaction is claimed.

The remaining failing tests are inherited: the signing-hook test on this head matches the base failure; the GPL crate-list failure matches base. The repository's per-test classifier returns own: false for both.

The head Rust panic ratchet and current base run have identical underlying findings: cmux-tui-core indexing 856/853, string slicing 57/52, and missing exception reasons in cmux-chats-mirror. No such finding is added by this patch. Their wrapper messages list different selected packages; the counts and actual source findings match.

@austinywang austinywang added ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds and removed ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds labels Oct 31, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at 426b668

Fresh independent review of the complete seven-file patch against e05d495 found no concrete correctness blockers. It covered shared and wire move paths, durable plans, reducer staging/rollback, adoption completion and runtime placement insertion, including the newly merged locking, settlement and reconnect code. Registry → connection → state serialization remains intact; settlement precedes projection and adoption materializes the current content placements.

The reviewer performed source review and git diff --check; no tests or live restart were run by the reviewer. Separately, the author executed 26 focused rbx tests on this exact head, all passing, plus the static prepush gate and normal push hook. The PR description records inherited CI failures and the current tagged-build limitation.

@austinywang austinywang added ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds and removed ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds labels Oct 31, 2026
@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at 693a7da

Fresh independent correctness review against db183fa found no concrete PR-caused blocker. The reviewer re-read the entire seven-file patch, current move/wire validation, layout projection, durable plans, rollback, adoption insertion, and relevant upstream template-key, PTY reclaim and server-origin changes. The key repair preserves durable identity; adoption and moves retain registry → pinned-state serialization, and adoption honors the current placements.

The reviewer performed source review and git diff --check; no tests/builds/live restart were run by the reviewer. Separately, the author executed the focused rbx suite on this exact head: 27 passed, including both regressions, layout property tests and actual daemon restart/adoption recovery. The static prepush gate and normal push hook passed. Current tagged fleet build and CI are in progress; the PR description discloses that scope.

@austinywang

Copy link
Copy Markdown
Contributor Author

CI attribution for 693a7da365e8c05eb4ca4552683dabd9e61fcab0 (merged base db183fa3bf5dc179b37d8f6675e131d53f19dcb9):

  • Static checks: head and exact base both report the default-cursor violation in unchanged LaneNoticeBatch.css.
  • Rust panic ratchet: head and current completed base run have identical blocking counts: CLI indexing 841/831, core unwrap 1042/1035, core indexing 857/853. The wrapper's selected-package list differs (cmux-remote, cmux-terminal-client, cmux-tui, cmux-tui-core versus acpmux, cmux-tui), which prevents the automated signature comparer from excusing this inherited failure. The actual findings are in unchanged files.
  • Windows: the head job fails in Unix-only cmux-automations. Independently reproduced on rbx at exact base db183fa3bf5dc179b37d8f6675e131d53f19dcb9 with rbx --lane issue-25999-tab-move-adoption-base -- cargo check --locked -p cmux-automations --target x86_64-pc-windows-gnu: the same 35 compile errors, exit 101. The PR changes none of that crate.

The exact PR head passed all 27 focused regression/layout/adoption tests on rbx. Tagged fleet build d8bea4f3dd58d7452d200bcc succeeded and was published as issue-25999-tab-move-adoption6; opener health, registration and artifact digest were verified. No GUI interaction was claimed. The exact-head independent SHIP receipt is posted above; ci-status is queued.

@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at 9254d56

Fresh independent correctness review against 3465552 found no concrete blocker. The reviewer re-read the full seven-file patch, current move/wire validation, durable plans, reducer staging/rollback and adoption materialization, including newly merged PTY-reclaim poison recovery and app event/subscription changes. Move/adoption serialization and insertion into current placements remain sound; unknown wire IDs remain rejected.

The reviewer performed source review and git diff --check, with no builds/tests/live restart. Separately, the author executed 27 focused rbx tests on this exact head: all passed, including both regressions, layout property tests and real daemon restart/adoption recovery. The scoped prepush gate and normal push hook passed. The tagged build is running, and the PR description records CI/build limitations.

@austinywang

Copy link
Copy Markdown
Contributor Author

Verification update for 9254d56be004fb822924a71298a60276dbf4dabe:

  • ci-status is green. cmux-next/fast-gates passed against base 9b6c218145c02320c5edb61a8b92cbb0911a2d66.
  • The exact head passed 27 focused regression/layout/adoption tests on rbx, the tagged build issue-25999-tab-move-adoption7, Debug app compile, and Release recipe v2 app plus bundled Rust compile. Fresh independent SHIP receipt is posted for this head.
  • The failed CI app-compile gateway obtained no verdict (controller timeout). After GitHub allowed retry, its second attempt was skipped by the workflow's gateway_attempt rule. That skipped job is not execution evidence; the actual fleet compiler runs above provide the evidence.
  • CI's separate cmux-next/compile publisher is still waiting on the Release result endpoint, which returns HTTP 404 for this SHA despite the passing Release v2 job. The problem is recorded in fleet journal entries f082a906ca92fb86a56968fd and 3c97f815d83996ca6e58614d; no CI status was manually overridden.
  • Remaining guard failures match base (test_reds.py returns own: false), and the Rust panic/Windows failures are in unchanged base code, as detailed in earlier evidence. The PR remains conflict-free with the reviewed head and refreshed ready-to-land label.

@cursor

cursor Bot commented Oct 31, 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.

@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at c30737e

Fresh independent review against 0e2fb2e found no concrete correctness or repository-rule blockers. The reviewer re-read the full seven-file patch and current shared/wire move, reducer projection/staging, durable plan/rollback and adoption materialization, including newly merged kept-tab/reaper changes. Move/adoption serialization and durable placement identity remain sound; the two regressions cover the mutation and wire precheck.

The reviewer performed read-only source review and git diff --check; no independent builds/tests/live restart were run. Separately, the author executed 27 focused rbx tests on this exact head: all passed, including both regressions, layout property tests and real restart/adoption recovery. The scoped prepush gate and normal push hook passed. The base merge was conflict-free, and the push was ordinary after verifying the remote head. Current-head CI and tagged build are pending; the broad local verifier reports localization and workspace-grouping failures in unchanged base files.

@austinywang

Copy link
Copy Markdown
Contributor Author

Review (review_final_adoption, independent correctness): SHIP at fde79e2

Fresh independent review against 3cf858d found no concrete correctness or repository-rule blockers. The reviewer re-read the complete seven-file patch and current wire/shared move, reducer projection, durable staging/rollback, adoption runtime insertion and undo paths. Newly merged startup adoption scheduling, durable unplaced-terminal reaping and locking preserve placement identity and move/adoption serialization.

The reviewer performed source review and git diff --check, without independent builds/tests/live restart. Separately, the author aligned the clean Ghostty checkout with this head's committed pin and executed 29 focused rbx tests: all passed, including both regressions, layout properties and real restart/adoption recovery. The exact head passed the executed CI static checks, app compile gateway, fleet Release compiler and same-tree daemon tests. Tagged build job 6f3d5455f597185cb87e5098 succeeded for issue-25999-tab-move-adoption9 with workspace cleanup confirmed; publication is in progress. No local native build or GUI interaction was performed.

This branch had an error being deployed

1 failed (outdated) and 3 inactive deployments
ci-routing-agent — fde79e2f Deployed Oct 31, 2026 by github-actions[bot] via cmux-next macOS placement #56104
artifacts — fde79e2f Deployed Oct 31, 2026 by cmux-bot[bot] via add the Windows daemon to the tree #91971
sentry-dsyms — fde79e2f Deployed Oct 31, 2026 by cmux-bot[bot] via upload cmux-tui dSYMs to Sentry #91971
ci-build-cache-reader — 9254d56b Deployed Oct 31, 2026 by austinywang via cmux-next Release compile (Xcode 26) #52999
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants