Expand description
The one Windows login task that keeps a managed WSL distribution alive, and the four operations on it: render, register, query, remove.
§What the task promises, and what it does not
WSL distributions are registered per user, so nothing that runs before
a user logs on can start one. The 2026-09-06 review closed exactly this
defect: an earlier design promised boot availability that Windows cannot
deliver. So this is a LogonTrigger task for one named principal, and
02-target-architecture.md states the consequence in the product’s own
words — “unattended Linux availability after that user’s logon, not before
any interactive logon after a Windows reboot”.
§There is no shell text in the action, at any layer
The other half of that review closed a design that composed systemctl and
a keep-alive through a shell string. The action here is
<Command>...\runner-manager-wsl-supervisor-VERSION.exe</Command>
<Arguments>...\runner-manager-wsl-VERSION.exe wsl-host supervise --distribution Ubuntu ...</Arguments>Task Scheduler has no Arguments vector — the element is a single string
that Windows splits with CommandLineToArgvW — so
LifecycleTask::action_arguments builds the vector and
LifecycleTask::rendered_arguments quotes each element with the same
function the service installer uses. A distribution called My Ubuntu is
therefore "My Ubuntu" in the document and one argument again on the way
out. What is not there is a cmd /c, a &&, a ;, or anything else a
shell would interpret, and no_shell_text_reaches_the_task_document is the
test that keeps it that way.
wsl-host supervise is the hidden Windows companion. It starts the
Linux-only wsl-host hold, restarts that child when the named distribution
is recovered, and owns the bounded recovery watchdog. Running in the
distribution owner’s interactive token is essential: an SCM service under
LocalSystem cannot see another account’s WSL registrations.
§A task this did not create is never touched
The name is derived from the distribution, so two workstations agree on it
and a re-run updates the task rather than accumulating copies. That same
determinism means the name could collide with something an operator made by
hand — and on the target workstation there is a hand-created task doing
this job today (01-current-architecture.md). So every mutating operation
reads the task back first and refuses unless its description carries
PRODUCT_MARKER. wsl detach removing somebody else’s keep-alive task
would be precisely the destructive behaviour the review renamed the command
to avoid.
Structs§
- Detached
- What
LifecycleTaskControl::detachdid, and what it deliberately did not. - Lifecycle
Task - Everything needed to render the task.
- Lifecycle
Task Control - Registering, reading and removing the product’s lifecycle task.
- Lifecycle
Task Identity - The stable, per-distribution name of the product’s lifecycle task.
- Registered
Task - What Task Scheduler says about a task that is registered.
Constants§
- HOLD_
ARGUMENTS - The hidden Linux command the task runs.
- LIFECYCLE_
TASK_ PREFIX - The prefix every product-owned lifecycle task name starts with.
- PRODUCT_
MARKER - The string that says a task is this product’s.