Cloud cap card: Pause frees a slot (CloudDO pause on the app-server link; classic Pause only where it frees room)
Leo, on a Cloud create past the plan's machine cap: "you try to create a new workspace/machine past the cap, what do we wanna do? reuse exisitng or ask upgrade or". The card #32679 shipped (Pause one / Upgrade / Run on This Mac) has two gaps; this fixes both. Fixes #32708, fixes #32710.
#32708, app-server link. The cap card's Pause, and the sidebar's Pause and Resume, called the classic /api/vm/{id}/pause, which cannot pause a CloudDO machine. On the app-server link CloudService.pauseMachine / resumeMachine now send cloud.machine.pause / cloud.machine.start through the app server (CloudMachinePower, CmuxNextCloud). CloudDO already answers a person's pause only once the provider call landed (CloudCore submitAs, its 25 s wait), so the slot is free when the card's create goes again. A pause longer than that wait answers mutation.indeterminate; it is asked again with the same key (it joins the call in flight), at most 3 times. No backend change is needed: the Mac relay's install may pause without an approval (cmux-platform domain/Cloud.ts authorize), and the Rust app server already declares mutation.indeterminate for pause.
#32710, classic link. The classic allowance counts paused machines (web/services/vms/repository.ts activeLimitExceededInTx, LIVE_VM_RESOURCE_STATUSES), so a Pause there frees nothing. The classic card now offers Pause only for the shared vCPU/memory pool refusal (vm_resource_pool_exceeded, activePoolUsage counts provisioning and running only), mapped to a new CloudUpgradeReason.pool; the allowance refusal and the local plan gate keep Upgrade and Run on This Mac. Classic's backend is untouched.
CmuxNextApp lines do not rise (in-place edits only).
Tests: CloudMachineCapTests (the classic card offers Pause only where pausing frees room; the app-server pause sends cloud.machine.pause with one key and origin user, retries indeterminate up to 3 calls, stops at once on any other error), CloudCreateWithoutAskingTests (a 402 vm_resource_pool_exceeded throws .pool).
Design: leo-workspace design/cloud.md, "At the machine cap".
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes two gaps in the Cloud cap card's Pause so that pausing actually frees a slot before the create retries (cmux#32708, cmux#32710).
Bug Fixes
- On the app-server link, Pause and Resume now send
cloud.machine.pause/cloud.machine.startthrough the app server, since the classic/api/vmcannot pause a CloudDO machine. - CloudDO answers once the provider call lands, so the slot is free on retry; a pause longer than CloudDO's wait answers
mutation.indeterminateand is retried with the same key, up to 3 times. - On the classic link, Pause is now offered only for the vCPU/memory pool refusal (
vm_resource_pool_exceeded), which counts running machines alone; the allowance counts paused machines, so its refusal keeps Upgrade and Run on This Mac. - No backend changes are needed.