Skip to content

fix(desktop): support safe WSL on-demand Host handoff across incompatible deployments #5143

Description

@me2seeks

What happened

Desktop cannot complete an incompatible managed WSL on-demand Host handoff. It directs the user to a manual update elsewhere and keeps an elapsed timer running, but provides no usable action for the managed WSL deployment it already knows how to address.

This issue is narrowed following review feedback. It covers one end-to-end WSL journey: classify the existing management route, retire through the persisted source operator, activate the selected exact deployment and reconnect, with truthful blocker UI. It does not define general WSL/SSH version governance.

Two lifecycles remain distinct:

  • The WSL Host process is on-demand/ephemeral. It can be reused by multiple surfaces and may remain alive for connections or work, but it does not promise long-term availability. Closing one client does not authorize stopping other work.
  • The deployment, exact package, operator and State Root ownership are durable. Process exit neither uninstalls the package nor deletes sessions. A restart of the same old package does not fix a cross-epoch mismatch.

How to reproduce / evidence

  1. Retain a WSL managed on-demand Host installed by Desktop.
  2. Connect with a Desktop whose contract is incompatible with that deployment.
  3. Observe the manual-update blocker with Cancel/Recheck but no WSL handoff action. The reported window reached 89:14; that duration is user-reported, not independently timed.
  4. The separate re-onboarding workaround can fail with Runtime Host cannot prepare for retirement: incompatible when new setup code attempts to retire a running incompatible on-demand Host. The precise user click before that error remains unconfirmed.

Source findings:

  • runtime-host-desktop-candidate.ts classifies profile targets as external; runtime-host-desktop-manager.ts supplies no replacement route for them. Connect-only SSH and an authority-verified managed WSL environment must not be treated identically.
  • runtime-host-lifecycle-transaction.ts requires a compatible connection for on-demand retirement when there is no supervisor. An isolated diagnostic using its real State Root writer lock and a stubbed incompatible handshake reproduced the error with either interruption policy. Releasing the writer allowed retirement. This is not a full Windows handoff E2E claim.
  • The existing managed update transaction already uses the installed source operator. Reuse that authority, rather than inventing a second updater or lifecycle owner.

Environment

  • Windows installed Desktop artifact inspected: 0.2.0-dev.25.20260908.
  • WSL Ubuntu / Linux x64 / 6.6.87.2-microsoft-standard-WSL2.
  • Managed Host 0.2.0-dev-fe229269f0df, epoch 121. Source TUI epoch 133 and a later Desktop diagnostic epoch 136 were separately observed; they are not asserted to belong to the inspected Desktop build.
  • Source investigation at f09119884e3e640f1c10755da19a583416aed19f; relevant Desktop manager paths subsequently checked locally.

Expected behavior

  1. Ordinary connection reuses/activates the installed deployment. Deterministic incompatibility is a blocker, not update progress. Show Cancel, Recheck and, when managed WSL authority and a valid target are available, an explicit action equivalent to Stop the old Host and continue with the selected Host. If this changes the package, disclose current/target identities; do not disguise a package change as a restart.
  2. Recognize managed WSL control capability from the validated persisted operator and deployment binding. Being a WSL profile alone is not authority. Do not grant a connect-only SSH profile replacement rights.
  3. After explicit handoff selection, execute safe retirement automatically only when absence of active work is established through the source operator/Host contract. A connected idle TUI is not itself proof of active work. Active work needs a separate interruption confirmation; if safe admission cannot be established, block truthfully. Do not add new cooperative-transfer promises.
  4. Stage/verify the selected exact target, retire through the persisted source operator, then use existing lifecycle transaction/writer fences for cutover, readiness verification and reconnect. New-client business-protocol compatibility with the old Host must not be a prerequisite to this control operation.
  5. Bind and revalidate deployment identity, Root ID and Host epoch under existing serialization. Changed identity, missing source operator or unknown activity produces a bounded blocker. No wsl --terminate, raw PID kill, deletion of ownership records or second writer.
  6. No Host downgrade. If the Host is known to be newer than Desktop, guide the user to update Desktop. Do not infer product ordering from epoch or source hash; uncertain target suitability is not permission to downgrade.
  7. Cancel before commit leaves existing work/deployment intact; once mutation has committed, complete the existing safe settlement/recovery contract and report that state. Do not claim an unsafe old-version rollback after the target may have opened storage. Distinguish successful handoff from failed Desktop reconnection.
  8. Keep the strict protocol/epoch/composition contract. Source builds may use an explicit development artifact without release-channel parity, but do not bypass ownership, storage admission or activity protection.

Acceptance

  • Existing compatible WSL Host is reused; stopped deployment can be activated without incidental replacement.
  • Running incompatible old Host + no active work: explicit action completes source-operator retirement, selected deployment activation and Desktop reconnect.
  • Connected idle TUI vs active TUI work: source-owned maintenance admission distinguishes them; activity interruption is separately confirmed. A TUI incompatible after cutover remains truthfully disconnected, not silently replaced or promised recovery.
  • Newer Host + older Desktop: no downgrade; compatible connection succeeds, otherwise client-update guidance.
  • Missing operator, unknown activity, changed Host/deployment or concurrent handoff: bounded non-destructive blocker/revalidation.
  • Cancel, transport loss and WSL exit around transaction boundaries recover from existing durable authority; no double writer or fabricated success.
  • Blocker state has no false update-progress timer; an actual handoff has real progress and truthful cancellation semantics.
  • Connect-only SSH remains unable to replace its Host; no broad SSH maintenance redesign is required.

Scope and related work

简体中文

根据审查意见收窄为一条完整的 WSL 按需 Host 交接:Desktop 遇到不兼容时,识别受验证的部署管理入口,通过旧 operator 安全退场,启动选定的精确部署并重连。临时的是进程,不是安装和数据;按需也不表示可以随意结束其他客户端的任务。

界面提供取消、重新检查,以及具备管理能力时“停止旧 Host 并继续”。需要换包时明确展示当前/目标版本;普通连接不隐含换包授权。选择交接后,无活动工作才自动完成;中断活动工作另行确认。有一个空闲 TUI 不等于有活动工作,未知状态也不能当成空闲。

操作复用现有部署事务,绑定并复验 deployment、Root ID 和 Host epoch。不终止整个 WSL、不裸杀 PID、不新增 owner、不绕过 epoch。不降级 Host;Host 较新时引导更新 Desktop。管理入口缺失、状态未知或身份改变均明确阻塞。取消与断线按事务阶段恢复,不能虚假承诺回滚。

保留 #5144 独立修复 onboarding 授权问题;#5145/#5146 的 WSL 必要部分合并到这里。移除 SSH 全矩阵、最新频道、客户端 inventory 和完整源码/发布组合等关闭条件。尚未实现,不因合并 issue 宣称缺陷已修复。

AI disclosure: OpenAI Codex investigated and revised/submitted this issue under explicit user direction accepting the review feedback.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions