Cloud: a machine's creator can start chats on it from the app, team machines included

TE
5d ago
+48-24

Leo, 2026-10-31, on a chat on his own Cloud machine refused with "Agent chats cannot be started from this Mac on a team VM yet.": "let's do option 1" / "but what's the sharing flow? we can't simply block always. we need to be able to get stuff running asap."

Why

In the DEV build on production, Leo picked his own machine (fs-firstsend-exercise, which he created) and sent a chat. It was refused with agent_session.team_vm_blocked. Every machine on his account sits on a Stack team, so cmux-host writes team to /etc/cmux/vm-kind. cmux-tui's start gate refused a team record before it read the caller's word.

The caller's word is already right. Since #28788 (main) and #28789, the Cloud API's attach answer is vmKind: "owner" only for the machine's creator, team machines included. Every other teammate gets team. The app sends vm_kind: "owner" per start only on that answer (#26323). The guest's team record was the only thing still blocking.

What changes

AgentSessionStarts::host_gate (cmux-tui-core): a team VM now lets a call through on the caller's vm_kind: "owner", the same as any other Cloud VM. The same gate guards three calls: agent-session-start, agent-session-trust and the chat move-in (agent-transfer-receive/-finish).

What still refuses:

  • On a team VM, a caller without the owner word (a teammate, or no word at all) still gets agent_session.team_vm_blocked.
  • On any other Cloud VM, a caller without the owner word still gets agent_session.host_unverified.
  • A word other than owner is still refused on any host.
  • The guest's own records still never allow a call by themselves.

No new capability: the param and its meaning are unchanged; only the team record no longer overrides it. The app bundles and pushes its own cmux-tui to the VM, so the next DEV or nightly build carries this. Nothing to deploy.

Risk: the creator's own chat on a team machine now runs there. The VM boundary (unsandboxed at the VM) already followed that same owner answer (#28788), so this adds nothing new on that axis. Teammates, the shared case #26323 protects, still can't start chats there; that goes to the grant flow (a later PR: "Share machine…", with grants in the attach answer).

Prior art: #26323 (the boundary), #26330, #28479 and #28788 (the owner answer for the creator on a team), #28613 (open, Codex on owner VMs; it doesn't touch host_gate's team arm).

Which link

The app's default link is classic (CloudConfiguration.linkSource = .legacy: /api/vm/{id}/attach-endpoint, web deployed from main), and there #28788 answers owner to the creator. That is Leo's DEV build, so this PR is all his case needs. The app-server link (CMUX_NEXT_CLOUD_LINK=app, cmux-api callerVmKind) still answers team to a shared-team creator until #28789 (open, another lane) lands. Until then that path stays refused, as it is today.

Review: router-review SHIP at 8ec04cd4 (gpt-6.1-sol). Its one follow-up (P1) is the app-server link above, which #28789 covers.

Tests

  • a_call_on_a_cloud_vm_needs_the_callers_owner_word (unit): a team VM with the owner word goes on; without it, it is refused.
  • a_cloud_vm_start_needs_the_callers_owner_word_not_the_vms_record (CLI, real daemon with a team record): owner gets past the host gate (next comes untrusted_folder); no word and team give team_vm_blocked.
  • agent_session_trust_on_a_cloud_vm_needs_the_callers_owner_word: the same on a team VM for trust.
  • Linux fleet (cmux-ci test --setup rust, job 1382a4dc7688347c089972e8, at 8ec04cd4): cargo fmt --check; core agent_session_start (1) and agent_transfer (48); CLI agent_session_st* (37) and agent_session_trust (2). All pass.

No UI change.

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

Allows a machine's creator to start chats on their own team Cloud VM from the app; previously the start gate refused it with agent_session.team_vm_blocked even when the caller sent the correct vm_kind: "owner" word.

  • The host gate for agent-session-start, agent-session-trust, and chat move-in now honors the caller's vm_kind: "owner" on team VMs, matching the Cloud API's per-caller answer that grants owner to the machine's creator only.
  • Teammates and callers without the owner word are still refused: agent_session.team_vm_blocked on team VMs, agent_session.host_unverified on other Cloud VMs.
  • No capability change or deploy needed; the next DEV or nightly build carries the fix.