-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(install): add no-WSL Windows candidate installer #10799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7d449f8
2d52feb
c8eacb9
1fa7e17
94ad38a
b833363
a8e4fe2
ce5d958
d402736
9df5c56
4c89232
5e808e2
b14b3c5
21b8c69
ef0edd2
e4d90f8
b803b65
d185049
3b8ded5
ee8dba7
d168651
3432028
be5d5ed
3dd80ef
c1b9e1a
9594a7b
9f32046
2eda6ed
b079406
c5eb5e7
acbfdac
f332eec
e7e7109
3ff04f5
8d63654
1042a54
3645738
fd29c69
eb79a93
5b965df
2a248fc
d4471ab
479b36e
c209640
5475f6a
6f44a32
4fb8cd7
8dd76a4
2b72dc9
ac48721
428957b
eb5ddee
bffb031
07878a2
4306e7e
4aae7e0
8b55f32
33d01a5
995d98a
df42e2f
32297ad
2c7c2a7
2253765
7fa8f9e
c032a7f
2f63b60
c6d8a32
27745da
ef83c08
2b68f38
91a447c
d97041e
d6d2e8a
5862b73
f3fe553
5033c7d
da3436f
d5b0234
704fd79
6795d13
971bd4f
396a048
2f2df9e
3a51db1
fbce77a
921a991
f2464e0
9947945
63a9619
4815184
4849749
0aac82d
c81dc8c
590888d
40d0f9e
8697371
d421215
7b9d781
5b39c78
16e5154
210ad84
1835073
fd64ef6
6d47532
e3447f4
86bbc95
50f4679
68debc9
2400d18
9c0aeb5
3b55fdf
d09750f
d557373
dffc854
0f4e352
e542aa8
18464f4
5c32ad6
8c1b7fc
f4eef71
d4cf05b
3b54151
d5a3d23
b8f7f15
8c74606
ff256cb
485ade9
826621a
5eb1be9
32fb244
3060eeb
99557b7
d1899c2
b806274
3f0a919
6766c18
b285014
e0bc9e1
84d4169
349ab13
b0c3874
5026563
ede9f59
9d2daca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| <!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> | ||
| <!-- SPDX-License-Identifier: Apache-2.0 --> | ||
| <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| <Bundle | ||
| Name="NemoClaw" | ||
| Manufacturer="NVIDIA Corporation" | ||
| Version="$(var.ProductVersion)" | ||
| UpgradeCode="1BA739B8-B632-4A8C-BB02-95058CC3A960" | ||
| IconSourceFile="$(var.SourceRoot)\packaging\windows\assets\NemoClaw.ico" | ||
| AboutUrl="https://github.com/NVIDIA/NemoClaw" | ||
| Copyright="Copyright (c) 2026 NVIDIA Corporation and affiliates"> | ||
| <BootstrapperApplication SourceFile="$(var.BootstrapperPath)"> | ||
| <PayloadGroupRef Id="NemoClawBootstrapperPayloads" /> | ||
| </BootstrapperApplication> | ||
| <Chain> | ||
| <ExePackage | ||
| Id="MxcSystemDrivePreparation" | ||
| CacheId="MxcSystemDrivePreparation-0.8.0-arm64" | ||
| Name="mxc\wxc-host-prep-system-drive.exe" | ||
| SourceFile="$(var.WxcHostPrepPath)" | ||
| InstallArguments="prepare-system-drive" | ||
| PerMachine="yes" | ||
| Permanent="yes" | ||
| Compressed="yes" | ||
| Vital="yes" /> | ||
| <ExePackage | ||
| Id="MxcNullDevicePreparation" | ||
| CacheId="MxcNullDevicePreparation-0.8.0-arm64" | ||
| Name="mxc\wxc-host-prep-null-device.exe" | ||
| SourceFile="$(var.WxcHostPrepPath)" | ||
| InstallArguments="prepare-null-device" | ||
| PerMachine="yes" | ||
| Permanent="yes" | ||
| Compressed="yes" | ||
| Vital="yes" /> | ||
| <MsiPackage Id="NemoClawArm64Msi" SourceFile="$(var.MsiPath)" Compressed="yes" Vital="yes" /> | ||
| </Chain> | ||
| </Bundle> | ||
| </Wix> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| {\rtf1\ansi\deff0 | ||
| {\fonttbl{\f0 Segoe UI;}} | ||
| \fs20 | ||
| NemoClaw Native Windows Candidate Preview\par | ||
| \par | ||
| Copyright (c) 2026 NVIDIA Corporation and affiliates.\par | ||
| \par | ||
| NemoClaw is licensed under the Apache License, Version 2.0. The complete | ||
| license is installed with the product as LICENSE.txt and is available in the | ||
| NemoClaw source repository.\par | ||
| \par | ||
| This package is a qualification candidate. It does not establish production | ||
| support for native Windows, Microsoft MXC, or any agent runtime.\par | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| MIT License | ||
|
|
||
| Copyright (c) Microsoft Corporation. | ||
|
|
||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
|
|
||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
|
|
||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| NemoClaw Native Windows Candidate Preview | ||
|
|
||
| This package contains the NemoClaw CLI, Node.js 22.22.3, OpenClaw 2026.7.1, | ||
| native Windows ARM64 builds of openshell.exe and openshell-gateway.exe from | ||
| NVIDIA/OpenShell#2721 merge commit bcd517bbe08cc80860c9be57699390cd32e8445f, | ||
| and the pinned Microsoft MXC 0.8.0 ARM64 wxc-exec.exe and wxc-host-prep.exe | ||
| ProcessContainer tools. WSLC and other unused backend sidecars are excluded. | ||
|
|
||
| The packaged OpenShell gateway is a source-built NVIDIA/OpenShell#2721 | ||
| derivative with the checked-in OPENSHELL-NODE-UI-COMPATIBILITY.patch applied. | ||
| That compatibility change emits ui.disable=false so the contained Node.js | ||
| process can initialize. The qualification turn runs OpenClaw in a worker inside | ||
| that same process; MXC filesystem containment remains active. | ||
|
|
||
| The pinned OpenShell create watcher does not return after the one-shot workload | ||
| completes. NemoClaw stops that client-side watcher after receiving the exact | ||
| workload result, then deletes the sandbox through OpenShell. | ||
|
|
||
| The NVIDIA-branded setup installs a native ARM64 NemoClaw GUI launcher and a | ||
| graphical first-run experience. The interface names OpenClaw, Hermes Agent, | ||
| LangChain Deep Agents Code, Pi, and NemoCUA, with Pi and NemoCUA explicitly | ||
| marked experimental. Every enabled choice has an agent-specific executable | ||
| adapter: OpenClaw opens its authentic Control UI, Hermes Agent, Deep Agents | ||
| Code, and Pi open their native terminal surfaces, and NemoCUA runs its bounded | ||
| experimental visible-browser implementation. A choice is not a production | ||
| support claim until its exact package qualification passes. | ||
|
|
||
| CI separately drives three deterministic turns through each real agent runtime | ||
| inside native MXC. OpenClaw uses its Control UI; terminal agents use their | ||
| genuine non-interactive CLI modes; NemoCUA observes and acts on real Edge | ||
| pixels. The deterministic loopback model proves transport and runtime wiring | ||
| without a pull-request secret; it is not production inference quality. | ||
|
|
||
| Graphical onboarding collects the selected provider endpoint and model. | ||
| Provider API keys are written by the native ARM64 launcher to Windows | ||
| Credential Manager and are not stored in MSI-owned files or JSON. Agent state | ||
| and secret-free configuration live below the current user's Local AppData. | ||
| Runtime processes receive only an authenticated, ephemeral loopback broker | ||
| route; the provider credential remains on the Windows host. | ||
|
|
||
| The setup executable applies Microsoft MXC's elevated prepare-system-drive and | ||
| prepare-null-device host prerequisites before installing the MSI. Windows | ||
| resets the null-device prerequisite at reboot; persistent production lifecycle | ||
| ownership remains deferred. | ||
|
|
||
| This is a qualification candidate, not a production support claim. Native MXC | ||
| execution remains limited by the Windows host build and capabilities. Gateway | ||
| service registration, messaging, web-search integration, managed local-model | ||
| lifecycle, and production activation remain incomplete. Mutable runtime state | ||
| stays outside this MSI-owned installation directory. | ||
|
|
||
| PR qualification artifacts are unsigned. Production use remains gated on | ||
| Authenticode signing of the NemoClaw, OpenClaw, OpenShell, MXC, MSI, and setup | ||
| payloads as applicable. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| <!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> | ||
| <!-- SPDX-License-Identifier: Apache-2.0 --> | ||
| <Project Sdk="WixToolset.Sdk/5.0.2"> | ||
| <PropertyGroup> | ||
| <OutputType>Bundle</OutputType> | ||
| <InstallerPlatform>arm64</InstallerPlatform> | ||
| <OutputName>NemoClawSetup-$(ProductVersion)-windows-arm64</OutputName> | ||
| <OutputPath>$(PackageOutputRoot)</OutputPath> | ||
| <IntermediateOutputPath>$(PackageIntermediateRoot)\bundle\</IntermediateOutputPath> | ||
| <EnableDefaultCompileItems>false</EnableDefaultCompileItems> | ||
| <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> | ||
| <DefineConstants>$(DefineConstants);ProductVersion=$(ProductVersion);SourceRoot=$(SourceRoot);MsiPath=$(MsiPath);WxcHostPrepPath=$(PayloadRoot)\mxc\wxc-host-prep.exe;BootstrapperPath=$(BootstrapperPath);BootstrapperRoot=$(BootstrapperRoot)</DefineConstants> | ||
| <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||
| <!-- The null-device prerequisite is boot-ephemeral by Windows design, so a | ||
| durable DetectCondition would incorrectly skip it after reboot. --> | ||
| <SuppressSpecificWarnings>1161</SuppressSpecificWarnings> | ||
| <DebugType>none</DebugType> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <Compile Include="Bundle.wxs" /> | ||
| <Compile Include="$(GeneratedBootstrapperPayloadAuthoring)" /> | ||
| </ItemGroup> | ||
| <Target Name="ValidateNemoClawBundleInputs" BeforeTargets="ResolveWixExtensionReferences"> | ||
| <Error Condition="'$(MsiPath)' == ''" Text="MsiPath is required." /> | ||
| <Error Condition="!Exists('$(MsiPath)')" Text="The ARM64 MSI input is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\mxc\wxc-host-prep.exe')" Text="The pinned ARM64 MXC host-preparation input is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\NemoClaw.exe')" Text="The NemoClaw UI launcher is missing." /> | ||
| <Error Condition="'$(BootstrapperPath)' == ''" Text="BootstrapperPath is required." /> | ||
| <Error Condition="!Exists('$(BootstrapperPath)')" Text="The native ARM64 NemoClaw bootstrapper application is missing." /> | ||
| <Error Condition="'$(BootstrapperRoot)' == ''" Text="BootstrapperRoot is required." /> | ||
| <Error Condition="!Exists('$(BootstrapperRoot)\mbanative.dll')" Text="The native WiX managed-bootstrapper bridge is missing." /> | ||
| <Error Condition="'$(GeneratedBootstrapperPayloadAuthoring)' == ''" Text="GeneratedBootstrapperPayloadAuthoring is required." /> | ||
| <Error Condition="!Exists('$(GeneratedBootstrapperPayloadAuthoring)')" Text="The generated bootstrapper payload authoring is missing." /> | ||
| </Target> | ||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| <!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> | ||
| <!-- SPDX-License-Identifier: Apache-2.0 --> | ||
| <Project Sdk="WixToolset.Sdk/5.0.2"> | ||
| <PropertyGroup> | ||
| <OutputType>Package</OutputType> | ||
| <InstallerPlatform>arm64</InstallerPlatform> | ||
| <OutputName>NemoClaw-$(ProductVersion)-windows-arm64</OutputName> | ||
| <OutputPath>$(PackageOutputRoot)</OutputPath> | ||
| <IntermediateOutputPath>$(PackageIntermediateRoot)\msi\</IntermediateOutputPath> | ||
| <EnableDefaultCompileItems>false</EnableDefaultCompileItems> | ||
| <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> | ||
| <DefineConstants>$(DefineConstants);ProductVersion=$(ProductVersion);PayloadRoot=$(PayloadRoot);SourceRoot=$(SourceRoot)</DefineConstants> | ||
| <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||
| <!-- Locked npm graphs contain three versionless native payloads. They remain | ||
| MSI-hashed, exact-manifest-qualified, repairable files; suppress only | ||
| ICE60's optional PE version/language metadata rule. --> | ||
| <SuppressIces>ICE60</SuppressIces> | ||
| <DebugType>none</DebugType> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <Compile Include="Product.wxs" /> | ||
| <Compile Include="$(GeneratedPayloadAuthoring)" /> | ||
| </ItemGroup> | ||
| <Target Name="ValidateNemoClawPackageInputs" BeforeTargets="Build"> | ||
| <Error Condition="'$(ProductVersion)' == ''" Text="ProductVersion is required." /> | ||
| <Error Condition="'$(PayloadRoot)' == ''" Text="PayloadRoot is required." /> | ||
| <Error Condition="'$(SourceRoot)' == ''" Text="SourceRoot is required." /> | ||
| <Error Condition="'$(GeneratedPayloadAuthoring)' == ''" Text="GeneratedPayloadAuthoring is required." /> | ||
| <Error Condition="!Exists('$(GeneratedPayloadAuthoring)')" Text="The grouped payload authoring is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\openshell.exe')" Text="The ARM64 openshell.exe payload is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\openshell-gateway.exe')" Text="The ARM64 openshell-gateway.exe payload is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\node.exe')" Text="The ARM64 Node.js runtime is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\NemoClaw.exe')" Text="The ARM64 NemoClaw launcher is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\bin\nemoclaw.cmd')" Text="The NemoClaw launcher is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\nemoclaw\app\bin\nemoclaw.js')" Text="The NemoClaw CLI package is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\openclaw\node_modules\openclaw\openclaw.mjs')" Text="The OpenClaw runtime package is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\pi\node_modules\@earendil-works\pi-coding-agent\dist\cli.js')" Text="The Pi runtime package is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\python\python.exe')" Text="The native ARM64 Python runtime is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\hermes\site-packages\hermes_cli\main.py')" Text="The Hermes Agent runtime is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\deepagents\site-packages\deepagents_code\main.py')" Text="The Deep Agents Code runtime is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\nemocua\run_with_harness.py')" Text="The experimental NemoCUA runtime is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\onboarding\index.html')" Text="The NemoClaw graphical onboarder is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\mxc\wxc-exec.exe')" Text="The MXC executor is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\mxc\wxc-host-prep.exe')" Text="The MXC host preparation utility is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\config\mxc-gateway.toml')" Text="The OpenShell MXC gateway configuration is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\qualification\run-installed-native-turn.mts')" Text="The installed native turn qualification entrypoint is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\qualification\run-installed-native-web-ui.mts')" Text="The installed native web UI entrypoint is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\qualification\run-installed-native-console-agent.mts')" Text="The configured native terminal-agent entrypoint is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\qualification\run-installed-native-pi.mts')" Text="The installed native Pi entrypoint is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\qualification\run-installed-native-nemocua.mts')" Text="The installed native NemoCUA entrypoint is missing." /> | ||
| <Error Condition="!Exists('$(PayloadRoot)\agent-support.json')" Text="The native Windows agent support catalog is missing." /> | ||
| <Error Condition="!Exists('$(SourceRoot)\packaging\windows\assets\NemoClaw.ico')" Text="The NemoClaw product icon is missing." /> | ||
| </Target> | ||
| </Project> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| <!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> | ||
| <!-- SPDX-License-Identifier: Apache-2.0 --> | ||
| <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> | ||
| <Package | ||
| Name="NemoClaw Runtime" | ||
| Manufacturer="NVIDIA Corporation" | ||
| Version="$(var.ProductVersion)" | ||
| UpgradeCode="52718EC2-AD6D-4A84-9FBF-3D73C9B11864" | ||
| Language="1033" | ||
| Scope="perMachine" | ||
| InstallerVersion="500" | ||
| Compressed="yes"> | ||
|
|
||
| <SummaryInformation | ||
| Description="NemoClaw native Windows ARM64 preview" | ||
| Manufacturer="NVIDIA Corporation" /> | ||
| <MajorUpgrade | ||
| Schedule="afterInstallInitialize" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P1] Qualify rollback after the old product is removed
|
||
| DowngradeErrorMessage="A newer NemoClaw native Windows candidate is already installed." /> | ||
| <MediaTemplate EmbedCab="yes" CompressionLevel="high" /> | ||
|
|
||
| <Property Id="ARPCOMMENTS" Value="NemoClaw native Windows ARM64 preview with pinned OpenShell, MXC, Node.js, and OpenClaw runtime. Host qualification and production activation remain required." /> | ||
| <Property Id="ARPCONTACT" Value="NVIDIA Corporation" /> | ||
| <Property Id="ARPURLINFOABOUT" Value="https://github.com/NVIDIA/NemoClaw" /> | ||
| <Property Id="ARPPRODUCTICON" Value="NemoClawIcon" /> | ||
| <Icon Id="NemoClawIcon" SourceFile="$(var.SourceRoot)\packaging\windows\assets\NemoClaw.ico" /> | ||
|
|
||
| <StandardDirectory Id="ProgramFiles6432Folder"> | ||
| <Directory Id="NvidiaFolder" Name="NVIDIA"> | ||
| <Directory Id="INSTALLFOLDER" Name="NemoClaw"> | ||
| <Directory Id="BinFolder" Name="bin"> | ||
| <Component Id="MachinePathComponent" Guid="4A428913-FB6B-4710-9573-5CCF0E3E4686" Bitness="always64"> | ||
| <RegistryValue | ||
| Root="HKLM" | ||
| Key="Software\NVIDIA Corporation\NemoClaw Native Windows Candidate" | ||
| Name="InstallBin" | ||
| Type="string" | ||
| Value="[BinFolder]" | ||
| KeyPath="yes" /> | ||
| <Environment | ||
| Id="NemoClawMachinePath" | ||
| Name="PATH" | ||
| Action="set" | ||
| Part="last" | ||
| System="yes" | ||
| Permanent="no" | ||
| Value="[BinFolder]" /> | ||
| </Component> | ||
| </Directory> | ||
| </Directory> | ||
| </Directory> | ||
| </StandardDirectory> | ||
|
|
||
| <Feature Id="Complete" Title="NemoClaw" Level="1"> | ||
| <ComponentGroupRef Id="PayloadComponents" /> | ||
| <ComponentRef Id="MachinePathComponent" /> | ||
| </Feature> | ||
| </Package> | ||
| </Wix> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[P1] Keep the previous MSI inside rollback protection
A bare
MajorUpgradeuses WiX'safterInstallValidatedefault, which removes the related product before the new install transaction is initialized. If the replacement then fails (for example while publishing files or PATH/ARP state), rollback cannot restore the removed version and the host is left with neither installation. This contradicts the advertised upgrade/rollback contract. Schedule removal atafterInstallInitializeor a later component-rule-safe point, and qualify a forced upgrade failure after removal has begun.