Skip to content

Land the WSL project mover dark (merges only after verify-15b, the flag-off audit and green CI) - #34059

Merged
nwparker merged 188 commits into
mainfrom
nwparker/wsl-mover-land-2
Oct 28, 2026
Merged

nwparker merged 188 commits into
mainfrom
nwparker/wsl-mover-land-2

Conversation

@nwparker

@nwparker nwparker commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 138 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​20106 $\color{#cf222e}{\Huge{\mathbf{−}}}$​89 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​20017
Prod 266 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​15416 $\color{#cf222e}{\Huge{\mathbf{−}}}$​487 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​14929

ELI5

This lands the WSL project mover on main dark. It's the feature that moves a local project, with its terminals, history, chats, browser logins and drafts, into the desktop's WSL host and can bring it back ("Use on this computer again"). Every code path stays inert unless ORCA_INTERNAL_WSL_HOSTS=1, the same way Track C and D0 landed. Shipped builds see no change.

Merges dark only after verify-15b, the independent flag-off audit and green CI.

What Changed

This is the mover's review base plus its restore stack (#32956 → #32965 → #32969 → #33040) and the move orchestrator (D3a, #33802, with its fix #34087), merged with current main. Every theme below was already reviewed as the PRs listed beside it.

Total: about 14.7k product lines and 19.3k test lines across 402 files.

Theme Prod lines / files Test lines / files Reviewed as
Export, manifest, migration source scope 0.8k / 31 0.5k / 9 #31414, #29825
Terminal history (host reads, moved-pane seed, daemon) 0.7k / 13 0.6k / 6 #29526, #32956
Main move driver, desktop rewrite, fences, undo, startup, IPC 6.5k / 92 8.9k / 61 #29652, #31957, #31401, #31417, #31952, #29833, #32343–#32923, #32965, #33040
Renderer store rewrite and hydration 1.3k / 31 1.2k / 9 #29827
Browser logins, tabs, drafts 0.7k / 9 1.1k / 5 #31400, #32668
Orchestration history 0.2k / 2 0.3k / 1 #31232
Move dialog and UX, i18n, e2e 2.4k / 34 3.1k / 18 #31429, #32403, #32969
Telemetry and agent hooks 0.3k / 7 0.4k / 5 #32000, #32001
Move orchestrator (D3a), dark 1.9k / 24 2.2k / 13 #33802, #34087

Commits on top of the reviewed stack:

  • Main merges. Each conflict and how it was resolved:
    • e1f3c79 (main a66f6bf):
      • runtime-environment-connectivity-handlers.ts: kept both. The undo spawn fence runs ahead of main's new chat-creation recording, so refused starts aren't recorded.
      • orcad-migration-blob-transfer.test.ts: took main's deletion of the inventory test (test: remove low-value wrapper and inventory suites #33736). A narrower pin is re-added below.
      • ipc/session.ts: imports only; kept both.
      • restored-pane-materialize.ts: imports only; kept both.
    • c8e54d1 (main 44d2fcb era):
      • renderer-shutdown-checkpoint.ts: kept main's error = formatShutdownCheckpointFailureReason(...), and updateUI stays wrapped in !isWslMoveWindowWriteHeld().
      • session-tabs-runtime-capabilities.ts: kept both new entries. The scrollback-read entry was later moved out of the static list; see the wire section.
      • Lint fix in the merge: workspace-session-host-hydration.ts is kept exactly as main has it, because adding to it pushed it over the line limit. The moved-rows filter moved to startup's session read (wslMovedSessionReadApi), with its test updated.
    • ed7e30a (D3a, nwparker/wsl-mover-restore-undo-live at 8a54590):
      • wsl-move-handlers.ts: took D3a's deletion of the inline undo; it moved into wsl-move-release-here.ts. That file keeps the gate check first, refuses before any host stop (X1), and keeps the spawn fence until the reload.
    • a18c4eb (nwparker/wsl-mover-restore-undo-live at 2a90632, fix(wsl-mover): D3a waits out a move still being retained; orchestrator-over-driver tests #34087): no conflicts.
    • 0f01f99, c0f0253 (main a96171d, 9bfabff):
      • wsl-move-storage-dispositions.ts: kept the stack's layout and added main's removed_orchestration_work and removed_orchestration_work_coverage to the receipts list.
      • wsl-host-service.test.ts: imports only; kept both.
      • wsl-host-service.ts: imports only; kept both. D3a's Remove note pushed the file one line over the limit, so the Remove teardown (stop the server, disconnect, release the holder) moved unchanged into wsl-host-remove-teardown.ts.
  • Pre-landing cleanup (c2a9649):
  • Gate-audit fixes (aaa76ce):
    • The moved-pane history wire surface is gated (below).
    • Restoring a pane probes for a moved pane's history only on a WSL host.
    • The journal's orphaned-write sweep runs on the WSL move journal only, so SSH migration journals behave as on main.
  • Review fixes after D3a (ff70fd2, 3fb409e):
    • The dialog's preview and start connect their host the way a user action does (service.connect, which may boot the distro and lifts a park). Neither reconnects a host that is already ready (the orchestrator readies it before the driver runs). The orchestrator and its startup recovery keep the no-boot path. A host whose Remove is still pending is never connected.
    • The dialog host's active-distro selector does no lookup with the flag off.
    • The host scrollback hold returns null before the environment list loads.
  • Wake fix (9439d17): now on main as fix(terminal): save a woken terminal's first history as a full snapshot #34060; the merge below keeps main's version, so it is not a change here.
  • ConPTY reflow taken out (1c51c85 reverts ecd8f07): it is ungated terminal code for every Windows user, so it lands on main separately as fix(terminal): keep ConPTY's viewport top through a width change #34061 and does not ride on this PR.
  • 2c38e14: main merge (ad2156c), no conflicts.
  • RPC params catalog fix (5737e0f): gating session.readTerminalScrollback out of the method manifest had dropped it from the generated params catalog (verify:rpc-params-catalog failed). The method is static in the manifest again, so the catalog types it; the dispatcher leaves it unregistered on any host that does not serve moved panes' history.
  • c0e045e, b6b1a76: main merges (037cf27 with fix(runtime): a restored host pane resumes its agent from the hook store, never replays the launch #34054, fix(terminal): save a woken terminal's first history as a full snapshot #34060, fix(wsl-host): a clean watch or holder exit also opens the settle window (E9 follow-up) #34063, fix(wsl-host): no-boot connects stay quiet, and liveness recovery never boots (E9 follow-up) #34093; then b8c596e):
  • df54a74: main merge (fix(terminal): a WSL bridge pane whose distro went away keeps its tab and cold-restores #34095), no conflicts.
  • 93d5ad9: main merge (fix(ssh): move enabled SSH automations to the host's Orca server #34044 and later):
    • orcad-source-automation-state.ts: main now moves enabled SSH automations (always sent disabled, re-enabled after commit) and lists the ones blocked by a running run; this PR records which WSL-moved automations were enabled. Kept both. The WSL list now reads the source row's enabled, since main's projection always sends it disabled (the manifest-export test pins it).
    • orcad-source-dormant-state.ts: kept main's runningAutomationItems and this PR's automationsEnabledAtSource.
    • wsl-host-service.test.ts: kept main's new imports and tests; the two Remove-as-user-action tests moved unchanged to wsl-host-service-user-actions.test.ts to stay under the line limit.
    • Brings fix(ssh): move enabled SSH automations to the host's Orca server #34044's fix to ssh-orcad-legacy-relay-bridge.spec.ts, whose Move anyway lookup also matched fix(ssh): make Move anyway the next step when saved items refuse a host's move #34041's refusal toast.
  • bcf7da8: main merge (test: extract WSL host connector fixture to restore lint #34132, test only). Main moved the WSL host connector fixture into wsl-host-service-test-connector.ts, byte-identical to this PR's wsl-host-service.test-support.ts; took main's file and pointed this PR's tests at it.
  • 4245537: test(wsl-mover): orchestrator automatic path never reconnects a serving host (E9) #34110 (test only): the orchestrator's automatic path over a real WslHostService never reconnects a serving host and adds a bridge host once. Its fixture import points at main's file.
  • 46a8f9e: main merge (90c713a). Conflicts, each keeping both sides: the WSL orcad e2e workflow (both lanes' paths and steps); browser-cookie-clear-store.ts (main's shared debugger session, plus this PR's cookie-jar read on it); confirmation-dialog.test.tsx and en.json (both additions); repo-header-project-actions.tsx (main's moved import plus the move menu item); fetch-all-worktrees.ts (main moved the hydration purge into hydrated-worktree-purge.ts; this PR's keep-a-moved-project's-chats rule moved with it).
  • 4ab3df7 (verify-15c): undo's host-copy stop took the host workspaces from this computer's session, which after a move keeps only a moved project's chats; a project with none named no workspace, so undo asked the host nothing, released it with the host's orcad stopped, and left its host shell running. The stop now always lists the host's terminals first, stops every workspace of the move that runs one, and refuses as host-unreachable when the host does not answer.
  • Undo fixes from verify-15b:
    • 723af2d (6c): undo points the window's focus back from a released project's host copy, so the reload does not reopen that copy and, since fix(runtime): a restored host pane resumes its agent from the hook store, never replays the launch #34054, resume its agent beside the one restored here.
    • 8d3fea2 → 206d58c: undo's automation step. Per move, before its terminals stop: every one of the move's automations is read on the host, those states (the user's latest choice) are recorded on the move, and each host copy that is on is turned off; as part of the release, the copy here takes the recorded state, so each automation runs in exactly one place. Any later refusal turns back on exactly what this attempt turned off and changes nothing here; what it cannot turn back on is recorded, shown in the unfinished-move notice and retried, and keeps its recorded choice for a later undo. Undo's per-move steps and that retry take turns. An unreachable host refuses as host-unreachable, a refusal as failed, and a host whose Remove is pending is left alone with its own message; the spawn fence is released on every refusal or throw.

Why

One PR instead of a themed chain, for two reasons:

Flag-off safety (read-only audit of every modified shared file)

  • Startup: the startup rewrite, retention pass and rewrite retry each check wslHostsGateOpen(). What runs ungated only registers stores and a journal listener.
  • Session persistence and hydration:
    • Main's session saves change only while a move holds the window's writes, which only a gated move does.
    • Renderer hydration passes data through unchanged when no project has been moved. One extra repos:listWslMoved IPC call is added at startup.
  • Layout writer: journal-driven and gated. The layout-writer ratchet passes.
  • Git and repo catalog: orcadRetained is only validated, and only the mover writes it. The catalog actions pass data through unchanged.
  • PTY spawn: the cwd and undo fences are empty unless a move journal or an undo exists.
  • Move orchestrator (D3a): nothing is constructed while the gate is closed; its IPC answers empty and the renderer's listeners are not subscribed.
  • SSH and orcad migration: the local-wsl branches are unreachable for SSH, and the ambiguity rule is gated to local-wsl.

Wire surface

  • Gated to a WSL move's destination: session.readTerminalScrollback (defined in the manifest and params catalog, registered by the dispatcher only there), session.terminal-scrollback-read.v1 (advertised), orcad.migration-blob.terminal-history.v1 (advertised) and the terminal-history installer.
    • They are on only on the WSL host's orcad (isWslHostOrcadProcess) or an e2e host standing in for one (ORCA_E2E_WSL_MOVE_DESTINATION=1). Every other host answers method-not-found and advertises neither capability.
    • The sender already checks the destination's advertised blob kinds before sending, so a move still carries terminal history to a WSL host. Older peers never call or send either.
  • Left ungated, both additive: the optional durableCommitted field on abort-by-reference, and its extra flush before a committed answer.
  • Tests: orcad-migration-blob-transfer.test.ts pins the advertised blob kinds for both a WSL host and any other host. session-terminal-scrollback.test.ts dispatches the method end to end: registered, params-validated and served on a move destination; method-not-found elsewhere.

Known limits

  • Automations created on the host after a move stay on the host when the move is undone; only the move's own automations come back.
  • A downgraded build drops the undo's recorded automation choice and left-off list from the move's record (lenient optional fields), so a pending retry of a refused undo's automations would not run there.
  • Dogfood profile run by a release build: a profile that committed a move under ORCA_INTERNAL_WSL_HOSTS=1 and is then opened by a release build shows the moved-projects section, and "Use on this computer again" refuses. This affects internal testers only; release users can't make a move.
  • Telemetry and agent hooks: telemetry is emitted only by the gated driver. The hook changes apply only inside a WSL host process.

Linked Issue

N/A (maintainer).

Visual Proof

N/A: dark behind ORCA_INTERNAL_WSL_HOSTS. Real-host evidence comes from verify-15b on awin, run against this head.

Testing

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

  • New tests on top of the reviewed stack:

    • The scrollback hold for SSH and paired tabs.
    • SSH conversion eligibility.
    • The wake-relaunch history save.
    • A user move connecting a parked host, automatic moves and recovery never booting one, and neither reconnecting a ready host.
  • Local checks: pnpm tc and check:code-quality:changed pass, the ratchets pass, and the touched tests pass. Full lint and the full test suite are left to CI while the build Mac is overloaded.

  • Real host: verify-15a ran on the stack. verify-15b will run on this head.

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

  • Platforms: the mover itself runs only on Windows with WSL, and only behind the gate. The Wake fix is general and applies on every platform. The ConPTY reflow is not in this PR (fix(terminal): keep ConPTY's viewport top through a width change #34061).
  • Mixed versions: the new RPCs and capabilities are registered and advertised only on a WSL host's orcad, and only the gated driver calls them. The one ungated wire change is additive: the optional durableCommitted field on abort-by-reference (see Wire surface), which older peers ignore.

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)

nwparker and others added 30 commits October 20, 2026 21:41
…collectors

Co-Authored-By: Claude <noreply@anthropic.com>
…urce-kind scope

A local-WSL scope lives on host local and owns only its projects, so host-wide
matches stay an SSH whole-host rule. SSH bytes are pinned by the collector golden.

Co-Authored-By: Claude <noreply@anthropic.com>
…ormant state (D1b-3c)

Collects the scoped projects, their groups and every dormant-state kind through the
local-WSL export scope, rewrites UNC paths to the distro's, and returns blockers for
anything the collectors can't carry instead of dropping it. Automations move disabled,
as the wire requires, and come back as a list to re-enable on the host after commit.

Co-Authored-By: Claude <noreply@anthropic.com>
…the host proves a commit

Co-Authored-By: Claude <noreply@anthropic.com>
… large for a request

Co-Authored-By: Claude <noreply@anthropic.com>
…d move forward on a by-reference commit only once the host flushed it

Co-Authored-By: Claude <noreply@anthropic.com>
… stays readable

Co-Authored-By: Claude <noreply@anthropic.com>
… scrollback, and never read bytes in render (D1b-6d-1)
…e the shared RPC error check, after main moved both (D1b-6d-1)
…ssion after a move (D1b-7c)

Registers the main-side desktop rewrite stores ui-routing, session-globals and host-session-seed. Adds a +2 main layout-writer baseline line for wsl-move-main-rewrite-stores.ts: these are one-shot, ledgered move rewrites, and no LayoutCommand can set focus or seed a runtime host's partition.
… one copy of each moved tab, and copy instead of move (D1b-7c)
…heir UI through catalog prunes (D1b-7d)

Registers the renderer-side desktop rewrite stores quick-open-history, file-view-preferences and notebook-environments. The renderer copies each moved workspace's entry to its WSL host key, marks it applied in the same storage, and records the ledger entry; main requests a storage flush first and accepts only the main window. Committed moves are re-listed for re-application at every startup. Catalog prunes keep filters, hook trust and setup-script dismissals of moved repos.
…manifest exporter, where 7d moved it (D1b-7d)
…he desktop (D1b-7e)

Settled local worker dispatches and their worker-terminal rows in a moved
project take the WSL host's worktree id, in one ledgered, idempotent store.
Chat workers, live rows, federated attachments and JSON receipts stay as
written; automations keep their unchanged local copy (the scheduler only
advances it). Per-table dispositions for orchestration.db.

Co-Authored-By: Claude <noreply@anthropic.com>
…is live; skip federated rows (D1b-7e review)

Co-Authored-By: Claude <noreply@anthropic.com>
…ve (D1b-7f)

A committed WSL move now copies each in-app browser profile's cookies once into
the WSL host's stable route partition (owner decision 3a), merging without
overwriting what the host jar holds and never touching the source. Where that
is infeasible (no deployment link so no stable partition, the destination is
not a WSL host or is gone, or the partition name is held by another identity)
the host starts fresh and the move journal records why (3b). Registered as the
ledgered browser-cookies rewrite store; it runs only once browser sessions and
an app window exist. WSL_MOVE_DESKTOP_REWRITE_REGISTRY_COMPLETE stays false.
…duction gate facts and journaled restore folders

One entry point (and preview/start/cancel/listUnfinished IPC for D1b-9) plans the move, gates
terminals on the hook server's agent status, the close-tab process probe, running automation runs
and live dispatches, pauses and proves exit, stages, sends blobs, commits only from
blobs-transferred (#29825), and finishes on the desktop. Any failure resets to zero or goes forward
when the host committed. Restore folders and the automations to turn back on are kept in the
journal; the host turns those automations back on after commit, retried until it confirms.
A real-PTY test pauses daemon shells, and runs on a real distro in the WSL orcad lane.
…ult behind the internal WSL hosts gate (D1b-9)
…fter a reload, and lets a start settle an unfinished move (D1b-9 review)
…/wsl-mover-land-2

# Conflicts:
#	src/renderer/src/i18n/locales/zh.json
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
…/wsl-mover-land-2

# Conflicts:
#	src/renderer/src/i18n/locales/es.json
#	src/renderer/src/i18n/locales/fr.json
#	src/renderer/src/i18n/locales/ja.json
#	src/renderer/src/i18n/locales/ko.json
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…core registration under its line cap

The optional commit-message resolvers pass straight through, so the call is the same with or
without them. #34059 left this file at the 300-line cap and the WSL drive-project wiring adds to it.

Co-Authored-By: Claude <noreply@anthropic.com>
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
…/wsl-mover-land-2

# Conflicts:
#	src/main/ipc/ui.ts
@nwparker
nwparker merged commit 1eaaf85 into main Oct 28, 2026
89 checks passed
nwparker added a commit that referenced this pull request Oct 28, 2026
… label moved automations

Follow-ups from the #34059 undo review, stacked on it:
- A host workspace's terminal count reads as zero only when the host says it no longer has the
  workspace (selector_not_found); any other error, or an answer it cannot read, now counts as the
  host not answering, so undo refuses.
- The exit wait keeps one wall-clock deadline for the whole stop instead of counting polls, so a
  slow host can no longer stretch it many times over.
- A test for D1b-7a's hydration purge rule: a moved project's chats survive, a stale worktree
  still goes.
- A moved project's local automation reads "Runs on the <distro> host" in the list, where it
  read Enabled though this computer never runs it.
nwparker added a commit that referenced this pull request Oct 28, 2026
…el moved automations (#34686)

* fix(wsl-mover): undo's host checks fail closed and keep one deadline; label moved automations

Follow-ups from the #34059 undo review, stacked on it:
- A host workspace's terminal count reads as zero only when the host says it no longer has the
  workspace (selector_not_found); any other error, or an answer it cannot read, now counts as the
  host not answering, so undo refuses.
- The exit wait keeps one wall-clock deadline for the whole stop instead of counting polls, so a
  slow host can no longer stretch it many times over.
- A test for D1b-7a's hydration purge rule: a moved project's chats survive, a stale worktree
  still goes.
- A moved project's local automation reads "Runs on the <distro> host" in the list, where it
  read Enabled though this computer never runs it.

* fix(wsl-mover): undo gives the host's terminals a minimum window to exit after the last sleep

A slow but healthy host with many workspaces could spend the whole stop budget sleeping them and
then read as still running on the first exit check. The exit wait now runs at least 5 s past the
last sleep, within or beyond the overall deadline.
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…core registration under its line cap

The optional commit-message resolvers pass straight through, so the call is the same with or
without them. #34059 left this file at the 300-line cap and the WSL drive-project wiring adds to it.

Co-Authored-By: Claude <noreply@anthropic.com>
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…core registration under its line cap

The optional commit-message resolvers pass straight through, so the call is the same with or
without them. #34059 left this file at the 300-line cap and the WSL drive-project wiring adds to it.

Co-Authored-By: Claude <noreply@anthropic.com>
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…core registration under its line cap

The optional commit-message resolvers pass straight through, so the call is the same with or
without them. #34059 left this file at the 300-line cap and the WSL drive-project wiring adds to it.

Co-Authored-By: Claude <noreply@anthropic.com>
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
nwparker added a commit that referenced this pull request Oct 28, 2026
…D1c-2) (#33090)

* feat(wsl): run Git for Windows for a WSL project on a Windows drive

A project on C:\ whose runtime is WSL ran every Orca Git command through wsl.exe on
/mnt/c: ~300x slower than Windows Git, and blind to Windows-side edits. The project's
WSL runtime preference gains an optional `git: 'windows-host'`. With it, Orca's Git
(and where new worktrees go) is Windows; terminals, agents, accounts and hooks still
resolve to WSL, so nothing else changes. Older builds drop the field and go back to WSL
Git.

The conversion checks first, then the caller saves the returned preference through the
normal project update:
- Git for Windows must exist.
- New worktrees must not be set to go inside the distro.
- No linked worktree may have a Linux-path link. WSL Git made those; Windows Git sees
  them as prunable, and Orca's prune after a worktree removal would delete their
  metadata.
- Optionally writes core.autocrlf=true into the repo when Windows Git uses it, so WSL
  Git in the project's terminals stops seeing CRLF changes. Never core.checkStat.

IPC is refused off Windows and with the internal WSL hosts gate closed.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(wsl): mock the drive-project IPC in the core handler registration test

Co-Authored-By: Claude <noreply@anthropic.com>

* test(wsl): pin WSL Git for a drive project that never chose Windows Git, and record which Git ran

* fix(wsl): base-ref lookups and the remote-identity sweep run Git where the project's runtime does

* fix(wsl): route base-ref and remote-identity reads by runtime only with WSL hosts on

These reads ran host Git on main. Routing them into a WSL-runtime project's
distro is part of D1c, so with the WSL hosts gate closed they run host Git
exactly as before.

(cherry picked from commit 2ed82987dc5b82c3a86ea7e03ce05e9efc3e77fb)

* refactor(ipc): register the filesystem handlers in one call, keeping core registration under its line cap

The optional commit-message resolvers pass straight through, so the call is the same with or
without them. #34059 left this file at the 300-line cap and the WSL drive-project wiring adds to it.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): skip folder repos in the Windows Git check, and read worktree links with the prune guard's reader

Folder repos run no Git, so rev-parse on them always failed the preview. The link reader and
the WSL-authored test now come from worktree-prune-guard.ts; the copy's startsWith('/') wrongly
refused //wsl.localhost links, which Windows Git writes itself.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(wsl): the remote-identity sweep checks the distro a drive project's Git runs in, so it never boots a stopped one

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
OrcaWin added a commit that referenced this pull request Oct 28, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
OrcaWin added a commit that referenced this pull request Oct 29, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
nwparker pushed a commit that referenced this pull request Oct 29, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
nwparker pushed a commit that referenced this pull request Oct 29, 2026
…on, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)
nwparker added a commit that referenced this pull request Oct 29, 2026
… restart (D1c-4c) (#33135)

* feat(wsl): convert UNC Windows-drive projects to drive paths across a restart (D1c-4c)

* fix(wsl): read the conversion's field table from its shared home

* test(wsl): the conversion runs Windows Git only on the drive path, since WSL denies UNC drive folders

WSL 2.7.11 answers EPERM for \\wsl.localhost\<distro>\mnt\c\... from Windows. Pin that the
preflight's Git runs and worktree-link reads use C:\... by making every UNC access throw EPERM.

* fix(wsl): name the cause when a conversion refuses over saved state

A refusal over saved state now says whether a project also holds an unconverted repo, or a drive
key already holds different data (and which key), instead of a bare collision code. The fields are
optional, so the window's copy still reads an older host's refusal. The seeded shape (a saved UNC
worktree with tabs beside the bare drive row startup discovery wrote) now converts.

* test(wsl): startup rolls back only when the drive key holds different user data

* fix(wsl): connect the conversion's pause to a WSL host as a user action, as #34059's mover now requires

Co-Authored-By: Claude <noreply@anthropic.com>
(cherry picked from commit bfeb4fe3ae7f278ac452e376d426315dbf7b985c)

* fix(wsl): never report a committed conversion as rolled back; record and check its profile; refuse paths off a Windows drive mount

- The journal's post-commit phase write sat inside the rollback catch, so a failure there
  dropped the journal and reported rolled-back for a profile already rewritten. The write now
  follows the commit outside the catch: a failure leaves the journal 'prepared', whose rewrite
  is idempotent, and reports resuming.
- The journal records the profile it rewrites, and startup runs only the active profile's.
- The run reads the distro's Windows-drive mounts and passes them to the scope.

Co-Authored-By: Claude <noreply@anthropic.com>

* test(wsl): type the journal-failure switch without a cast

* fix(wsl): only this profile's waiting conversion blocks starting another

* test(wsl): compare the two profiles' journals without depending on directory order

* fix(wsl): a torn shell-history meta.json never stalls a conversion, it is written atomically, and only a prepared conversion blocks a new one

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
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.

2 participants