Skip to content

Chief: use the user's Cloud machines, and offer cmux Pro when a create needs it - #23952

Merged
austinywang merged 51 commits into
feat-cmux-nextfrom
feat-cmux-next-chief-cloud-vms
Oct 28, 2026
Merged

austinywang merged 51 commits into
feat-cmux-nextfrom
feat-cmux-next-chief-cloud-vms

Conversation

@austinywang

@austinywang austinywang commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Chief can use the user's cmux Cloud machines from the Mac through the cmux CLI, the app shows a machine's desktop over its own Cloud tunnel, and the tunnel only serves cmux's own processes.

Size: one integration PR by request (the Chief skill, Pro gating, the hub token and Open Desktop share the Cloud tunnel and land together); most of the diff is tests, localization and the design note.

  • Chief and Cloud machines. A shipped chief-cloud-machines skill (and one prompt line): list machines (cmux cloud list-machines), create one (cmux cloud new-machine, the Create card still asks the person), run commands and the machine's own cmux (cmux cloud exec), and drive its Linux desktop with cua-driver, pulling screenshots back with cloud file-read. The skill forbids building tunnels, bridges or local ports, and says older notes that do are out of date.
  • cmux Pro. A create refusal that names cmux Pro (upgradeRequired on /api/vm, or the app server's plan_required) is a typed CloudAPIError.planRequired, and the person sees one "Cloud machines need cmux Pro" dialog whoever asked (click, CLI, Chief).
  • Open Desktop (cmux cloud open-desktop --target machine:<id>, palette and the machine menu's Connection submenu): the machine's noVNC page in a Chromium tab at http://<machine>.cloud-desktop.localhost:6901/…. RemoteLocalhostProxy (peer-checked) routes that address by its URL to the machine's private address over the app's WireGuard hub, so no port opens on this Mac; the shim store guard reroutes a desktop URL typed into another tab, and WebKit refuses one.
  • Tunnel hardening (VPN parity, plans/cmux-next/cloud-tunnel-protection.md). wg hub --client-token-stdin serves only SOCKS5 clients that present a per-launch token (RFC 1929, constant-time compare); link sidecars get it on stdin (remote connect --wireguard-hub-token-stdin). The hub's config (--config -) and the WireGuard key never touch disk: the key is made per app launch and held in memory, each start enrolls its public key and the server rotates the device's peer. Found live: a Chief subagent had copied the key file into a second hub and a 127.0.0.1:16901 bridge; the two hubs knocked each other off and the desktop's mouse froze. Classic's cmux vpn up Network Extension is not ported (a product decision; see the note). The one tokenless lane is port 22, for base's cmux wg dial ssh route (cloud enroll-machine).
  • Development-build viewers (the remote view pane is DEBUG-only): --viewer native, the app's VNC client over RFB-in-WebSocket (WebSocketRFBTransport) on the same tunnel; --viewer rd, Lawrence's cmux-rd host (H.264 via Cisco's OpenH264, XTest input) over the machine's daemon link (loopback-forward-v1). The rd host is not in the VM image yet.

Testing

  • Fleet Swift suites at 5777e8c (step 23952-cloud-5777e8c1, all 9 green): CloudHubLoopbackTests, CloudLinkReconnectingTests, CloudAPIClientPlanRequiredTests, CloudCreationProOfferTests, CloudCLITargetTests, ActionSurfaceParityTests, ActionSurfaceExportTests, RemoteViewTabPolicyTests, RemoteViewVNCTests. CmuxVNC WebSocketTransportTests and EndToEndTests green (step d0261167).
  • Rust on rbx at 6a36de6: cmux-remote wireguard_hub_e2e 3/3 (a tokenless and a forged client are refused at the real hub), socks 4/4, cmux-tui hub/stdin flags 6/6, optchat-chief all green.
  • Dev build 23952-chief-cloud-machines (jobs 1aceaabc at 5f8b8bb and the 5777e8c build) dogfooded on a Freestyle machine: Chief creates and drives a machine; Open Desktop connects through the tunnel; the page moved the VM's pointer to the aimed pixel (xdotool reported 359,222 for 25% of 1440x900); with the key in memory a Chief subagent's attempt at its own SOCKS bridge was refused ("the app's hub refuses no-auth SOCKS").

Observed / Not run

  • Not observed: a --viewer rd frame on screen (the host runs on one hand-set-up machine; one live Connect ended with the app exiting and no crash report, under investigation). --viewer native was not seen streaming on a VM.
  • Not run: the Chief first-turn cost guard.

No capture: the visible changes are a standard CmuxDialogSpec dialog (Pro) and an Open Desktop workspace that needs a signed-in Cloud account with a running machine; the capture minis have neither, so a real capture cannot show them. The dogfood above is on a live machine.

Changelog

Added: Chief can create and use your cmux Cloud machines, including their desktop; Open Desktop shows a machine's screen over the app's own Cloud tunnel; a Cloud create on a plan without Cloud offers cmux Pro.

🤖 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

Chief can now create and use the user's cmux Cloud machines from the Mac through the cmux CLI, and a Cloud create on a plan without Cloud offers an Upgrade to cmux Pro dialog instead of a bare refusal.

  • Ships a chief-cloud-machines skill and one prompt line: find machines with cmux cloud list-machines, create with cmux cloud new-machine (the app's Create card still asks the person), run commands and the machine's own cmux via cmux cloud exec, and drive the Linux desktop with cua-driver. The desktop helper makes its folder with exec (cloud file-mkdir makes a root-owned folder the daemon cannot write) and fails when no screenshot was saved. After a create refused for cmux Pro, the skill defers to the base's paid-plans skill: a checkout (a billing checkout link) starts only when the user asks or no dialog could show. The skill forbids its own tunnel or port bridge (a second hub on the app's key knocks the app's link off the machine; a local port hands the machine's unprotected VNC to every program on this Mac).
  • New Open Desktop action (cloud open-desktop, palette and machine menu) shows a machine's desktop over the app's own WireGuard tunnel: SOCKS5 on the Cloud hub socket to the machine's private address, with no port opened on this Mac and only cmux's own Chromium allowed through. The default web viewer loads the machine's noVNC page in a cmux browser tab; --viewer native and --viewer rd (both DEBUG-only, refused without the remote view pane) show it in the app's own pane — native through RFB inside websockify's WebSocket on the machine's 6901, rd through the machine's Rust cmux-rd host (H.264) on its private address — with no sign-in sheet and no listener on this Mac; a reader drains the tunnel as it comes, so a burst never drops the session. The pane's card names the machine, says "Connecting through your Cloud tunnel," keeps its session for two minutes after a hidden tab, and reconnects by itself after a lost path (1 s up to 10). A via=cloud record connects for a person's open within 15 seconds and asks first otherwise. The desktop route serves only this Mac's tabs (a remote workspace's tab never dials this Mac's hub), and the page's URL names its machine, so remote localhost routes it by URL through relaunches, moves and hibernation with no stored state; following that URL in any other tab of this Mac reroutes to the machine's store over the app's tunnel (a shim guard keeps the page out of this Mac's store; WebKit tabs cancel the URL, which would load this Mac's loopback), and a route that cannot start leaves the page blank, never this Mac's localhost. The badge matches the machine without case. The hub now requires a per-launch token of every client — one per app launch, made in memory so a restarted hub keeps its running links (SOCKS5 username/password, constant-time compare) — and reads its config on stdin, an earlier build's file copy removed, so the private key never lands on disk and another program of this user that finds the socket gets nothing. The one tokenless exception is ssh: cmux wg dial (used by cloud enroll-machine) reaches port 22, which authenticates both ends itself, and lets a same-user program with the user's ssh key carry ssh -L to the machine's loopback services.
  • A create refusal that names cmux Pro is now a typed CloudAPIError.planRequired: upgradeRequired on /api/vm with no other plan named (not a credits top-up), or the app server's plan_required, which shows the dialog's own localized copy instead of the server's English text. Only a person's own create shows the dialog, whose body is the server's reason; Upgrade opens the refusal's cmux.com link and one offer shows at a time. A CLI or Chief create gets no dialog: its answer has code cloud.plan.required and ends with (plan: …), and Chief offers the checkout. Refusals naming another plan (Max) stay plain HTTP, and a free-plan gate refusal maps to a Pro refusal already marked offered.
  • The shipped skill list now holds five in install order, cmux-adoption and paid-plans beside the new skill.

Testing

  • CloudAPIClientPlanRequiredTests stubs the server's own free-plan 402 body and checks .planRequired; a Pro budget naming Max and a paid plan's limit stay .http.
  • CloudCreationProOfferTests checks the flow offers Pro once for a Pro refusal or the app-server plan_required, never for an ordinary refusal or an agent's create.
  • CloudHubLoopbackTests checks the SOCKS5 CONNECT to the machine's address and port, the client token (a wrong token gets an auth failure), byte echoing, a refused or non-loopback connection, and an unroutable desktop address opening blank, not a reroute loop (the stand-in hub now runs off the main actor).
  • WebSocketTransportTests checks the native viewer's RFB-over-WebSocket stream under a time limit: masked client frames, split server frames, a ping, and a refused or wrong handshake.
  • Rust wireguard_hub_e2e checks that a tokenless and a forged client are refused and ssh's tokenless exception works.
  • The desktop loop was walked on a dev Cloud machine through the tagged build's CLI: diagnostics, exec, the machine's own cmux, the helper install, launching Chrome, a click that navigated, and the screenshot round trip.
  • The shipped-skill test now expects the new skill; not run yet are the full CmuxNext and optchat-chief suites and the tagged dogfood.

Written for commit 3634d90. Summary will update on new commits.

View guided diff Turn on auto-fix

…e needs it

Chief gets a shipped `chief-cloud-machines` skill and one prompt line: it
finds the user's Cloud machines with `cmux machine list`, creates one with
`cmux cloud new-machine` (the app's Create card still asks the person), runs
commands and the machine's own `cmux` through `cmux cloud exec`, and drives
the desktop with cua-driver (one helper step per exec, the screenshot pulled
back with `cloud file-read`). The loop is the one verified on classic Chief
(b7284a8), moved to cmux next's Cloud actions.

A create the plan does not include (`upgradeRequired` on the /api/vm
refusal, or the app server's plan_required) is now a typed
`CloudAPIError.planRequired`, and the creation flow shows the person one
"Upgrade to cmux Pro" dialog whoever asked (a click, the CLI or Chief);
Upgrade opens the pricing page. A paid plan's ordinary limit stays a plain
HTTP refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang austinywang added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 22, 2026
@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 3634d90: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr23952 -f ref=feat-cmux-next-chief-cloud-vms -f platform=macos -f backend_mode=local

Not verified: macOS jobs did not run: compile and app tests were skipped on 3634d902d6; ci-status is green without them.

CI passes on 3634d902d6 (run 40636433224 attempt 1).
macOS jobs did not run: compile and app tests were skipped: Fast static checks skipped (the macos job needs both to succeed). Re-run CI once they pass, before merging.

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

web and size checks: green

@blacksmith-sh

blacksmith-sh Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Found 5 test failures on Blacksmith runners:

Failures

Test View Logs
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g/
nightly must build and hand off the macOS 26 helper and Xcode 26.5 app before publishin
g
View Logs
nightly.yml must derive the embedded key and sign every appcast through the helper/
nightly.yml must derive the embedded key and sign every appcast through the helper
View Logs
test_only_restore_workloads_take_linux_and_fresh_builds_keep_macos (main.WorkflowRo
utingTests.test_only_restore_workloads_take_linux_and_fresh_builds_keep_macos) (name='b
uild-nightly-ghostty-cli-helper')/
test_only_restore_workloads_take_linux_and_fresh_builds_keep_macos (main.WorkflowRo
utingTests.test_only_restore_workloads_take_linux_and_fresh_builds_keep_macos) (name='b
uild-nightly-ghostty-cli-helper')
View Logs
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)/
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)
View Logs
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)/
test_the_repository_highlights_validate (main.DigestTests.test_the_repository_highl
ights_validate)
View Logs

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

- Chief lists machines with `cmux cloud diagnostics` (every Cloud machine,
  paused ones too, by the Cloud id `--target` takes); `--target` also takes
  the `machine_…` id `cmux machine list` prints for a connected one.
- The Pro offer is only for a refusal that names Pro (`upgradeRequired`
  with no other `upgradePlanId`, not a credits top-up): a Pro user's budget
  that names Max stays an ordinary error. The dialog's body is the server's
  localized reason, Upgrade opens its cmux.com link, one offer shows at a
  time, and a failed open is logged.
- The skill reads fields under `.result`, runs the machine's own cmux with
  HOME=/home/cmux, creates the log directory before a detached job, and
  notes that a --command cannot start with `--`.
- CloudCreationProOfferTests: the flow offers Pro once for a Pro refusal or
  the app server's plan_required, never for an ordinary refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

Review and verification

The review is a correctness-first subagent review, run twice: on e5d3fea, and again on the current head fb4f2b85329ced42fa297da06aaaadcbba6136a0. The second pass's verdict is SHIP.

First pass (e5d3fea): FIX, all resolved in fb4f2b8

  1. Blocker: cmux machine list prints machine_… resource ids, but --target resolves Cloud VM ids, and the list leaves out paused machines.
    • The skill now lists machines with cmux --json cloud diagnostics (every Cloud machine, by VM id).
    • CloudHandlers.machine also accepts the resource id.
  2. The Pro offer covered too many refusals. upgradeRequired alone also matched Pro→Max budgets and credit top-ups.
    • It now requires no upgradePlanId other than pro, and excludes vm_create_credits_insufficient.
    • The dialog body is the server's localized reason, and Upgrade opens the refusal's cmux.com link.
  3. The skill read fields at the top level. It now reads them under .result.
  4. The machine's own cmux was run without HOME=/home/cmux. Added.
  5. "One offer at a time" was not enforced. There is now a MainActor guard, and no dialog is shown when no window is open.
  6. Nits:
    • The skill now notes that a --command can't start with --.
    • The job-log directory is created before a detached job.
    • A failed upgrade open is now logged.
    • A test now covers the creation-flow hook: CloudCreationProOfferTests.
  7. The bounded 10 s wait loop in the VM-side helper is kept. The reviewer agreed it isn't blocking: it runs in the guest shell, inside the 25 s exec cap.

Second pass (fb4f2b8): SHIP, nits held for after dogfood

  • The dialog title is too specific for Go-plan limits.
  • The app-server plan_required path shows the backend's internal English text instead of the localized fallback.
  • fromjson fails if diagnostics' details is empty.

Checks

  • optchat-chief at fb4f2b8 (rbx): cargo fmt --check, every test target (75 library tests plus all integration tests), and cargo clippy --all-targets -D warnings all pass.
  • CmuxNext suites at c8ff24d (cmux-ci step 5e4cc4836f23dda9b4c795b5, aws-m4pro-2, Xcode 26.6): all passed.
  • Dogfood build: fleet job 22bdae23d12a33ec7b51eff9 at c8ff24d, tag 23952-chief-cloud-machines, sha256 d1bd83d5…, against dev backend https://cmux-dev-backend-1.tail137216.ts.net:4799/. The tag's backend is set to Pro with free provisioning.
  • Not run yet:
    • the Chief first-turn cost guard (runs at landing);
    • the dogfood itself (Chief creating a machine, running a cua-driver step and posting a screenshot), which is with Austin;
    • the native capture of the dialog.

@teamleaderleo

Copy link
Copy Markdown
Collaborator

Bead cx-iclbe created for this PR by the cmux coordinator.

Conflicts: the shipped Chief skill list (optchat-chief src/skills.rs and
tests/auth_escalation_brain.rs) now holds the base's cmux-adoption and
paid-plans beside chief-cloud-machines, five in install order.

chief-cloud-machines defers to the base's paid-plans skill: after a create
refused for cmux Pro, the app's Upgrade dialog is the offer, and Chief
starts a checkout only when the user asks or no dialog could show.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Walking the skill on a dev Cloud machine found that `cloud file-mkdir`
makes a root-owned folder (the Cloud file API runs as root) the cmux-user
cua-driver daemon cannot write its screenshot into, and that cua-driver
exits 0 on "Capture error: Permission denied". The skill now makes the
folder with exec (the machine's cmux user), and the helper removes the
old screenshot and fails when no new one was saved.

Verified on the dev backend machine through the tagged build's CLI:
cloud diagnostics, exec, the machine's own cmux (workspace and terminal
list), the helper install, launch_app (Chrome on example.com), a
background click that navigated to iana.org, and the screenshot round
trip (1440x900 PNG).

Also from review: the app server's plan_required shows the dialog's own
localized copy, the diagnostics jq tolerates an empty report, and the
skill says an "unverifiable" click is checked by title or screenshot.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 23, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

A Chief subagent showed a machine's desktop by starting a second
cmux-tui wg hub on the app's WireGuard config and a local port bridge to
its noVNC. The second hub on one key fought the app's own link (the
desktop reconnected whenever the app touched the machine), and the
bridge gave the machine's unprotected VNC to every program on the Mac.
The skill now forbids both and sends screenshots until cmux has a live
view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nnel

cmux Classic shows a Cloud machine's desktop in a cmux browser pane whose
traffic goes through the app's userspace WireGuard tunnel. cmux next had
no way in, so a Chief subagent improvised a second `cmux-tui wg hub` on
the app's key and a local port bridge to noVNC: it reconnected whenever
the app touched the machine (two hubs on one key) and handed the
machine's unauthenticated VNC to every program on the Mac.

Open Desktop (`cloud open-desktop`, palette and the machine's menu) opens
a "<machine> Desktop" workspace on this Mac whose Chromium tab loads the
machine's noVNC (6901 on its loopback). Its pane is marked as that
machine's before the tab loads, so remote localhost routes it: the
peer-checked proxy (only cmux's own Chromium) opens the stream with the
new HubLoopbackOpener, SOCKS5 over the app's CloudTunnelHub socket (the
tunnel enrolled for this Mac with POST /api/vm/tunnel) to the machine's
private address. No port opens on the Mac. A Cloud machine whose cmux-tui
predates the loopback forward takes the same route for its own tabs.

Chief's skill uses Open Desktop to show a desktop and still forbids any
hub, tunnel or bridge of its own.

CloudHubLoopbackTests: a stand-in hub checks the SOCKS5 CONNECT to the
machine's address and port, echoes bytes through the tunnel, a hub
refusal is refused, and a non-loopback host never dials.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…losure crashed the compiler's diagnostics)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of ba13b9b: the pane mark lived only in memory, keyed by a daemon
pane handle that does not survive a daemon restart, so a relaunched
desktop tab loaded this Mac's 127.0.0.1:6901 and a reused handle could
send an unrelated local tab to the Cloud machine.

The desktop page's URL now names its machine,
`http://<machine id>.cloud-desktop.localhost:6901/vnc.html`: a name under
`.localhost`, loopback by the remote-localhost rule. Remote localhost
routes that URL to the machine over the app's tunnel whatever pane or
daemon holds it, through relaunches, moves and hibernation; no state.

- configureBrowser no longer turns a nil configuration (a blocked
  proxied tab, a route that cannot start) into the default store: the
  page stays blank (TabContentCache.chromiumConfiguration), never on this
  Mac's localhost.
- The hub route is Open Desktop's only; Cloud machines whose cmux-tui
  lacks the loopback forward keep "update machine" for their own tabs.
- HubLoopbackOpener: one deadline over the whole open, and the SOCKS5
  reply is read by its ATYP (IPv4, IPv6 or a name) so none of it reaches
  the page.
- Copy says "no TCP port opens on this Mac"; skills/cmux-cloud-vm lists
  `cloud open-desktop`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of b00c7ea: pasting or following an Open Desktop URL in a tab of
this Mac loaded this Mac's port 6901 (the profile store had no guard)
while the badge named the Cloud machine.

The shim's store guard gets mode 3, any URL but an Open Desktop page
(`*.cloud-desktop.localhost`), and this Mac's tabs take it instead of
"any". Such a navigation is cancelled and reported as rerouteStore, and
the page comes back in the machine's store over the app's tunnel.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a later shadowing let made the bind closure capture it before its declaration)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 23, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

…efaults to the main actor, so its accept thread tripped the runtime isolation check)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of rerouting forever

The shim's IsCloudDesktopHost refuses any *.cloud-desktop.localhost page in
the ordinary store (exceptCloudDesktop). Swift's routing is stricter (one DNS
label, this Mac's tabs only), so for a host it could not route (a_b., x.y.,
a trailing dot, or a remote tab whose localhost is this Mac on purpose) it
chose that same store, the guard fired on the new browser's first load and
TabContentCache.reroute rebuilt it again, endlessly; a web page could
trigger it. RemoteLocalhostStorePlan.blank: such an address gets no page.
isCloudDesktop now drops a trailing dot like the shim, so the two agree.

Regression: CloudHubLoopbackTests.aDesktopAddressThatCannotRouteOpensBlankNotAReroute
(red at c3da2a8: no .blank; green on this commit, fleet run below).
Found by the independent review of 0263369.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ext-chief-cloud-vms

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextApp/Cloud/CloudMachineCreateFlow.swift
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@austinywang

Copy link
Copy Markdown
Contributor Author

Review of 0263369 (independent subagent, correctness first): FIX, with one blocker.

  1. Blocker, fixed in 61265ff. The CEF shim's store guard (IsCloudDesktopHost) refuses any *.cloud-desktop.localhost host in the ordinary store. Swift's routing only routes one DNS label, from this Mac's tabs. For any other desktop host (a_b., x.y., a trailing dot, or a remote tab whose localhost is this Mac on purpose), Swift gave the page the ordinary store again, and TabContentCache.reroute rebuilt the browser forever. A web page could trigger this.
    • The fix adds RemoteLocalhostStorePlan.blank: such an address opens blank.
    • isCloudDesktop now drops a trailing dot, as the shim does.
    • Regression test: CloudHubLoopbackTests.aDesktopAddressThatCannotRouteOpensBlankNotAReroute. It is red at c3da2a8 (RemoteLocalhostStorePlan has no member blank) and green at 61265ff (5 suites passed on the fleet).

Lows (not fixed here, none blocking):

  • A trailing-dot desktop URL for a real machine opens blank. It fails closed.
  • A Max refusal shows the failure text but no upgrade card; Chief and the CLI still get cloud.plan.required with the plan.
  • If Open Desktop's tab never appears, the person-open mark keeps its 15 s window.
  • The first Open Desktop after launch can time out while the hub is still starting.
  • A Cloud VNC tab retries every 10 s while it stays open.

Re-review of 61265ff: SHIP at 61265ff. It checked every Chromium configuration path: creation, reroute, hibernated wake, duplicate, history, popups and ChromiumNewTabNow. Each ends blank or in the right store, and the Swift and shim host checks now agree.

Then I merged origin/feat-cmux-next (8711a8c), giving head ea69bc6. The one conflict was CloudMachineCreateFlow: base's new rule (the upgrade card only for creates a person started) is kept, together with this PR's Failure.upgradeRequired(reason). Base's new test now expects .upgradeRequired(.freePlan). The fleet build and the focused suites are running on ea69bc6.

austinywang and others added 2 commits October 27, 2026 02:20
…o card

feat-cmux-next made the upgrade card person-only; this PR's planRequired
hook still opened the Pro dialog for a Chief or CLI create the server
refused (app-server mode, or before the plan limits load). Fails until the
fix: CloudCreationFlow has no startedByPerson.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat-cmux-next made the upgrade card person-only ("the person is not
prompted on every agent request"), but this PR's planRequired hook still
opened the Pro dialog for a Chief or CLI create the server refused (always
in app-server mode, where no limits gate first; in legacy mode before the
limits load). CloudCreationFlow.startedByPerson now gates the hook; the
agent still gets cloud.plan.required with the plan and offers the checkout.

Regression: CloudCreationProOfferTests.anAgentsServerRefusedCreateOffersNothing
(red at d0a17c7: no startedByPerson; green here, fleet run below).
Found by the independent review of ea69bc6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

Review (claude subagent, independent): SHIP at 8f8e081

Review history

  • ea69bc6 (a merge of origin/feat-cmux-next 8711a8c): FIX, one blocker. Base made the upgrade card person-only, but this PR's planRequired hook still opened the Pro dialog for a Chief or CLI create that the server refused.
  • Fix: CloudCreationFlow.startedByPerson gates the hook. The agent still gets cloud.plan.required with the plan.
  • Regression test: CloudCreationProOfferTests.anAgentsServerRefusedCreateOffersNothing. It is red at d0a17c7 (no startedByPerson) and green at 8f8e081.
  • The re-review of 8f8e081 checked every flow caller (New Cloud Machine and Workspace: person vs CLI/MCP/page; Retry and Dismiss) and gave SHIP.

Lows (follow-ups, not blocking)

  • A person's Retry builds the flow as not person-started, as it did before this PR, so Retry shows no second Pro card.
  • Base's own legacy 402 path still shows the card to agents. This is the same on 8711a8c and is asserted by base's aServerPlanRefusalBecomesTheUpgradeCard.

Checks on 8f8e081

  • Fleet suites: 11 of 12 passed (CloudHubLoopback, CloudLinkReconnecting, CloudAPIClientPlanRequired, CloudCreationProOffer, CloudCreateWithoutAsking, CloudCLITarget, CloudErrorText, ActionSurfaceExport, RemoteViewTabPolicy, RemoteViewVNC, OmnibarFilePathDisplay).
  • ActionSurfaceParityTests.everyMenuKeepsAShortTopLevel fails (.sidebarBackground has 14 top-level rows). This is a base finding: the same failure occurs on 8711a8c, and this PR places nothing in that menu.
  • prepush gate: no new violations.
  • Fleet build e0463fee87d5fe8321da242b is done and installed as tag 23952-chief-cloud-machines.
  • optchat-chief: cargo fmt is clean. 121 of 122 tests pass. The failing test, memory_sync_state::detect_finds_…, needs the zip binary, which the rbx builder lacks; this PR does not touch that file.

Not run: a live Open Desktop --viewer rd click-through on this head.

austinywang and others added 2 commits October 27, 2026 15:26
…ext-chief-cloud-vms

Base's `cloud enroll-machine` reaches a machine's ssh through the app's
WireGuard hub with `cmux wg dial --hub`, a separate process without the
hub's per-launch token. The hub now admits a tokenless client for port 22
only (wireguard_hub::OPEN_PORTS): ssh authenticates both ends itself, and
every other port (noVNC, desktop hosts, dev servers, daemon links) still
needs the token. socks::server_greet returns a Greeting (Refused,
Authenticated, Open) so the hub can narrow an Open client.

Conflicts kept both sides: CloudTunnelHub (base's restart watch and hub
symlink, this PR's in-memory key and token); CloudMachineLink (vm-kind
args plus the token on stdin); CloudMachineCreation and
CloudHandlers+Account (base's bootstrap hook, this PR's Pro offer gated on
startedByPerson); CloudLinkReconnectingTests (both sides' tests);
cmux-tui/spec/cli.md (wg hub flags plus wg dial).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review of b909146: the lane lets a same-user program that can use this
Mac's ssh key ssh -L to an enrolled machine's loopback services; say so,
and name the narrowing options for 13742. cli.md names the lane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 27, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

feat-cmux-next added CloudAPIError.code (a2f2…, Sandboxed sends) after
this PR added .planRequired; the merge compiled only on the fleet build,
which failed with "switch must be exhaustive" (job a0fbe73ed6b0). The
code is plan_required, as the runs control error answers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

Review (claude subagent, independent): SHIP at 0f7afcc

What changed since 8f8e081

  • The merge. b909146 merged origin/feat-cmux-next (a6c49db). Six conflicts, each resolved by keeping both sides:
    • CloudTunnelHub: base's hub restart and stable socket symlink, plus this PR's in-memory key and token;
    • CloudMachineLink: base's VM-kind arguments, plus the token on stdin;
    • CloudMachineCreation and CloudHandlers+Account: base's bootstrap hook, plus the Pro offer gated on startedByPerson;
    • CloudLinkReconnectingTests;
    • cmux-tui/spec/cli.md.
  • The ssh lane. Base's cloud enroll-machine ssh ProxyCommand (cmux wg dial --hub) is a separate process with no token. The hub now admits a client without the token to port 22 only: wireguard_hub::OPEN_PORTS, and socks::Greeting returns Refused, Authenticated or Open. Every other port still needs the token.
  • Docs. a89f79a states what the lane gives back: a same-user program that can use this Mac's ssh key can ssh -L through an enrolled machine's sshd to that machine's loopback services. It names the narrowing options (an open lane only for enrolled addresses, or restrict on the enrolled authorized_keys line) as a policy question for Design and product calls (gallery: #15427), plus CI admin #13742. That is not posted there yet.
  • Compile fix. The fleet build of b909146 failed with CloudAPIError.swift:43: switch must be exhaustive, because base added CloudAPIError.code (job a0fbe73ed6b0f931568b8701). 0f7afcc adds .planRequired: "plan_required".

Reviews

  • b909146: SHIP. The token can't be bypassed: offering both methods selects user/pass, and a tokenless client can't reach any port but 22. Hubs without a token behave as before. Base's restart keeps the token, the key and the socket path.
  • 0f7afcc: SHIP. Every switch over CloudAPIError is exhaustive, and sandboxCode maps a plan refusal to unavailable, as base does for any code it doesn't list.

Checks on 0f7afcc

  • Fleet build 4e401ed9e50d776345281d0f: done, installed as tag 23952-chief-cloud-machines.
  • Focused suites: all 11 passed (CloudHubLoopback, CloudLinkReconnecting, CloudAPIClientPlanRequired, CloudCreationProOffer, CloudCreateWithoutAsking, CloudCLITarget, CloudErrorText, ActionSurfaceExport, RemoteViewTabPolicy, RemoteViewVNC, OmnibarFilePathDisplay).
  • ActionSurfaceParityTests was left out. It fails on base 8711a8c with .sidebarBackground has 14 top-level rows, the same failure as on this PR, so it is a base finding.
  • rbx at b909146: cmux-remote all green, including the wireguard_hub_e2e ssh-lane assertions; the 8 wg_ tests in cmux-tui green; cargo fmt clean.
  • prepush gate: no new violations.

Not run: a live --viewer rd click-through on this head.

@github-actions

github-actions Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Default changes

This pull request changes 7 defaults at 3634d902d6df (what everyone gets without configuring anything):

  • tunable-source.CmuxNextActions/ActionSurfaceCatalog+MenusContent.swift:contentPlacements: "047202114c4c6cd393b7cf9cbd0f8e811d090ed92f1ecfe688d0b5204d0650db" -> "79a906ee164b61f61a7a235b1100bae5a09af3035dda1d0a78d2be2df8278b07"
  • tunable-source.CmuxNextApp/Cloud/CloudStrings+Errors.swift:apiErrorText: "f10053d5a1b75379d156debd105868baf524fec409a8634705515b7fb366b56a" -> "e8bd7f1d699fb481a826021417278053a90563353dd06cd322580ea63d7a1199"
  • tunable-source.CmuxNextApp/Control/AppControl+Cloud.swift:runError: "6b8df46136da12416fe87c24329263cebe6f77d7837365b4ad2eae6564dd8c52" -> "afba481aff824b1902dca59141e96b61fbb3556740e3a9ed54a5fe29eeb75752"
  • tunable-source.CmuxNextApp/Handlers/CloudHandlers.swift:machine: "c1c7d7548f9f0e4ee339028cd9dc4453fd3c27c44a9f22552b28751041e7cc7d" -> "1f88adcd3d5d33f9162c228346cb8b2f76a206289ad801640297c04fcf130c9b"
  • tunable-source.CmuxNextApp/Handlers/WorkspaceHandlers.swift:createAndShow#: "bbfdf603022d47aebcaf02796766a536e9a29dc2b876e6e6a1a22886ab1940ef" -> "a2535c5257a941ce9b1122b18a253ec2a3d1607decb445b0c120c279b9bc0b5f"
  • tunable-source.CmuxNextRemoteViewSessions/RemoteViewPageSession.swift:cloudRFBTransport: (none) -> "334f18a0365c77e2cd35f507538a4989196ced49813c59b21d1baceb56406cbf"
  • tunable-source.CmuxNextRemoteViewSessions/RemoteViewPageSession.swift:make: "6c65fc2109e7b0fd1f2c66d59eeba822d00018dd8b0cd8b9a08398627ece3af0" -> "896afa50147e8ca82ee9837a25fb4f9504db86320aa782a4bb1f89d4e0a9a9d6"

Needs a review. It passes with an independent review receipt on this commit: a comment or review whose first line is Review (<reviewer>): SHIP at 3634d902d6dffe6c02d89abf00d3248919642e54, from a member, not a self-review (the newest verdict naming the head decides; a later BLOCK beats an earlier SHIP), or with an approving review on this commit from @lawrencecchen or @teamleaderleo (the call owners in .github/defaults-call-owners.json, never the author). A receipt posted as a review re-runs this check; after a plain comment, re-run it. The needs a call label alone does not pass, and a new push needs a new receipt.

Merge receipt: merged as 0ab915d9442e with these defaults changed, WITHOUT a SHIP receipt or an approving call owner review on its head.

Regenerate the snapshot with python3 scripts/ci/defaults_guard.py snapshot.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40626998043 at 0341883 failed: cmux-next generated files.
Those jobs last passed at 46c2c64. This pull request is one of 2 merged since: #26584, #23952.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40626020108 at 0ab915d failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 46c2c64. This pull request is one of 2 merged since: #26584, #23952.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40627558915 at 47b4dbb failed: cmux-next checks (god files, concurrency, crash safety, l10n), cmux-next generated files.
Those jobs last passed at 46c2c64. This pull request is one of 3 merged since: #26584, #23952, #26596.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@github-actions

Copy link
Copy Markdown
Contributor

The feat-cmux-next push run https://github.com/manaflow-ai/cmux/actions/runs/40628944074 at 18af98c failed: cmux-next generated files.
Those jobs last passed at 46c2c64. This pull request is one of 4 merged since: #26584, #23952, #26596, #26609.
If the failure is in your change, fix forward on feat-cmux-next. Pull requests run only the tiers their paths reach (docs/ci/cmux-next-tiers.md); label a batch PR full-ci to run them all before merging.

@austinywang

Copy link
Copy Markdown
Contributor Author

Review (claude subagent, independent): SHIP at 3634d90

This head

  • 3634d90 merges origin/feat-cmux-next 46f5779 into 0f7afcc (SHIP at 0f7afcc) with no conflicts.
  • It picks up base's own compile fix 3186450 (CuaSocketClient.send is nonisolated). That fix is what turned 0f7afcc's CI red: ComputerUseSetup.swift:236 was a base finding, a file this PR does not touch.

Review findings

  • No blockers. Everything base brought in either doesn't overlap this PR or adds alongside it: CloudMachineLink.ownerPID, the newCloudWorkspace changes, and CloudMove --to-pid/--vm-kind.
  • Nothing calls an API this PR replaced, and no new switch over CloudAPIError appeared.
  • Advisory, for a follow-up: base's new Chief cloud_workspace tool hands Chief only the error's message, so a plan refusal reads "… (plan: pro)" without the cloud.plan.required code that the tool's description names. Its header comment also still says an agent's free-plan create shows an upgrade card.

Checks on 3634d90

  • Fleet build 72e80d61e319a0c3cd1866ee: done.
  • Focused suites, step ac1846d88656702fcb270625 on aws-m4pro-4: all 12 passed (CloudHubLoopback, CloudLinkReconnecting, CloudAPIClientPlanRequired, CloudCreationProOffer, CloudCreateWithoutAsking, CloudCLITarget, CloudErrorText, ActionSurfaceExport, ActionSurfaceParity, RemoteViewTabPolicy, RemoteViewVNC, OmnibarFilePathDisplay). The first run, step 32f0a4100f4aff18ef7e8899, timed out on cmux10s-Mac-mini (step exit 124), an infrastructure failure, so I reran the same SHA.
  • prepush gate: no new violations.
  • PR size: passes with the Size: line (one integration PR, by request).
  • defaults guard: the 7 changed defaults are this PR's own Cloud error mapping, machine target, Open Desktop placement and remote view transports, all reviewed above.

Not run: a live --viewer rd click-through on this head.

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

@github-actions

Copy link
Copy Markdown
Contributor

Shipped in:

This branch had an error being deployed

1 failed (outdated) and 3 inactive deployments
artifacts — 3634d902 Deployed Oct 28, 2026 by austinywang via add the Windows daemon to the tree #68608
sentry-dsyms — 3634d902 Deployed Oct 28, 2026 by austinywang via upload cmux-tui dSYMs to Sentry #68608
ci-routing-agent — 3634d902 Deployed Oct 28, 2026 by austinywang via wait for same-key tree publisher #68608
cmux-tui-merge-tree — 61265ff6 Deployed Oct 26, 2026 by austinywang via publish the merge tree #6651
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-land Reviewed at this head; next-autoland merges it into feat-cmux-next when its only reds are base reds risk:high Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants