Skip to content

The WSL probe gives up on a cold distro, so the first run on Windows hands back a Windows shell #110

Description

@Hotragn

detectShell() in packages/runtime/src/providers/local.ts chooses between WSL and the
Windows host shell. On the genuine first run of npx -y @husk-ai/cli doctor — Windows 11
ARM64, Docker installed but stopped, Ubuntu registered and Stopped, ~/.husk moved
aside so it was a true first run — it chose the host shell:

  ✓ local    not isolated
      via Windows host shell -- WSL is installed but not responding; commands are NOT Linux
      guarded working directory -- and with no WSL, commands run in the Windows shell, not Linux

WSL was fine. Seconds later, nothing changed on the machine:

$ wsl.exe -e uname -sr
Linux 6.18.33.2-microsoft-standard-WSL2      3.315s
$ wsl.exe -e uname -sr
Linux 6.18.33.2-microsoft-standard-WSL2      0.201s
$ wsl.exe -e python3 -V
Python 3.14.4

Those are the two strings the README promises for exactly this configuration. Running
doctor again, with WSL now warm:

  ✓ local    not isolated
      via WSL2 (Ubuntu)

Same machine, same config, same command. The only variable was whether WSL had been
started yet.

Why this is the one that matters

The downgrade is reported honestly. wsl-broken says "commands are NOT Linux", doctor
never pretends otherwise, and the wording even distinguishes a broken distro from an
absent one. None of that helps, because the run that hits it is the first one, and
husk up and husk exec in that state run Windows commands. The README's headline
example — the one that prints Linux 6.18.33.2-microsoft-standard-WSL2 and
Python 3.14.4 — fails on a machine that matches its stated preconditions.

A new user cannot tell the difference between "husk decided my WSL is broken" and "husk
does not work here".

What I could not pin down

I could not force it. After wsl --shutdown, husk's exact probe succeeds well inside its
budget:

$ wsl.exe --shutdown
$ wsl.exe -l -v
  Ubuntu                 Stopped         2
$ time wsl.exe -d Ubuntu -e echo husk-wsl-ok
husk-wsl-ok
real    0m5.560s

and doctor then correctly reported via WSL2 (Ubuntu). wsl --shutdown stops the
distro but leaves the WSL service warm, so the state I hit was most likely the first WSL
use since boot, where the service and the VM come up as well. The cold npx download was
running at the same time, which will not have helped.

So: seen once, on the one run that was genuinely cold, and not reproducible by stopping
the distro alone. I would rather file it with that caveat than not file it.

The budgets

wsl.exe -l -q gets 8s
(local.ts:109)
and the marker probe gets 15s
(local.ts:154).
15s is generous against the 5.5s I measured with the service warm, and evidently not
against a cold one.
DOWNGRADE_RECHECK_MS
is 60s, so a long-running husk serve recovers by itself. A one-shot CLI invocation never
gets the chance — which is every invocation a new user makes.

Options, in the order I like them

  1. Retry the marker probe once. A cold WSL that answers the second time costs one
    extra probe on a machine that was going to be slow regardless. It also fixes the case
    where husk's own probe is what triggers the boot it then gives up waiting for.
  2. Raise the marker budget. Cheap, but it is picking a number, and it makes a
    genuinely broken distro slower to report.
  3. Do not cache a downgrade decided by a single cold probe. Closest to correct, most
    work, and it does not help the one-shot case on its own.

(1) is what the measurement points at. (1) and (3) together would mean a first run can no
longer be wrong about the thing the product is named for.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpkg: runtimeTouches packages/runtimetested with opus 5Found during an Opus 5 test pass

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions