cloud start-chat: a --name no machine has yet goes relay-first (hq#7086)

TE
8h ago
+273-52

HOLD: parked after review round 5. A named create in the CLI races a concurrent same-name create; that needs the backend create key (#36682).

Part of manaflow-ai/cmuxterm-hq#7086 (Leo: "it should take <30 seconds from starting a thing to having a response on cloud"). Lane (a)'s relay-first chat merged in #35785 and #35829, but the production probe never takes it.

What was wrong

cmux cloud start-chat --name N --wait for a name no machine has yet skipped the relay chat (relay_chat returned Fallback(None)) and went straight to start-session plus the link. The hourly probe cloud-chat-replies-production always passes a fresh --name probe-prod-…, so on NIGHTLY 42abbd2b (which has both relay PRs, as does the prod image) it still ends at "Machine … didn't connect, so no agent started there" (run https://github.com/manaflow-ai/cmuxterm-hq/actions/runs/42029887579, 56.9 s). The relay route was never tried.

The change

  • A --name no machine has is made with cloud new-machine --name N --json, then the chat goes over cloud relay-chat, like a start with no name already did.
  • When the relay certainly never delivered, the link path runs on that same machine (--target machine:ID), never a second create.
  • A create still on its way gives the same cloud.start_pending answer (exit 75, the same command again) as the link path, now one function, start_pending. A retry that sees a create of that name in flight waits on it and never makes a second machine. Once the machine is listed, the chat goes relay-first to it.
  • Only a plain name (what cloud new-machine --name takes) is made this way, and only when the list is loaded and no nameless create is on its way. Anything else keeps the link path the command took before.
  • A prompt over 96 KiB is checked after the machine is resolved, so it goes the link way on that machine.

Known limit (follow-up manaflow-ai/cmux#36682): two start-chats with the same new name at the same moment can each create a machine. cloud new-machine --name has the same race today. No data is lost; the cost is one extra machine's time until idle pause. The real fix is a backend create key scoped to the account, in cmux-platform. A key kept only in the app's action cache was tried and dropped, because it can replay a deleted machine or another account's machine.

Tests

Red commit c39700efe963 adds a_name_no_machine_has_is_made_and_its_first_chat_goes_the_relay_way and a_named_new_machine_the_relay_never_reached_goes_the_link_way_on_that_machine, and asserts the new-machine --name step in a_pending_machine_names_the_command_that_waits_on. The command is cargo test -p cmux-tui --bins cloud_start_chat through cmux-ci test. Red-at-test-commit and green-at-head results go in a comment.

Observed / Not run

  • Observed: the probe's state branch (reconciler-state/probes-app-chat-production): 13/13 failures since 04:26Z, the latest at "didn't connect". The compare API shows #35829 and #35785 are both ancestors of the NIGHTLY's commit and of the cloud-native-4171772 / 0cda689 images.
  • Not run: a real production run. The first one is the next hourly probe after a NIGHTLY carries this.

Changelog

  • Fixed: cmux cloud start-chat --name NEW --wait sends the first prompt over the relay instead of waiting for the link to a new machine.

Agent session: agent session

🤖 Generated with Claude Code