Skip to content

feat(wsl-mover): terminal gate, last-folder capture and exit proof for a WSL move (D1b-5b) - #28606

Merged
nwparker merged 5 commits into
mainfrom
nwparker/wsl-mover-d1b-5b-gate
Oct 14, 2026
Merged

nwparker merged 5 commits into
mainfrom
nwparker/wsl-mover-d1b-5b-gate

Conversation

@nwparker

@nwparker nwparker commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​298 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​298
Prod 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​242 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​242

ELI5

Before Orca moves a WSL project onto the WSL host, it has to pause the project's terminals and reopen them on the host. This PR adds the three checks that make that safe:

  • Which terminals can be paused without losing anything.
  • Which folder each one was in.
  • Proof that none of them is still running on this computer before the move commits.

Nothing calls these checks yet; the move flow wires them in later.

What Changed

This is step D1b-5b of the lossless WSL project mover. It is independent of D1b-5a (#28536). All three modules are pure and live in src/main/persistence/moving-wsl-projects/.

  • Terminal gate (wsl-move-terminal-gate.ts). Every pane in scope either passes or blocks the move. A blocked pane comes with the actions that would unblock it: wait, end, skip the project, or clear scrollback. Nothing is ended automatically. A pane blocks when:
    • An agent is busy or waiting on a person. That covers the working, waiting and blocked states, because some providers (Copilot, Pi, Freebuff) report an approval or question as blocked.
    • A non-agent process is in the foreground. An agent row vouches for the foreground process only when the caller confirms the agent owns it, so a stale agent row can't let a dev server through.
    • The agent has no session to resume.
    • The daemon can't answer for the pane. This includes a byte count that isn't a valid number.
    • Scrollback is over the transfer caps: 5 MiB per pane, 512 panes, or 256 MiB in total. The per-pane and total checks are reported together.
  • Restore hints (wsl-move-restore-hints.ts). Each paused pane's last folder is read from the daemon's checkpoint and converted to its Linux path. A pane's folder is kept nowhere else.
    • UNC folders in another distro and Windows folders are dropped, so a pane reopens at its workspace root rather than in the wrong place.
    • Checkpoints that can't be read are named for the move preview.
    • A checkpoint whose newer log couldn't be read is flagged as possibly stale.
  • Exit proof (wsl-move-exit-proof.ts). Before commit, this proves that no session of a moved workspace is alive on this computer's terminal daemon. It returns exited, live (with session ids) or unverifiable.
    • An incomplete census, meaning a daemon generation didn't answer or terminals are running in degraded fallback mode, is unverifiable, never exited.
    • Sessions are matched by the moved workspace keys, both git worktree and folder workspace. The two UNC spellings (\\wsl$ and \\wsl.localhost) and distro-name case are matched as the same workspace. Sessions are also matched by the exact ids the panes recorded, which covers older session ids.

Why

The owner decided that a move pauses and restores terminals rather than bridging live ones. That is only lossless if nothing that matters is running and every pane's folder survives the move. The terminal gate refuses anything it can't restore, and the exit proof makes sure no terminal still writes to the old location after the move.

Ending busy terminals automatically was rejected because it loses work silently. Truncating scrollback to fit the transfer was rejected for the same reason.

Linked Issue

N/A (maintainer; tracked in the WSL-via-orcad implementation tracker, step D1b-5).

Visual Proof

N/A: pure main-process logic with no UI and no callers yet.

Testing

  • I manually tested these changes locally
  • Automated tests added/updated, or explained why not below

85 unit tests in src/main/persistence/moving-wsl-projects/. They cover:

  • every gate state, including a stale agent row over a dev server;
  • invalid byte counts;
  • exact cap boundaries;
  • combined cap reporting;
  • the UNC and case forms;
  • folder workspace keys;
  • incomplete censuses;
  • fallback sessions;
  • stale and unreadable checkpoints.

Lint, oxfmt and pnpm tc:node are clean. An adversarial review found one HIGH (blocked doesn't mean failed), three MEDIUM and four LOW findings. All of them are fixed except one LOW: mapping a C:\ checkpoint folder to /mnt/c is left out, because a distro's automount root can differ. It fails safe: the pane opens at its workspace root.

AI Disclosure

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

The feature stays behind the internal WSL host gate, and nothing here is called yet. There is no SSH or wire change. The SSH mover keeps its own terminal rules.

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)

@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 1 minute.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5b15caef-4ff6-44fe-b5b8-abb89f605bcc
📥 Commits

Reviewing files that changed from the base of the PR and between 38d1801749bed17e7df48b1a6c1ac0420df92669 and 7e98ad7.

📒 Files selected for processing: 6
  • src/main/persistence/moving-wsl-projects/wsl-move-exit-proof.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-exit-proof.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-restore-hints.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-restore-hints.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-terminal-gate.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-terminal-gate.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2ca7d020-b366-498b-b97a-aa3d7ecd7426
📥 Commits

Reviewing files that changed from the base of the PR and between eb7f427 and 38d1801749bed17e7df48b1a6c1ac0420df92669.

📒 Files selected for processing: 6
  • src/main/persistence/moving-wsl-projects/wsl-move-exit-proof.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-exit-proof.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-restore-hints.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-restore-hints.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-terminal-gate.test.ts
  • src/main/persistence/moving-wsl-projects/wsl-move-terminal-gate.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

📝 Walkthrough

The change adds a terminal readiness gate for WSL moves, a function that captures eligible restore cwd hints, and a function that verifies whether moved terminals exited. Tests cover blocker conditions, scrollback limits, restore states and path formats, and exit-proof outcomes including census failures and fallback sessions.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 38d18

This change adds helper modules that the move flow does not yet call, so it has no user-visible effect today. No actionable merge-blocking risk was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main changes: the WSL mover terminal gate, restore-folder capture, and exit proof.
Description check Passed The description follows the repository template and explains the scope, behavior, rationale, testing, limitations, and checklist status. It also correctly marks visual proof as not applicable for pure…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ 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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nwparker
nwparker force-pushed the nwparker/wsl-mover-d1b-5b-gate branch from 38d1801 to 0090374 Compare October 14, 2026 06:14
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.

1 participant