Skip to content

feat(wsl): admit no new WSL host or move in serve-only (kill switch 2/2) - #34694

Merged
nwparker merged 4 commits into
mainfrom
nwparker/wsl-kill-switch-block-entry-points
Oct 28, 2026
Merged

nwparker merged 4 commits into
mainfrom
nwparker/wsl-kill-switch-block-entry-points

Conversation

@nwparker

@nwparker nwparker commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 6 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​80 $\color{#cf222e}{\Huge{\mathbf{−}}}$​5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​75
Prod 9 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​39 $\color{#cf222e}{\Huge{\mathbf{−}}}$​10 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​29

Stacked: based on nwparker/wsl-kill-switch-gate-states (#34683), which is based on main at 1eaaf85e9fd. Merge after #34683.

ELI5

The previous PR keeps saved WSL hosts and moved projects working when the internal WSL switch is off (serve-only). This PR makes sure serve-only can't grow: nobody can add a new WSL host or move another project onto one. Saved hosts still connect and can be removed.

What Changed

Main:

  • Add refused: the wslHosts:add refusal itself now lives in feat(wsl): serve saved WSL work behind a closed hosts gate (gate states, kill switch 1/2) #34683, so that PR is safe on its own.
  • Moves: they already needed the open gate (refuseUnlessOpen on preview, start and cancel, plus the orchestrator), so nothing changes there.
  • Capability: wslHosts:getCapability now also returns acceptsNewWork (true only with the open gate). It's an optional field, so a renderer from before this change treats it as absent, which means allowed. Main still refuses either way.

Renderer:

  • Store: a new wslHostsAcceptNewWork, which starts false and is set from the capability by wsl-host-ipc-bridge.ts, so Add and Move never flash in serve-only before main answers.
  • Hook: useWslHostsAcceptNewWork() means WSL hosts are enabled and main accepts new work.
  • Hidden in serve-only:
    • "Add WSL distro" in the add-project host menu (AddRepoHostSelectorSlot);
    • "Add WSL distro" in Settings (WslHostsSection), where serve-only also doesn't show "Turn on in Experimental";
    • "Move projects from this distro…" on a host row;
    • every per-project Move entry, through useWslMoveTargetForRepo: the project menu and the project settings runtime row;
    • the WSL-bridge chat refusal's "Add the distro as a WSL host…" wording (feat(wsl-host): point the WSL chat refusal at adding the distro as a WSL host #34804). wslHostChatAvailable() now also requires wslHostsAcceptNewWork, so serve-only keeps the terminal-only words instead of pointing at a hidden button.
  • Still shown: Connect, Remove and the rest of a saved host's row.

Flag-off: with the gate open, acceptsNewWork is true and nothing changes. With the gate closed and nothing saved, there's no WSL API and no service, as before.

Why

Serve-only exists to keep users' existing work reachable after a rollback. Admitting new hosts or moves behind a closed gate would defeat the rollback. Both main and the renderer enforce it, so an older renderer, or a direct IPC call, still can't add a host.

Linked Issue

N/A (WSL hosts kill switch, PR2 of the design).

Visual Proof

N/A beyond the e2e screenshot wsl-hosts-serve-only-settings.png: the "Add WSL distro" button and the move entries are removed, and nothing is added.

Testing

  • wsl-host-handlers-user-actions.test.ts:

    • with the gate open, Add still reports as before;
    • in serve-only, Add is refused without calling the service, the capability says acceptsNewWork: false, and Remove still works.
  • use-wsl-hosts-enabled.test.tsx: with the gate open, new work is offered; once main reports serve-only, saved hosts stay enabled but nothing new is offered.

  • structured-agent-session-launch-failure-wsl.test.ts: serve-only keeps the terminal-only words. This fails without the check.

  • e2e serve-only case (extended). Both gate-closed cases pass locally, hidden (ORCA_BACKGROUND_LAUNCH=1).

    • IPC wslHosts.add is refused (disabled).
    • IPC wslMove.start is refused (wsl_move_unavailable).
    • There's no "Add WSL distro" in the add-project host menu or in Settings → Servers.
    • The saved host is still listed, connects and stays on disk.
  • The 18 suites that import the touched modules pass (145 tests). WslMoveDialog.test.tsx's mock gained the new hook export.

  • pnpm tc, typecheck:ci, oxlint, the anti-slop lint, ast-grep-gates.mjs, check:code-quality:changed and check:process-host-imports pass.

  • I manually tested these changes locally

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

AI Disclosure

Review

Risk: low.

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

  • Desktop only. acceptsNewWork is an optional field on a desktop-local IPC reply, not a paired-wire contract.
  • Not here: the "WSL hosts paused" banner (PR3 of the design) and the remote policy fetcher (PR4/5, which needs owner sign-off).

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
nwparker force-pushed the nwparker/wsl-kill-switch-block-entry-points branch 2 times, most recently from 17a2c09 to b494660 Compare October 28, 2026 06:29
@nwparker
nwparker force-pushed the nwparker/wsl-kill-switch-gate-states branch from d5c4907 to b4b8acf Compare October 28, 2026 07:20
@nwparker
nwparker force-pushed the nwparker/wsl-kill-switch-block-entry-points branch from b494660 to bd357a7 Compare October 28, 2026 07:20
@nwparker
nwparker changed the base branch from nwparker/wsl-kill-switch-gate-states to main October 28, 2026 07:21
@coderabbitai

coderabbitai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e3b942b9-404d-4a0b-ac91-d46a7e77c358
Commits

Reviewing files that changed from the base of the PR and between 0a349b3 and f6217cd.

Files selected for processing: 15
  • src/main/ipc/wsl-host-handlers-user-actions.test.ts
  • src/main/ipc/wsl-host-handlers.ts
  • src/renderer/src/components/settings/WslHostsSection.tsx
  • src/renderer/src/components/sidebar/AddRepoHostSelectorSlot.tsx
  • src/renderer/src/components/sidebar/use-wsl-hosts-enabled.test.tsx
  • src/renderer/src/components/sidebar/use-wsl-hosts-enabled.ts
  • src/renderer/src/components/wsl-move/WslMoveDialog.test.tsx
  • src/renderer/src/components/wsl-move/wsl-move-entry.ts
  • src/renderer/src/components/wsl-move/wsl-move-orchestrator-flag-off.test.tsx
  • src/renderer/src/hooks/ipc-events/wsl-host-ipc-bridge.ts
  • src/renderer/src/lib/structured-agent-session-launch-failure-wsl.test.ts
  • src/renderer/src/lib/structured-agent-session-launch-failure.ts
  • src/renderer/src/store/slices/wsl-hosts.ts
  • src/shared/wsl-host-types.ts
  • tests/e2e/wsl-host-fake-transport.spec.ts

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

Walkthrough

The WSL host capability response now includes whether hosts accept new work. The renderer stores this value and uses it to gate host additions, WSL moves, and WSL chat availability. Saved hosts remain enabled when new work is not accepted. Tests cover capability reporting and serve-only behavior.

Priority: Normal

Merge Risk: Minimal · up to f6217

New-host and move controls follow the gate while saved-host access remains available. No material merge risk was established.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 62.50% 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 Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title names the main change: a serve-only WSL gate that stops new WSL hosts and moves while keeping saved hosts. It follows the conventional commit format and matches the changeset, which adds acc…
Description check Passed The description follows the template well. It has ELI5, What Changed, Why, Testing, AI Disclosure, Review, Agent skill upstream boundary, Notes, and Checklist sections. It explains the before and afte…
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.
Full details: Title check

Explanation

The title names the main change: a serve-only WSL gate that stops new WSL hosts and moves while keeping saved hosts. It follows the conventional commit format and matches the changeset, which adds acceptsNewWork to the capability and hides Add and Move entry points. The '(kill switch 2/2)' suffix is series context and does not hurt clarity.

Full details: Description check

Explanation

The description follows the template well. It has ELI5, What Changed, Why, Testing, AI Disclosure, Review, Agent skill upstream boundary, Notes, and Checklist sections. It explains the before and after behavior, the mechanism (main refusal, optional capability field, renderer store and hook), and the reason for the approach. It also gives detailed test evidence. Gaps: the Linked Issue section says N/A and does not link an issue, although the template requires one for outside contributors. The Visual Proof section cites a screenshot filename but does not attach a before and after. The Testing checkbox is marked, but the final checklist item for pnpm lint, typecheck, test, and build is unchecked. The AI Disclosure section is empty.

Full details: Docstring Coverage

Explanation

Docstring coverage is 62.50% 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 8 functions across 15 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.

❤️ Share

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

Main refuses wslHosts:add while the internal gate is closed and reports
acceptsNewWork in the WSL host capability; moves already need the open gate.
The renderer hides Add WSL distro and every Move entry point once main says
serve-only, while saved hosts keep their Connect and Remove.
…lity

The renderer's acceptsNewWork now starts false, so Add WSL distro and the Move
entries never flash in serve-only before the capability reply.
…en it is offered

In serve-only Add WSL distro is hidden, so the refusal keeps its terminal-only
words there.
#34676's test mocks use-wsl-hosts-enabled; WslHostsSection now also reads
useWslHostsAcceptNewWork, which follows the same gate there.
@nwparker
nwparker force-pushed the nwparker/wsl-kill-switch-block-entry-points branch from bd357a7 to f6217cd Compare October 28, 2026 08:14
@nwparker
nwparker merged commit 0cca424 into main Oct 28, 2026
87 of 88 checks passed
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