Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat(windows): add uninstall.ps1 and rewrite Windows documentation
Windows no longer ships an application: the ordinary Linux build runs inside
a WSL 2 distribution named "1helm" and the browser is the interface at
http://localhost:8123. Nothing is code-signed because nothing is shipped, so
SmartScreen never appears. The documentation still described a Setup
executable, a Squirrel feed, an Authenticode disclosure and %APPDATA% data
roots, none of which exist.

Add site/public/uninstall.ps1, the only supported way off Windows. In order:
stop the keepalive (via its own keepalive-remove.ps1 when present, otherwise
unregistering \1Helm\ directly), run /opt/1helm/uninstall-host.sh inside the
distribution so 1Helm removes its own ownership-checked containers and units
while it still can, then terminate and unregister the distribution, then
delete C:\1helm and the Start Menu entry.

Because `wsl --unregister` deletes the virtual disk holding every channel's
files, the database and the provider credentials, it requires typed
confirmation stating exactly what is lost; -Force exists for scripted use.
It refuses to run as SYSTEM, whose per-user WSL state is not the user's. It
never calls `wsl --shutdown`, which would stop every distribution for every
user on the machine, and both the targeted terminate and the unregister sit
behind the keepalive's protective pattern plus an exact, case-sensitive match
against a currently registered distribution. Every step is idempotent and the
run ends by reporting what was removed and what was not.

Documentation now matches the verified flow at the altitude a first-time user
needs: one command, one permission pop-up, a deliberate "Restart required"
stop, the same command again, then the browser. It also names the things that
look like failures and are not - Microsoft's own "Welcome to WSL" window, the
~40s the channel-computer runtime needs after install, the ExecutionPolicy
wall that only appears when the script is downloaded rather than piped - and
records that #main's terminal is now bash inside WSL, not cmd.exe.

test/site.mjs asserted the retired contract: that getting-started tells
Windows users to download a Setup executable and discloses `NotSigned`. Both
now assert the opposite, because SmartScreen and Authenticode cannot apply to
a product that ships no .exe and repeating them would send people looking for
a file that does not exist. New assertions cover /uninstall.ps1 being served,
the Windows guide carrying the whole two-phase flow, and the uninstaller's
safety guards.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
  • Loading branch information
claude committed Aug 2, 2026
commit b2bd3ae51a7a8d8b3ea085dcbce322ecd990621b
139 changes: 95 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<p align="center">
<a href="https://1helm.com/download/macos"><strong>Download for Mac</strong></a>
&nbsp;·&nbsp;
<a href="https://1helm.com/download/windows"><strong>for Windows</strong></a>
<a href="https://1helm.com/manual/install-windows"><strong>for Windows</strong></a>
&nbsp;·&nbsp;
<a href="https://1helm.com/manual/install-linux"><strong>for Linux</strong></a>
&nbsp;·&nbsp;
Expand Down Expand Up @@ -130,30 +130,74 @@ device displaying the web UI—to download and verify the signed update.

### Windows 11 x64

