A recipe VM workspace runs on its VM's own Orca server, so a phone, the CLI or
the desktop reaching it while the VM slept dialed a server that was not there
and failed. Only the host window's click ran the recipe's resume.
- The VM wake owner (WorkspaceSleepCoordinator) tracks the VM operations it
was asked for and answers where the VM stands: a pending wake or a running
suspend outranks the stored record.
- The host holds a request that opens the workspace (worktree.activate,
defined once in shared code) until the VM is up: three minutes for the
desktop and the CLI, and for a phone only as long as still lets the relay
connect inside the phone's 30-second deadline. A VM still up keeps a sleep
on its way from suspending it; a VM asleep or suspending wakes after what is
running, joining a wake already pending. The open answers waking only when
the hold runs out, wake_failed when the wake fails, and asleep when a Sleep
asked for while it was held won; that open then wakes nothing more. Other
requests answer waking or asleep instead of dialing nothing. A Sleep asked
for during a wake keeps its place in the lifecycle queue and starts once the
wake is done. A caller that gives up stops waiting and frees its queue
place; the wake goes on.
- An open of a server the user disconnected is refused before anything wakes
its VM, and cancelled if they disconnect while it waits. A wake carries the
SSH host's user hold from when it was accepted and every Disconnect since,
so its connect never lifts a hold; the VM still resumes and its new SSH
address is saved for the user's own Connect.
- A wake re-pairs a paired VM's server. The request that waited for it is
held to its caller's pairing as of before the wake (a stale caller is
refused before it can wake anything), then to exactly the pairing revision
the resume produced (including a re-pair its SSH reconnect made), whatever
process now serves it; any other change still
refuses it. A phone link still preparing for an open survives only the
re-pair its own wake made; any other retirement, or a user Disconnect, ends
it, and a link preparing for anything else is retired at once.
- The hold lives in the desktop's environment preparation, which its own calls
and subscriptions, the phone relay and the CLI all go through. A phone open
on a link to a server whose VM is not up gets a fresh link; the old link's
requests are answered waking or asleep. Further opens join a link already
waiting on the wake. A phone link's whole open (server preparation with any
hold, grant sync and the socket) shares one deadline inside the phone's
own, for every server.
- The CLI dials a VM directly, so `orca worktree activate` asks the desktop
(runtimeEnvironment.wakeRecipeVm) to open the VM and reads the server's
pairing again; the refusals (including runtime_manually_disconnected) keep
their codes over RPC, and a host without recipe VMs answers that one RPC
with method_not_found. Hosts that do this advertise
host.recipe-vm-wake.v1.
- A workspace this host runs on a recipe VM over its SSH target wakes on this
host's own activation, through the resume's explicit connect
(wakeWorkspaceVm -> resumeVm -> connectRuntimeOwnedSshTarget). That connect
runs whenever the VM is in SSH mode, even when its recipe had no resume step,
since suspend tore down the transport.
Fixes#36923
Co-authored-by: ggbdpq <ggbdpq@gmail.com>