You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(wsl-mover): no move of a distro may start while its move is being undone - #35369
Bringing a moved project back to this computer ("Use on this computer again") reconnects to the WSL host, and that wakes Orca's automatic mover. The mover could then start moving that same distro while the project was still on its way back. The undo would fail after it had already stopped the project's terminals on the host. Now no move of a distro can start while that distro's move is being undone.
What Changed
Before:
The undo connects to the WSL host. After a relaunch, or whenever the host wasn't connected, that makes the host ready.
The automatic mover runs for that distro (its "connect" trigger). Because the distro's move had finished, the mover may preview and start a new move straight away. Opening a project of the distro mid-undo, or the mover's re-check timer, does the same.
The undo then stops the host's copies of the project's terminals.
The undo finds a move running ("move running"), or a newer move committed (superseded), and refuses. The host's terminals stay stopped and the project stays moved.
After:
While a distro's move is being undone, no move or automatic preview of that distro can start. The mover gets "already running", which it treats as try-later, so the undo completes. Afterwards the mover parks the distro as declined, as before.
The undo also re-checks, right before it stops the host's terminals, whether it may still go ahead. If anything changed since its first check, it refuses with the host's terminals still running.
releaseWslMovesHere takes the mark first, before any guard or host connect, so the connect it triggers can't slip a run in.
claimWslMoveRun(distro), used by the driver and by the orchestrator's settling preview, returns null while that distro's undo runs. The user's read-only preview never claimed a run and is unchanged.
releaseOneMoveHere calls wslMoveReleaseRefusal once more after the host automations stop and before stopHostCopies; on a refusal it restores the automations.
Why
Why refuse the claim, not exempt previews. The orchestrator's preview claims the run while it settles an interrupted move. Left unblocked, that claim alone would make the undo refuse "move running" after the stop.
Why the mark comes before the guards. The undo's own connectUndoHost is what wakes the orchestrator. Taking the mark first means no run can claim after the undo's first check.
Alternatives considered:
Making the undo's guards ignore moves would let a newer move supersede it mid-flight.
Pausing the orchestrator globally would affect other distros.
Known gap (follow-up): a refusal that comes after stopHostCopies still leaves the host's terminals stopped. This PR makes the refusals this race caused impossible, and the late re-check catches anything else before the stop. What's left is a failure after the stop: a journal write error in releaseWslMove, or, in R38 Restore, an older move in the chain refused after a newer one stopped and released. Restarting the host's copies on that path needs a "start host copies" port that doesn't exist yet.
Flag-off: moves and undo exist only behind the WSL hosts gate (undo needs wslHostsServing(), the orchestrator needs the gate open). With ORCA_INTERNAL_WSL_HOSTS unset and no saved WSL work, no undo mark is ever taken, so claimWslMoveRun behaves exactly as before.
User-risk: low. While a project comes back (seconds), a move of that same distro started from the dialog is refused as already running and can be retried. Other distros are unaffected.
Linked Issue
Follow-up to #35357 (merged), raised in its review.
Visual Proof
N/A. No UI change; it is ordering between background operations, covered by tests.
Testing
I manually tested these changes locally
Automated tests added/updated, or explained why not below
New wsl-move-release-here-move-race.test.ts, using the real driver, journal, undo path and orcad profile store (the kill rig):
With an undo paused while it stops the host's terminals, the orchestrator's move and its settling preview of that distro are refused wsl_move_already_running, another distro still claims, and the undo releases. With the claim refusal removed, this fails.
A move already running when the undo starts makes the undo refuse move-running before the host's terminals are stopped.
wsl-move-release-here.test.ts: a newer move journaled while host automations stop makes the undo refuse superseded without stopping the host's terminals, and the automations are restored. This fails without the late re-check.
updater-wsl-move-install-hold.test.ts:
the undo mark blocks only its own distro's claims (case-insensitive) until it ends
the install-hold cases still pass
Checks run: pnpm tc, pnpm run typecheck:ci, 111 test files (1181 tests passing: every updater test, the mover IPC tests and every moving-wsl-projects test), pnpm run check:code-quality:changed, anti-slop oxlint, oxlint, ast-grep scan, the flaky-test filter and gates.
Review
Agent skill upstream boundary
Not applicable, or this change copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.
Notes
SSH: not involved; WSL host moves only.
Folder workspaces: undo of a moved folder workspace takes the same path.
Wire compatibility: no change.
Status
Ready for review. Two reviewers.
Checklist
This PR is small and focused
I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
Before/after screenshots or videos attached for UI changes, or N/A with reason
Self-reviewed for correctness, security, and performance
Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)
STATUS: ready. Head abe2f5f, stacked on #35357 (fb1e131) and #35345 (8a57edc); I'll rebase onto main once they merge. The undo mark is now keyed by distro and taken before any guard or host connect. claimWslMoveRun (driver and the orchestrator's settling preview) refuses that distro while it runs, and the undo re-checks its guards just before stopping the host's terminals. Known gap noted in the body: a refusal after the stop still leaves host terminals stopped. Checks: pnpm tc, typecheck:ci, 111 test files (1181 tests passing), code-quality, anti-slop, oxlint, ast-grep scan, flaky filter and gates. Reviewers: fix-reviewer, e9-reviewer.
Blocks moves and settling previews of a distro while its undo runs.
A WSL project undo blocks new move claims for its distro.
Undo checks the move record again before stopping host terminals.
nwparker explicitly deferred recovery from failures after stopHostCopies, including journal-write failures and partial chain restores, because a “start host copies” port does not exist yet.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Start undo] --> B[Mark distro as undoing]
B --> C[Check whether undo may proceed]
C --> D[Connect host and stop automations]
D --> E[Check again]
E -->|Refused| F[Restore automations]
E -->|Allowed| G[Stop host terminals and release move]
F --> H[End undo mark]
G --> H
B -. Same distro move claims are refused .-> H
The reason will be displayed to describe this comment to others. Learn more.
Update can interrupt an undo
wslMoveInstallHold() is checked only before the updater waits for quit cleanup. On Windows, that cleanup saves agent state and waits for pending writes. An undo request arriving during that wait can still enter releaseWslMovedProjectHere; its handler does not check whether an update is installing. The updater then calls quitAndInstall without checking the undo mark again, so it can close Orca while the undo is stopping the host's terminals, before the project has returned.
Block new undos once installation starts, or re-check the hold immediately before calling the native installer and abort cleanly.
STATUS: rebased onto the rebased #35357 (144ba18). Head 9e77093; the commit is identical to abe2f5f (range-diff '='). Approved by e9-reviewer; waiting on fix-reviewer. Not merged.
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.
Walkthrough
The changes coordinate WSL project moves with “Use on this computer again” undo operations. Undo runs block move claims for the same distro, and release checks for supersession before stopping host copies. The updater now holds installation during active moves or undos, records the corresponding lifecycle event, and reports a retryable status. Tests cover move and undo races, install retries, and localized hold messages.
Priority: Normal
Merge Risk: Minimal · up to 9e770
Updates are held for an already-running undo. An undo can still start during update preparation, a pre-existing limitation.
Pre-merge checks: 4 · 1
Failed checks: 1 warning
Check name
Status
Explanation
Resolution
Docstring Coverage
Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta…
Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed checks: 4 passed
Check name
Status
Explanation
Title check
The title clearly and concisely describes the main change: preventing a distro move from starting while that distro is being undone.
Linked Issues check
Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check
Check skipped because no linked issues were found for this pull request.
Description check
The description is complete and well aligned with the template. It explains the problem, user-visible behavior, implementation, rationale, testing, known gap, compatibility considerations, and visual-…
Full details: Description check
Explanation
The description is complete and well aligned with the template. It explains the problem, user-visible behavior, implementation, rationale, testing, known gap, compatibility considerations, and visual-proof status. The AI Disclosure section is omitted, but the template states that internal contributors should leave it empty. The linked issue is referenced as #35357 rather than using a Fixes keyword, but it identifies the relevant issue and follow-up context.
Full details: Docstring Coverage
Explanation
Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 7 functions across 8 files.
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
Finishing Touches: 💡 1
📝 Generate docstrings: 💡
Commit to this branch
Create a new PR
Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
The reason will be displayed to describe this comment to others. Learn more.
Major · Stability & Availability · Heavy lift
Supported by static analysis
Script executed:
#!/bin/bash# Inspect release entrypoints and install-state guards at the reviewed revision.
rg -n -C 5 'releaseWslMovedProjectHere\s*\(|releaseWslMoveChainHere\s*\(|quittingForUpdate|runBeforeUpdateQuitCleanup' src/main
Repository: stablyai/orca
Length of output: 30419
Script executed:
# Locate install-state guards, the hold definition, and preflight/quit call sites.
rg -n -F -e 'isQuittingForUpdate' -e 'wslMoveInstallHold' -e 'preflightMacInstall' -e 'quitAndInstall(' -e 'quittingForUpdate' src/main ||test"$?" -eq 1
# Read the release handler around the call site, including its guards.
sed -n '130,200p' src/main/ipc/wsl-move-handlers.ts
# Read the install execution flow from entry through the awaited cleanup.
sed -n '40,130p' src/main/updater/updater-install-execution.ts
Repository: stablyai/orca
Length of output: 21087
Re-check the WSL move hold after the install awaits.
performQuitAndInstall reads wslMoveInstallHold() once, at updater-install-execution.ts:62. It then awaits preflightMacInstall (line 86) and runBeforeUpdateQuitCleanup (line 102) before it calls the native quitAndInstall (line 143). An undo that starts during either await is not seen by the hold.
The release entrypoint does not check install state. registerWslMoveUseHereHandler in src/main/ipc/wsl-move-handlers.ts checks the gate, the sender, and the request shape. It then calls releaseWslMovedProjectHere without reading quittingForUpdate. If the update proceeds during an undo, the quit can interrupt the undo after it has stopped host terminals.
Make undo admission and install quit share one state until native invocation. Refuse new WSL release claims once quittingForUpdate is set. Keep the install refusal path valid until quitAndInstall runs. A second hold check placed just before the native call does not close the window, because an undo can still start after that check.
STATUS: rebased --onto main 2be70e5 (#35357 merged as 89a7c68). Head 8932eae; range-diff identical to abe2f5f; the diff stat shows only the 5 race-fix files. Approved by e9-reviewer and fix-reviewer. Checks: pnpm tc, typecheck:ci, code-quality, 9 test files (127 tests passing). Not merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ELI5
Bringing a moved project back to this computer ("Use on this computer again") reconnects to the WSL host, and that wakes Orca's automatic mover. The mover could then start moving that same distro while the project was still on its way back. The undo would fail after it had already stopped the project's terminals on the host. Now no move of a distro can start while that distro's move is being undone.
What Changed
Before:
After:
Mechanism (
wsl-move-running-moves.ts,wsl-move-release-here.ts):beginWslMoveUndoRun(distro).releaseWslMovesHeretakes the mark first, before any guard or host connect, so the connect it triggers can't slip a run in.claimWslMoveRun(distro), used by the driver and by the orchestrator's settling preview, returns null while that distro's undo runs. The user's read-only preview never claimed a run and is unchanged.releaseOneMoveHerecallswslMoveReleaseRefusalonce more after the host automations stop and beforestopHostCopies; on a refusal it restores the automations.Why
connectUndoHostis what wakes the orchestrator. Taking the mark first means no run can claim after the undo's first check.Known gap (follow-up): a refusal that comes after
stopHostCopiesstill leaves the host's terminals stopped. This PR makes the refusals this race caused impossible, and the late re-check catches anything else before the stop. What's left is a failure after the stop: a journal write error inreleaseWslMove, or, in R38 Restore, an older move in the chain refused after a newer one stopped and released. Restarting the host's copies on that path needs a "start host copies" port that doesn't exist yet.Flag-off: moves and undo exist only behind the WSL hosts gate (undo needs
wslHostsServing(), the orchestrator needs the gate open). WithORCA_INTERNAL_WSL_HOSTSunset and no saved WSL work, no undo mark is ever taken, soclaimWslMoveRunbehaves exactly as before.User-risk: low. While a project comes back (seconds), a move of that same distro started from the dialog is refused as already running and can be retried. Other distros are unaffected.
Linked Issue
Follow-up to #35357 (merged), raised in its review.
Visual Proof
N/A. No UI change; it is ordering between background operations, covered by tests.
Testing
I manually tested these changes locally
Automated tests added/updated, or explained why not below
New
wsl-move-release-here-move-race.test.ts, using the real driver, journal, undo path and orcad profile store (the kill rig):wsl_move_already_running, another distro still claims, and the undo releases. With the claim refusal removed, this fails.move-runningbefore the host's terminals are stopped.wsl-move-release-here.test.ts: a newer move journaled while host automations stop makes the undo refusesupersededwithout stopping the host's terminals, and the automations are restored. This fails without the late re-check.updater-wsl-move-install-hold.test.ts:Checks run:
pnpm tc,pnpm run typecheck:ci, 111 test files (1181 tests passing: every updater test, the mover IPC tests and everymoving-wsl-projectstest),pnpm run check:code-quality:changed, anti-slop oxlint, oxlint, ast-grep scan, the flaky-test filter and gates.Review
Agent skill upstream boundary
Notes
Status
Ready for review. Two reviewers.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)