1. [Download the current Setup executable](https://1helm.com/download/windows).
2. Windows Setup is **not yet Authenticode signed**, so SmartScreen shows
"Windows protected your PC". Choose **More info** → **Run anyway**.
3. Open 1Helm and complete Captain → Providers → Workspace.
4. At the Workspace step, 1Helm builds its WSL 2 runtime. **You do not need WSL
installed beforehand.** A stock Windows 11 ships with WSL and
VirtualMachinePlatform turned off, and 1Helm enables both itself:
- Approve the one administrator (UAC) prompt.
- A PowerShell window opens and reports progress. **Leave it open** until it
finishes.
- Because those Windows features were just turned on, **Windows has to
restart once.** 1Helm says so in plain language. This is the normal path
on a new PC — it is not an error, and nothing is lost.
- Restart, sign back in as the **same** Windows user, then open 1Helm and
continue setup. It picks up where it left off; already-completed steps are
skipped.

Setup downloads Microsoft's pinned WSL 2 package and a pinned Ubuntu 24.04 root
filesystem, both SHA-256 verified, and the WSL package is additionally checked
for a valid Microsoft Authenticode signature. The result is one
installation-scoped WSL 2 runtime hosting one durable OCI container per ordinary
channel, with Windows-drive mounts and process interop disabled. App state lives
in `%APPDATA%\1Helm-OCI-v1`; the shared runtime disk lives in
`%LOCALAPPDATA%\1Helm-Runtime`.
There is nothing to download and no Windows application to install. 1Helm runs
its ordinary **Linux** build inside a WSL 2 distribution named `1helm`, and your
**browser is the interface**, at `http://localhost:8123`. Because no `.exe`
ships, nothing needs code signing and **SmartScreen never appears**.

You need: Windows 11 **x64** (arm64 is not supported), virtualization enabled in
firmware, internet access, and roughly 10 GB of free disk. **You do not need to
install WSL first** — this does it for you.

1. Open **PowerShell**. The normal one — do **not** use "Run as
Administrator".

2. Run exactly this:

```powershell
irm https://1helm.com/install.ps1 | iex
```

3. A Windows permission pop-up appears. Click **Yes**. That one approval covers
only turning on Windows' WSL features and installing Microsoft's own WSL
package; everything after it deliberately runs as you, because WSL state
belongs to the signed-in user.

4. Wait about a minute. The window finishes by printing **"Restart required"**
and a short numbered list. **This is normal — it is not an error and nothing
is lost.**

5. Restart the PC.

6. Sign back in as the **same** Windows user and open PowerShell again.

7. Run the **identical command** a second time:

```powershell
irm https://1helm.com/install.ps1 | iex
```

8. Wait about six and a half minutes. Pages of `apt` output scroll past — that
is normal progress. When it is done it prints the address and opens your
default browser on the onboarding page.

9. Complete Captain → Providers → Workspace in the browser.

The whole thing takes about **9 minutes**, restart included.

Two things you may see along the way:

- Microsoft's own **"Welcome to WSL"** window may open during step 8. It belongs
to Microsoft, it is harmless, and you can close it.
- After 1Helm reports that it is running, the channel-computer runtime needs
roughly another **40 seconds** to finish preparing before your first channel
computer can be created. It has not hung.

If you *download* `install.ps1` instead of piping it, Windows blocks running
`.ps1` files and you must run it as
`powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1`. The
`irm | iex` form above is unaffected, because it pipes a string rather than
executing a file.

One behaviour difference from earlier versions: **`#main`'s Terminal is now bash
inside the WSL distribution, not `cmd.exe`.** Windows commands do not work
there. That is deliberate — the host is Linux now.

To remove it later, from the same ordinary PowerShell window:

```powershell
irm https://1helm.com/uninstall.ps1 | iex
```

### Linux (Ubuntu/Debian, systemd)

Expand All @@ -178,20 +222,26 @@ machines for safe deletion. Export irreplaceable channel files before you start.

- **macOS** — drag 1Helm to the Trash. `~/Library/Application Support/1Helm-OCI-v1`
is preserved unless you delete it yourself.
- **Windows** — uninstall from Settings → Apps → Installed apps. The uninstaller
removes 1Helm's own containers, unregisters its WSL runtime, and deletes
`%LOCALAPPDATA%\1Helm-Runtime`.
- **Windows** — from an ordinary PowerShell window, run
`irm https://1helm.com/uninstall.ps1 | iex`. It stops the keepalive, runs
1Helm's own Linux uninstaller inside the distribution, then unregisters the
`1helm` distribution and deletes `C:\1helm` and the Start Menu shortcut. It
asks you to type `remove` first, because unregistering the distribution
**destroys every channel's files and the database** — there is no undo and no
copy is kept. Other WSL distributions on the PC are never touched.
- **Linux** — `sudo /opt/1helm/uninstall-host.sh` removes the services, helper,
and 1Helm-owned containers while preserving `/var/lib/1helm-oci-v1` for
recovery.

### Release discipline

Mac, Linux, and Windows use one synchronized desktop release version. A release
is held in full until the signed/notarized Mac DMG and updater ZIP, verified
Linux host archive, and Windows Setup/Squirrel feed have all passed native
install and update acceptance from the same source commit. Windows
Authenticode status is disclosed in every release; v0.0.38 is `NotSigned`.
Mac and Linux use one synchronized desktop release version, and a release is
held in full until all three artifacts — the signed/notarized Mac DMG, the
notarized Mac updater ZIP, and the verified Linux host archive — have passed
native install and update acceptance from the same source commit. Windows ships
no release artifacts at all: it installs the Linux build through
`install.ps1`, served from the site, so there is nothing to sign and no
Authenticode status to disclose.

### Connect from a phone or tablet

Expand Down Expand Up @@ -324,9 +374,9 @@ and an audit trail. A prompt saying “use this service” is not a connector.
SHA-256 chain for new operational events.
- Local-first collaboration through an optional workspace domain routed to the
Captain's helm host; workspace state and provider credentials remain there.
- Host-owned updates: a signed native Mac updater, a Windows Squirrel feed with
disclosed Authenticode status, and an atomic digest-verified Linux system
service with health-check rollback.
- Host-owned updates: a signed native Mac updater, and an atomic digest-verified
Linux system service with health-check rollback — which is also how a Windows
host updates, because Windows runs that same Linux service inside WSL.
- Signed, Apple-notarized, stapled Apple Silicon DMG releases.
- Browser access from phones and tablets to an already configured HTTPS 1Helm
host; native mobile gateway source is present but has no v0.0.38 public build.
Expand All @@ -337,7 +387,7 @@ and an audit trail. A prompt saying “use this service” is not a connector.
|---|---|
| **Apple Silicon macOS 26** | Native desktop product and real isolated Linux computer per resident (Apple `container machine`, `home-mount=none`). |
| **Linux / CI** | Supported headless systemd host with one durable Podman OCI container per resident, runtime-owned storage, and exact ownership checks; CI may select an explicit test backend. |
| **Windows 11 x64** | Native desktop product with one installation-scoped WSL 2 OCI runtime and one durable container per resident; Windows-drive mounts and interop are disabled. |
| **Windows 11 x64** | The Linux host, installed by `install.ps1` into a WSL 2 distribution named `1helm`, with the browser as the interface at `http://localhost:8123`. One durable Podman OCI container per resident, exactly as on Linux. No Windows application ships. |
| **iPhone, iPad, and Android** | Use the current HTTPS browser interface. Native gateway source exists, but v0.0.38 has no public mobile artifact and the iOS app is not publicly listed. |

Not yet shipped: current public mobile builds, a native Linux desktop shell, a
Expand Down Expand Up @@ -383,17 +433,18 @@ npm run helm -- audit-verify

## Architecture

1Helm is a compact Node/TypeScript control plane hosted by Electron on macOS
and in the accepted Windows implementation, or by systemd on Linux. It does not
need an external database or a server transpilation step.
1Helm is a compact Node/TypeScript control plane hosted by Electron on macOS, or
by systemd on Linux — including the Linux inside a Windows host's WSL 2
distribution. It does not need an external database or a server transpilation
step.

| Layer | Implementation |
|---|---|
| Runtime | Official Node 22 with native TypeScript stripping. |
| Control plane | `node:http`, WebSocket, additive SQLite migrations. |
| Client | Vanilla TypeScript bundled with esbuild and Tailwind CSS. |
| Model routing | Embedded ReRouted headless engine, private internal gateway, account pools, retries, routes, quotas, and logs. |
| Computers | Defensive argv-only Apple `container machine`; native Podman OCI on Linux; one shared managed WSL 2/Podman runtime on Windows; explicit `native`/`mock` test seams. |
| Computers | Defensive argv-only Apple `container machine`; native Podman OCI on Linux, including inside a Windows host's WSL 2 distribution; explicit `native`/`mock` test seams. |
| Terminal | `node-pty`; ordinary terminals enter their channel VM while Skipper remains native. |
| Memory | Curated records with provenance plus an isolated Mnemosyne SQLite store per identity. |
| Scheduling | Durable obligations, wake reconciliation, lifecycle safety, repair, update, and pressure-aware sizing. |
Expand Down Expand Up @@ -430,9 +481,9 @@ the complete `npm test` contract.

## Security boundary

- Residents use separate Linux worlds: Apple machines with no Mac home mount,
or durable OCI containers on Linux and inside Windows' one shared managed
WSL runtime. Windows-drive mounts and interop are disabled.
- Residents use separate Linux worlds: Apple machines with no Mac home mount, or
durable OCI containers on Linux — including the Linux inside a Windows host's
WSL 2 distribution.
- Skipper's host tools require Captain-authorized provenance.
- OCI workspace storage is runtime-owned and authoritative; Files and Cowork
access it directly through a channel-scoped boundary. Apple mirrors remain
Expand Down
106 changes: 70 additions & 36 deletions docs/USER_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,15 @@ longer exists, 1Helm opens a fresh one.
Ordinary residents cannot select or enter the Captain's native host. On
supported Apple Silicon Macs, each resident runs inside its own Apple
`container machine` with `home-mount=none`; Linux systemd hosts use one durable
Podman OCI container per resident; Windows uses one installation-scoped WSL 2
runtime hosting one container per resident, with Windows-drive mounts and
interop disabled. `native` and `mock` remain explicit source/CI test seams.
Podman OCI container per resident. A Windows host is that same Linux host,
running inside a WSL 2 distribution named `1helm`, so its residents get the
identical Podman OCI containers. `native` and `mock` remain explicit source/CI
test seams.

On Windows, `#main`'s Terminal is therefore **bash inside that WSL
distribution, not `cmd.exe`** — Windows commands do not work there. This is a
deliberate change from earlier versions, where the Windows host was a native
application and Skipper's terminal was the Windows shell.

![The full-height channel Terminal in its persistent workspace](assets/guide/terminal.png)

Expand Down Expand Up @@ -385,21 +391,36 @@ Every host update preserves:
```text
macOS: ~/Library/Application Support/1Helm-OCI-v1
Linux: /var/lib/1helm-oci-v1
Windows: %APPDATA%\1Helm-OCI-v1 (plus %LOCALAPPDATA%\1Helm-Runtime)
Windows: /var/lib/1helm-oci-v1, inside the "1helm" WSL 2 distribution
```

On macOS that directory contains databases, credentials, workspaces, resident
state, and Apple mirrors. Linux and Windows preserve the equivalent
OCI-generation state; on Windows the shared WSL runtime disk lives separately
under `%LOCALAPPDATA%\1Helm-Runtime`. The retired data roots remain untouched
and are not imported by this generation. Do not delete a current data root
during replacement.
state, and Apple mirrors. Linux preserves the equivalent OCI-generation state.
A Windows host has **no data under `%APPDATA%`**: it runs the Linux host inside
WSL, so the same `/var/lib/1helm-oci-v1` is the data root and it lives on that
distribution's virtual disk under `C:\1helm\distro`. Reach it from PowerShell
with `wsl -d 1helm -u root --exec ls /var/lib/1helm-oci-v1`; it is root-owned
inside the distribution, exactly as on any other Linux host. The
retired data roots remain untouched and are not imported by this generation. Do
not delete a current data root during replacement, and do not unregister the
`1helm` distribution unless you intend to destroy everything on it.

Before removing 1Helm, use its removal preparation flow. It is Captain-only,
requires typed confirmation, reports backend-owned resident machines, and
prepares those machines for safe deletion. Export or back up irreplaceable
channel files first.

Then, per host: on macOS drag the app to the Trash; on Linux run
`sudo /opt/1helm/uninstall-host.sh`; on Windows run
`irm https://1helm.com/uninstall.ps1 | iex` from an ordinary PowerShell window,
signed in as the user who installed it. macOS and Linux deliberately leave the
data root in place for recovery. **Windows does not**, and cannot: it unregisters
the `1helm` distribution, which deletes the virtual disk the entire data root
lives on. It therefore asks you to type `remove` before it starts, states exactly
what will be lost, and takes `-Force` only for scripted removal. Other WSL
distributions on the PC are never touched, and Windows' own WSL feature is left
installed.

Recovery principles:

- restore an archived channel rather than recreating it;
Expand All @@ -414,29 +435,40 @@ Recovery principles:

### First run and installation

**Windows asks me to restart in the middle of setup.** That is the expected
path on a normal Windows 11 PC. WSL and VirtualMachinePlatform ship disabled;
1Helm turns them on for you, and Windows cannot use them until it restarts.
Restart, sign back in as the same Windows user, open 1Helm, and continue —
completed steps are skipped. Nothing is lost and nothing else is required.

**Windows says "Windows protected your PC" when I run Setup.** Windows Setup is
not yet Authenticode signed, so SmartScreen warns about it. Choose **More info**
→ **Run anyway**. Every release discloses its Authenticode status; v0.0.38 is
`NotSigned`. Only run an installer you downloaded from
[1helm.com](https://1helm.com/download/windows) or the project's GitHub
releases.

**A PowerShell window opened during Windows setup.** That window is the setup
itself and shows live progress. Leave it open until it finishes; closing it
early aborts the step. 1Helm mirrors the same progress in the app and writes a
log to `%APPDATA%\1Helm-OCI-v1\windows-wsl-setup.log`.

**Windows setup failed or stalled.** Check the PowerShell window for the error,
then use **Retry shared runtime setup** in onboarding or Settings → Channel
computers. Setup is idempotent — retrying resumes rather than starting over.
The runtime requires Windows 11 **x64**; arm64 Windows is not supported by this
build.
**Windows printed "Restart required" and stopped.** That is the expected halfway
point of a Windows install, not a failure. WSL and VirtualMachinePlatform ship
disabled; the installer turns them on for you, and Windows cannot use them until
it restarts. Restart, sign back in as the same Windows user, open PowerShell, and
run the **same command again** — it continues from where it stopped and skips
what is already done. Nothing is lost. The whole install, restart included, took
about 8 minutes 49 seconds on a real Windows 11 machine.

**Windows refuses to run install.ps1.** You downloaded the script instead of
piping it, and Windows blocks running `.ps1` files. Use
`powershell -NoProfile -ExecutionPolicy Bypass -File .\install.ps1`. The
`irm https://1helm.com/install.ps1 | iex` one-liner is unaffected, because it
pipes a string into PowerShell rather than executing a file.

**A "Welcome to WSL" window opened during the Windows install.** That window is
Microsoft's, not 1Helm's. It is harmless; close it and let the install continue.

**Windows says nothing is listening on `http://localhost:8123`.** After the
installer reports 1Helm is running, the channel-computer runtime needs roughly
another 40 seconds to finish preparing before the first channel computer can be
created — it has not hung. If the address itself stays unavailable, ask the
service inside the distribution:
`wsl -d 1helm -u root --exec systemctl status 1helm`.

**Windows says port 8123 is already in use.** Windows and every WSL distribution
share one network namespace, so another distribution or an ordinary Windows
process listening on 8123 stops 1Helm binding it. The installer refuses to
continue rather than half-install, and names the port. Stop whatever owns it and
run the command again.

**The Windows install stopped for another reason.** Every step is idempotent:
read the reason it printed, fix it, and run the same command again — it resumes
rather than starting over. It requires Windows 11 **x64**; arm64 Windows is not
supported by this build.

**macOS blocks the app or reports it is damaged.** The Mac release is Developer
ID signed, notarized, and stapled, so Gatekeeper should accept it after you
Expand Down Expand Up @@ -484,8 +516,8 @@ fallback.
## Security summary

- Per-resident Apple Linux VMs have no Mac home mount. OCI residents use exact
container labels and runtime-owned storage; the shared Windows runtime
disables Windows-drive mounts and interop.
container labels and runtime-owned storage, including inside a Windows host's
WSL 2 distribution.
- Credentials and connectors remain host-owned and minimally brokered.
- Membership scopes data and live events; private coworker channels are not
Captain-readable without invitation.
Expand All @@ -494,8 +526,10 @@ fallback.
- External skills are revision-pinned, bounded, scanned, hashed, and wrapped.
- Operational history is locally tamper-evident.
- Mac artifacts are Developer ID signed, notarized, stapled, and Gatekeeper
verified. Linux assets are digest-verified, and Windows Authenticode status
is disclosed for every release (`NotSigned` for v0.0.38).
verified, and Linux assets are digest-verified. Windows ships no artifact of
its own; its installer verifies Microsoft's WSL package against a pinned
SHA-256 and a valid Microsoft Authenticode signature, and the pinned Ubuntu
root filesystem against its SHA-256.

For the detailed boundary, see [SECURITY.md](../SECURITY.md). For product intent,
see [VISION.md](VISION.md).
Loading