cmux-tui: a fresh Cloud VM serves fs-v1 (Cloud first send, Move to Cloud)
Leo, 2026-10-30: "can you guys just do it", "like the initial 0 to 1 chat auto it sends to cloud".
Evidence: https://github.com/manaflow-ai/cmux/pull/28111#issuecomment-6538116185. On a fresh devbox VM, cmux link sync push failed with fs.unavailable ⦠fs-v1 is not served here, which breaks #28111's Cloud first send (cloud.startChat) and Move to Cloud on every new machine.
Root cause
The daemon serves fs-v1 only on a Cloud host that knows its model plane identity (CMUX_CODEROUTER_URL and CMUX_VM_ID). It looked for them only in its own environment and in ~/.config/cmux/model-plane.env. Since #11813 the image bakes a static /etc/cmux/model-plane.env (no CMUX_VM_ID, the same bytes for every machine) and create writes nothing into the guest. The daemon's unit carries neither key, and a shell only writes the per-home file from a boot env, which Freestyle never gives. So a fresh VM's daemon never had an identity.
Fix
coderouter_usage::machine_source()resolves each key from the first place that has it: the process env,~/.config/cmux/model-plane.env, the image's/etc/cmux/model-plane.env, and forCMUX_VM_IDlast the bound/etc/cmux/daemon-instance-id. The bind agent (cmux-devbox-boot, cmux-host) writes that id before it starts the daemon, and rewrites it and restarts the daemon on a clone.cloud_fs(thefs-v1gate) and the machine spend poller both use it. The root-owned image stamp is still required, so a Mac or plain host stays unchanged.- Nothing is written to the guest's home. In the live exercise, a per-home file holding only the identity keys shadowed
/etcfor the shell and broke both agents. This fix leaves the shell's model plane alone. - Cloud diagnostics (
cloud.machinesrow): the newfile_opsfield, andfs-v1listed inmissing_featureswith compatibilitylimitedon a Cloud machine whose daemon lacks it. Before this, the row saidcompatibility: current, so the app could not see the problem before the sync.
No image rebake is needed. The fix ships with the guest's cmux-tui (in-place machine update, or the next image).
Tests
- Unit:
fresh_vm_resolves_from_the_image_env_and_the_bound_id,earlier_layers_win_per_key_and_bad_bound_ids_are_ignored(coderouter_usage). - Linux journey:
a_fresh_image_vm_serves_fs_v1_from_the_baked_env_and_the_bound_id(cloud_move_journey). A daemon with only the baked env does not servefs-v1. Oncedaemon-instance-idexists it does,link sync pushsucceeds, and no per-home model-plane.env is written. - Swift:
aCloudMachineWithoutFileOpsIsReportedBeforeTheSync(CloudCLITargetTests).
Verified on a Cloud VM
On a devbox VM with the manual ~/.config/cmux/model-plane.env removed (nothing in ~/.config/cmux) and the daemon restarted:
- before, the image's build
c230bb58:identifylists nofs-v1; - after, this branch's Linux build
51b333f(the Rust at the PR head is unchanged since):identifylistsfs-v1, andcmux link sync pushof a git repo with an untracked file returnsok: true(14 files written). Still no per-home model-plane.env. The machine was paused again afterwards.
No capture: the only app change is two fields in the cloud.machines / Cloud diagnostics JSON row (AppControl+Cloud.swift); no view, layout or string changes.
Risk: the fs-v1 gate now also passes on a Cloud-stamped host whose only identity is the root-owned /etc/cmux files. Before, a user-writable per-home file was enough, so the gate is no looser than it was.
Agent session: agent session
š¤ Generated with Claude Code
![View with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v3-3x.png)
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Fixes a fresh Cloud VM's daemon never serving fs-v1, so cmux link sync push (Move to Cloud, Cloud first send) failed with fs.unavailable on every new machine.
The daemon now resolves its model plane identity (CMUX_CODEROUTER_URL and CMUX_VM_ID) from the process env, the per-home model-plane.env, the image's baked /etc/cmux/model-plane.env, and for the VM id the bound /etc/cmux/daemon-instance-id written by the bind agent before it starts the daemon. No per-home file is written, so the shell's model plane is left alone. Cloud diagnostics' machine row reports a file_ops field and lists fs-v1 as a missing feature on a Cloud machine whose daemon lacks it. The capability check now treats fs-v1 as conditional (served only on a Cloud host), so the isolated identify probe no longer requires it.