cloud.startChat: a composer Cloud start works on the app server's link

Merged
TE
3d ago
+115-159

A composer Cloud start (cloud.startChat) and Move to Cloud now work on the Cloud app server's link, the link every DEV and tagged build uses.

Why it was refused

#28111's review (router-review, gpt-6-astra, SHIP at 8c9971b) filed follow-up #28979: with the app-server link and no free machine, cloud.startChat created a VM and then CloudMove.connected refused it for its appLink, leaving an unused VM. That guard dates from #19627 and says the app link's socket "serves one connection, the app's own: the CLIs need another". #28111 took the follow-up's first option and refused the start before creating anything, with unavailable. On a DEV build the start card fails at once at "Set up a Cloud machine" and no machine is made (HQ capture run 41392333978, on a build of #28950 at 30a7996).

The guard's premise is not true. The app server's carrier (first-party-apps/cloud/server/src/link/carrier.rs) runs one cmux link dial per accepted connection, up to 64 at once, and CloudConnectOpResolver documents it ("each connection to it is one dial of the machine's daemon"). cmux link machine update already takes its own connection to that socket (#25396, CloudLinkSession.currentSocket). The copy (cmux link start-chat copy) and the move CLI connect the same way, so this takes #28979's other option: the app link gets its sync path, the one the legacy link already uses.

Change

  • CloudStartChat.refusal refuses only Cloud off by policy (cloud_disabled) or a signed-out account (not_signed_in), whatever the link.
  • CloudMove.connected no longer refuses an app-link machine. It reads no services, so it is now static, which lets a test call it.
  • The now unused cloud.move.linkUnsupported string goes.

There is no new logic: the machine pick, pin, keys and copy stay in cmux-tui (#29582). The only Swift change removes two refusals.

Changelog

Fixed: Starting a chat in Cloud from the composer no longer fails at once in builds that use the Cloud app server's link.

Tests

cmux-ci run --class light --script scripts/ci/package-test-lane.sh --arg=suite --arg=Packages/macOS/CmuxNext --arg=CloudStartChatAppLinkTests,CloudStartChatMachineTests

  • Red at 652186003c83 (test only, on the base code): aMachineOnTheAppLinkIsNotRefusedForItsLink ("refused for its link"), and CloudStartChat.refusal(cloudDisabled: false, signedIn: true, appServerLink: true) → "unavailable".
  • Green at the fix: see the comment below.

Observed / Not run

  • Observed: the red run above, and the prepush gate (no new violations).
  • Not run yet: an end-to-end Cloud start on a DEV build. The fleet capture (cloud-start-chat) also waits on cmux-platform#472, the dev backend's machine create.

Risk: risk:normal. This removes a refusal on a path that only the person's Send with Cloud picked can reach. On a link whose carrier dial fails, the copy fails as it does on the legacy link, and the toast offers Retry.

Agent session: agent session

šŸ¤– Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes composer Cloud start (cloud.startChat) and Move to Cloud failing at once on the Cloud app server's link, the link every DEV and tagged build uses. The start no longer refuses with unavailable before creating a machine, and CloudMove.connected no longer rejects app-link machines: the app server's carrier socket serves each connection as its own dial of the machine's daemon, so the CLIs' copy and move get their own connection beside the app's. Move to Cloud on the app link also now sends the link's owner answer (owner) instead of always none, which a current Cloud daemon refused.

  • CloudStartChat.refusal now refuses only for Cloud off by policy (cloud_disabled) or a signed-out account (not_signed_in).
  • CloudMove.connected is now static and drops its app-link guard; CloudMove.ownerAnswer reads the app link's current connect answer and sends it with no link PID.
  • Removes the unused cloud.move.linkUnsupported string and adds tests covering app-link starts, connects, and owner answers.