Skip to content

cmux NEXT: Cloud as where a new chat runs, a row in the composer's environment picker - #26801

Closed
teamleaderleo wants to merge 8 commits into
leo/cloud-start-chatfrom
leo/cloud-run-location
Closed

teamleaderleo wants to merge 8 commits into
leo/cloud-start-chatfrom
leo/cloud-run-location

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

HOLD: lands after #26791, whose fleet package tests have not run yet (the fleet controller is stalled).

What

Where a new chat runs becomes one choice in the composer: This Mac or Cloud. Behind Labs (preview features).

  • The control. A Cloud row at the top of the environment picker's Cloud section, with one line on what it does. Every existing row stays: the account's machines, New Cloud Machine, Open Cloud…, SSH… and the rest. Picking it makes the composer read Cloud; a machine picked after it makes the chat a chat on that machine again.
  • The default stays This Mac. Nothing flips it.
  • The first send with Cloud picked calls cloud.startChat (cmux NEXT: cloud.startChat, a new chat's first send runs in Cloud #26791) with the prompt, the folder the folder chip names, the agent and the model. The host picks and sizes a Cloud machine, copies the folder, opens the chat there and closes this tab. No machine, size or environment prompt.
  • Refusals keep the prompt. Attachments are refused on Cloud for now. A Cloud pick that is no longer available when the send happens (Labs went off, a chat started here) is refused too, never sent as a chat on this Mac.
  • One start at a time. While a Cloud start waits on the host (a new machine boots in minutes), another Return or New chat starts nothing.
  • Picking Cloud drops a saved environment or machine picked before it, so the folder sent is the one the chip shows. It also hands focus back to the prompt, so Return sends.
  • The row lives in the existing picker, so it opens the way that picker already does; this PR adds no menu or animation.

Gallery

Gallery: agent-pane.cloud-run-designs/row, agent-pane.cloud-run-designs/bare, agent-pane.cloud-run-designs/chip, agent-pane.composer-context/environment-picker-cloud-picked

Three designs side by side in agent-pane.cloud-run-designs (CloudRunDesigns.tsx, experimental). The two alternatives are gallery-only and wrap the real scope row; only the picked one ships.

  • row (picked): Cloud is a row at the top of the picker's Cloud section, with one line on what it does.
  • bare: the same row with no subtitle.
  • chip: a This Mac / Cloud switch beside the picker.

Why row: one control already answers where a chat runs, and the subtitle tells Cloud apart from a named machine.

States of the shipped row stay in agent-pane.composer-context: environment-picker-cloud-row, -cloud-picked, -cloud-search and -cloud-closed.

Why

Leo, 2026-10-28: "You can just say ... where should this chat run and stuff, and that's just about it ... it's somewhere in the cloud, and then it gets managed for you. You don't have to select an environment, you don't have to create an environment, you don't have to do all that nonsense".

Risk

  • Behind Labs. Without it the row does not show and the host method refuses with labs_off.
  • The environment picker's other rows are unchanged; persistent() now resets any non-persistent mode (Sandboxed or Cloud) when a machine is picked.
  • The model goes to the host, but the machine's start uses the agent's default model for now (cmux NEXT: cloud.startChat, a new chat's first send runs in Cloud #26791).
  • A folder-history default (a folder whose last chat ran in Cloud opens with Cloud picked) is not in this PR.

Tests

  • EnvironmentPicker.test.tsx (new): picking Cloud sets the mode and focuses the prompt on the first pick and on a repeat pick; a machine picked while Cloud is the mode goes back to a chat here.
  • NewTabScreen.test.tsx: a Cloud send goes to onCloud, not a new chat, and a refusal keeps the prompt; a saved environment picked then Cloud sends the chip's folder (/repo/A), not the tab's inherited home.
  • cloudRun.test.ts: the host call's params, its refusals, attachments refused, a Cloud pick that is no longer offered refused, and a second start while one waits refused.
  • Linux webview checks (bun run check) and these suites ran with cmux-ci test at this head.
  • test/gallery-coverage.test.ts fails the same two tests on feat-cmux-next (a2f8b65), with the same list of components; none is in this PR. A base red.

Review: an independent Codex (gpt-6-astra, high) review took three rounds and returned SHIP at 8098947; a delta review of the gallery designs and the one-start guard returned SHIP at ca765c9. Since then only the gallery-only switch design changed (a fieldset for lint).

Stacked on #26791. It is retargeted to feat-cmux-next once that lands.

Captures: the Gallery: line above picks the states the gallery advisory run renders. Per #21400 its images stay in the run's artifact (gallery-advisory-<PR>-<HEAD_SHA>), not on this public PR.

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 5 commits October 28, 2026 00:38
…ironment picker's Cloud section

Behind Labs. Picking it makes the first send call cloud.startChat; attachments are refused on
Cloud for now. Gallery: four states of the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…ere; picking Cloud drops a saved environment and refocuses the prompt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
… dropped by a Cloud pick, and a refused send keeping its prompt

The not-offered refusal moves into cloudRun.ts so it is tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…mes, also when the tab inherited home

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

teamleaderleo and others added 2 commits October 28, 2026 01:41
…, beside the shipped Cloud row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
… it waits starts nothing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra): SHIP at ca765c9

@cursor

cursor Bot commented Oct 28, 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.

@blacksmith-sh

blacksmith-sh Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Found 168 test failures on Blacksmith runners:

Failures

Test View Logs
src/pages/settings/layout.test.ts/layout.test View Logs
src/pages/settings/layout.test.ts/layout.test View Logs
test/accent-glass-invariants.test.ts/accent-glass-invariants.test View Logs
test/accent-glass-invariants.test.ts/accent-glass-invariants.test View Logs
test/agent-pane-agents-pill.test.ts/agent-pane-agents-pill.test View Logs
test/agent-pane-agents-pill.test.ts/agent-pane-agents-pill.test View Logs
test/agent-pane-background-tasks.test.ts/agent-pane-background-tasks.test View Logs
test/agent-pane-background-tasks.test.ts/agent-pane-background-tasks.test View Logs
test/agent-pane-chat-unavailable.test.ts/agent-pane-chat-unavailable.test View Logs
test/agent-pane-chat-unavailable.test.ts/agent-pane-chat-unavailable.test View Logs

...and 158 more test failures. View all on Blacksmith

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

@cmux-bot

cmux-bot Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

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

Unclear: web / react-apps-check failed: no known signature; failed step: Check webview test shards.

CI failed on d1838f3216 (run 40659638104 attempt 1): 4 code, 1 unknown.

Job Verdict Why
web / react-apps-base-check (2) code a web test failed
web / react-apps-base-check (3) code a web test failed
web / react-apps-base-check (4) code a web test failed
web / react-apps-base-check (1) code a web test failed
web / react-apps-check unknown no known signature; failed step: Check webview test shards

Failures:

  • seen on other PRs layout.test.ts only page.css imports the page's sheets: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts chromium > a prompt the fold hides, run elsewhere, leaves no room as the stack shrinks, opens and cl...: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > the queue opened, the view scrolled to its end shows the last row whole, and it stays: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > the queue closed at the latest row keeps the last row on the stack, with no room that glide...: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > a prompt the fold hides, run elsewhere, leaves no room as the stack shrinks, opens and clos...: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > a prompt past the opened queue's cap, run elsewhere, leaves no room when the queue closes: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > in a chat switched to, a queued prompt withdrawn leaves no room held for the last chat's qu...: failed (job)
  • seen on other PRs agent-pane-queue-scroll-bottom.test.ts webkit > a new line in the composer leaves the transcript's distance from its end as it was: failed (job)
  • seen on other PRs agent-pane-dock-gutters.test.ts chromium > the gutter beside every part of the stack scrolls the transcript, and the part keeps the ...: failed (job)
  • seen on other PRs agent-pane-dock-gutters.test.ts webkit > the gutter beside every part of the stack scrolls the transcript, and the part keeps the po...: failed (job)
  • ... 22 more in the job logs
Matched log lines
web / react-apps-base-check (2): (fail) only page.css imports the page's sheets [36.16ms]
web / react-apps-base-check (3): (fail) chromium > the gutter beside every part of the stack scrolls the transcript, and the part keeps the pointer [8549.77ms]
web / react-apps-base-check (4): (fail) the summary card lists the chat's background tasks: running ones first, the finished folded [1168.90ms]
web / react-apps-base-check (1): (fail) no orange or system accent and no opaque glass on the gallery stages [489614.74ms]

Not re-run automatically: web / react-apps-base-check (2), web / react-apps-base-check (3), web / react-apps-base-check (4), web / react-apps-base-check (1), web / react-apps-check are not machine failures.

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.

CI fast guards failed on d1838f3216 (https://github.com/manaflow-ai/cmux/actions/runs/40659638104). It does not block the merge; a red guard merged into main breaks it for every open PR.
The log named no failed step; see the run.

Agents: python3 scripts/ci/guard_attribution.py fix applies the mechanical fixes locally.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Folded into #28686 (original commits kept, on current feat-cmux-next). Review and landing continue there; the owner closes this one.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session · took over from an earlier session (its owning session is closed)

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Closing as a duplicate: #28686 folds this PR (with #26801, #26920 and #26921) into one PR on feat-cmux-next and carries it from here. This branch stays on the remote.

teamleaderleo added a commit that referenced this pull request Oct 31, 2026
…d start progress (fold of #26801, #26920, #26921) (#28686)

* cmux NEXT Cloud: pick a chat's machine from its folder (repo, ref, size, task kind), sent as autosize

A chat sent to Cloud no longer needs a machine or size choice: CloudWorkPick reads the chat's
folder (repo key and GitHub repo from the remote, branch and whether it is pushed, git object
size, root files, task kind, .cmux/machine.toml, Codex broker) and Move to Cloud with no machine
to reuse, and New Cloud Machine from a chat, send its autosize with POST /api/vm. The answer's
sizePick stays on the machine's session for the hand-off. Behind Labs preview features.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cmux NEXT Cloud pick: clone the upstream's branch name, no GitHub repo from a local remote, no pick on the app-server link

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cmux NEXT Cloud: cloud.startChat, a new chat's first send started in Cloud with no machine or environment prompt

The page's Send with Cloud picked asks the host (`cloud.startChat {task, cwd, harness?, model?, key}`),
with Sandboxed's guards (a new chat, the Send's gesture, the replacements held, one at a time;
both now share AgentPaneHandOff). The App takes a Cloud machine as Move to Cloud does (a new one
sized by CloudChatPick), copies the folder with Move to Cloud's sync, opens the chat on the machine
with the prompt seeded as the person's, and closes this Mac's unstarted tab. Behind Labs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: the page's folder is optional; the tab's own folder otherwise

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: a started chat keeps the pane's hold; the folder must exist; the hand-off body is main-actor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: only a chat on this Mac starts one; the App checks the tab's daemon is local

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer: Cloud as where a new chat runs, a row at the top of the environment picker's Cloud section

Behind Labs. Picking it makes the first send call cloud.startChat; attachments are refused on
Cloud for now. Gallery: four states of the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a Cloud pick not offered now is refused, never sent here; picking Cloud drops a saved environment and refocuses the prompt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: tests for the picker's Cloud row, a saved environment dropped by a Cloud pick, and a refused send keeping its prompt

The not-offered refusal moves into cloudRun.ts so it is tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: format the new-tab test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: the folder a Cloud send copies is the one the chip names, also when the tab inherited home

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Gallery: the two other designs of where a new chat runs, gallery-only, beside the shipped Cloud row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: one start at a time from a page; another Return while it waits starts nothing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Gallery: the switch design's group is a fieldset

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a new chat's run location defaults from its folder's newest chat

A folder whose newest chat went to a Cloud machine (a Cloud start or Move to
Cloud) opens new chats with Cloud picked; otherwise this Mac, as before. The
history is acpmux's chat list: a Cloud chat is matched to the folder by the
folder the app's copy made on the machine (CloudMoveFolder remoteName under
CloudMoveSetup workRoots). Labs only, and a pick in the pane always wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a new chat's carried-over Cloud is a default its folder may undo; archived chats are not history

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a carried-over Cloud is marked in the folder default's effect, per chat

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: no change while a Cloud start is out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: the folder default looks again once a Cloud start ends

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a chat starting here keeps the mode it starts with

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a chat starting in Cloud shows its progress under the message, as metadata

The card shows the message, a spinner with the step, and the folder, machine, secrets and network
as the host learns them (a cloudStartProgress push keyed by the start), never a modal. Three
layouts behind the cloud-start-look experiment (chips, fact rows, step list), compared in the
gallery's agent-pane.cloud-start. On the New Tab page it shows over the box, without the bubble.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: the host tells the page's card each step (machine, folder, opening) as the start reaches it

cloud.startChat pushes a cloudStartProgress event keyed by the page's send before it takes a
machine, copies the folder and opens the chat; the shared page host hands it to the bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start card: spacing and sizes on the design token scale

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* AgentPageChats: the Cloud start runner's pane closure, typed (Xcode 26.6 could not type the map)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: the host pushes the folder and the machine's size; a failed card goes when the person picks another place

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: format

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start gallery: the experiment's script has one step (an empty one does not load)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: the machine's chat starts on the picked model; type the seed's Cloud runner for Xcode 26.6

next-review's P2: CloudStartChat built the remote seed with the harness and prompt only,
so the model the page picked was dropped. AgentPaneCloudStart.seed(cwd:) now builds it
with the model too, with a test. The request carries no effort, so there is none to forward.

AgentPageChats.seed's Cloud runner is written out with its type, as #26921 does: #26921
found Xcode 26.6 could not type the map form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-22973a84aab760788504

* cloud.startChat: a retry opens the same tab on the machine; the folder check reads off the main thread

next-review's BLOCK at b3389d1 (Codex gpt-6-astra): CloudStartChat opened the machine's
chat tab with a fresh creation key, so a retry of the same send after a lost answer could
make a second chat and send the prompt twice. The tab's key is now the send's own
(AgentPaneCloudStart.tabKey), with a test that a retry's key matches and another send's
does not.

The folder check (FileManager.fileExists) ran on the main actor; it now runs in a
@Concurrent helper (guardrails main-blocking).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-22973a84aab760788504

* cloud.startChat: copy only a folder the pane may name, each send into its own copy on the machine

Two blocking findings from the Codex review of #28686, both in this PR's code:

- The page named the folder whose tree is copied to Cloud, and the host only checked that it was
  absolute. A page script could name any folder on this Mac. The hand-off now takes the folder's
  canonical path (realpath, off the main actor) only when it is inside one of the pane's roots by
  components, the same roots AcpmuxPathPolicy uses for a chat that starts here: the pane's own and
  the New Tab scan's, never home or above it, plus the folders the person added. Anything else is
  refused with transport.path_outside_roots before the hold and the gesture. No folder from the
  page still means the tab's own folder, which the host reads.
- Every Cloud start from the same folder synced into the same folder on a reused machine, and
  Move to Cloud's sync overwrites every file the machine changed, so a second Cloud chat could
  write over the first one's work. A start now copies into its own place under the work root
  (chats/<send key>). A retry of the same send lands in the same copy.

Tests: a folder outside the roots, a link out of a root, a `..` path out of it, a missing
folder, the disk's root, home, and a folder under home when the pane's folder is home are all
refused and never reach the runner. The root's own folder still starts with its canonical path,
and a send's place is its own and stable for a retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-672a743921bc7917cca7

* fix(cloud.startChat): a first send takes this person's free machine, and its retry stays there

Leo (2026-10-30): "like the initial 0 to 1 chat auto it sends to cloud".

- The machine: never the team's first connected one (often someone's busy lane VM). A machine
  this person created that is free (no chat open, or idle-paused) or named for chats
  (cloud-chats[-N]), else a new one named cloud-chats. Lane-pool VMs (fs-lane-N, lane-vm-N)
  are never picked.
- #28845: CloudStartChat.Destinations pins each send key to the machine its first try took
  (newest 64, kept in the app's defaults), so a retry names that machine and its tab key gets
  the first try's tab back instead of a second chat with the prompt on another machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(acpmux): a chat's first send that a revoked OAuth token failed goes again once, 2 s later

Leo (2026-10-30): "like the initial 0 to 1 chat auto it sends to cloud". On a fresh Cloud VM
the first Claude call failed once with "Failed to authenticate: OAuth token revoked" and the same
call 2 s later ran (cmux#28111 hand-walk, gap 5).

- claude_auth::is_revoked_token: only a revoked token, never expired/missing sign-in or an outage.
- hub/auto_resume/first_send.rs: on the chat's first turn only, and only for a prompt of its own
  (never a ~resume- attempt), the turn is resent once as P~resume-1 after 2 s through the Retry
  button's resend (retry_turn.rs resend_turn), under the chat's continuation mark, so Stop,
  close, a move or a person's prompt during the wait keep it from going. A retry that fails the
  same way is shown as before. Decisions are logged (first_send_retry, auto_resume_skipped).
- daemon/cloud_handoff.rs: such a turn is not reported failed before its retry is decided.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud.startChat): copy only a checked upload root, never copy a finished send again, create under the send's key

router-review BLOCK at 8b117be (gpt-6-astra), all three findings:

- [P1] The copy uploads the Git working copy that holds the page's folder. The pane now checks
  that upload root against its roots too (AgentPaneHandOff), hands it on as
  AgentPaneCloudStart.uploadRoot, and the App copies only that folder (CloudStartChat.uploads):
  a grant of /repo/paint never uploads /repo.
- [P1] Destinations records, per send key and machine, that the send's copy finished. A retry
  whose copy finished opens its chat by its tab key without pushing again, which would overwrite
  what the chat already changed there.
- [P2] A new machine for a send is created under AgentPaneCloudStart.createKey (from the send
  key), so a retry after a lost create answer gets the same machine, never a second VM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud.startChat): no await inside the upload root check's autoclosure (fleet compile)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud start): small-radius chips; picker test picks New Cloud Machine, not the Cloud row

The Cloud start card's chips were 999px capsules, which agent-pane-no-capsules
refuses; they are 4px small-radius rects now. The Sandboxed picker test found
the Cloud row's icon (data-kind="cloud", no data-mode) before New Cloud
Machine; it now matches the row element itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud start): the composer takes no edits while a Cloud start is out

The review of #28686 at 563e8aa blocked on this: the composer stayed
editable while the machine booted, later Returns were ignored, and on
success the host closed the tab with only the first prompt sent, so text
or files added meanwhile were lost. Now the box is inert while the start's
card says starting (both the chat composer and the New Tab box), and the
pane-wide paste-anywhere takes nothing then. A failed start ends it, and
the prompt is still in the composer to edit and send again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud start): a Cloud start's copy counts as its folder's history

The review of #28686 at 0638b7f blocked on this: a Cloud start copies
into <work root>/chats/<key>/<attempt>/<name>-<hash>, while the folder
default only matched <work root>/<name>-<hash>, so after a Cloud start the
next chat in that folder defaulted to This Mac. The matcher now also takes
the start's own place out of the path (withoutStartPlace).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* style: runLocationDefault test fits the formatter's line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud start): no typing, paste or file drop reaches the composer while a Cloud start is out

The review at f6094ea found two routes the inert box did not cover: New
Tab's type-anywhere still edited the field, and the page-wide file drop
(and paste) still staged attachments, which the tab then closed without
sending. The intake takes a `locked` option (paste and drop stage nothing
and the drop overlay stays hidden), and New Tab's type-anywhere and
paste-anywhere do nothing while `cloudStarting`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud start): Do not work in a project sends nothing to Cloud; dictation writes nothing during a start

The review at 53d7adf blocked on two:
- With Cloud picked and Do not work in a project, the send named no
  folder and the host fell back to the tab's inherited folder, copying a
  repository the person had just said not to work in. New Tab now refuses
  that send ("Cloud isn't available for this chat") and keeps the prompt.
  #29109's folderless start (`home: true`) is the way such a chat goes to
  Cloud.
- Dictation still wrote into the locked composer. Its field getter gives
  no field while a Cloud start is out, and New Tab's writeText does
  nothing then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
* cmux NEXT Cloud: pick a chat's machine from its folder (repo, ref, size, task kind), sent as autosize

A chat sent to Cloud no longer needs a machine or size choice: CloudWorkPick reads the chat's
folder (repo key and GitHub repo from the remote, branch and whether it is pushed, git object
size, root files, task kind, .cmux/machine.toml, Codex broker) and Move to Cloud with no machine
to reuse, and New Cloud Machine from a chat, send its autosize with POST /api/vm. The answer's
sizePick stays on the machine's session for the hand-off. Behind Labs preview features.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cmux NEXT Cloud pick: clone the upstream's branch name, no GitHub repo from a local remote, no pick on the app-server link

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cmux NEXT Cloud: cloud.startChat, a new chat's first send started in Cloud with no machine or environment prompt

The page's Send with Cloud picked asks the host (`cloud.startChat {task, cwd, harness?, model?, key}`),
with Sandboxed's guards (a new chat, the Send's gesture, the replacements held, one at a time;
both now share AgentPaneHandOff). The App takes a Cloud machine as Move to Cloud does (a new one
sized by CloudChatPick), copies the folder with Move to Cloud's sync, opens the chat on the machine
with the prompt seeded as the person's, and closes this Mac's unstarted tab. Behind Labs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: the page's folder is optional; the tab's own folder otherwise

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: a started chat keeps the pane's hold; the folder must exist; the hand-off body is main-actor

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* cloud.startChat: only a chat on this Mac starts one; the App checks the tab's daemon is local

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer: Cloud as where a new chat runs, a row at the top of the environment picker's Cloud section

Behind Labs. Picking it makes the first send call cloud.startChat; attachments are refused on
Cloud for now. Gallery: four states of the row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a Cloud pick not offered now is refused, never sent here; picking Cloud drops a saved environment and refocuses the prompt

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: tests for the picker's Cloud row, a saved environment dropped by a Cloud pick, and a refused send keeping its prompt

The not-offered refusal moves into cloudRun.ts so it is tested.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: format the new-tab test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: the folder a Cloud send copies is the one the chip names, also when the tab inherited home

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Gallery: the two other designs of where a new chat runs, gallery-only, beside the shipped Cloud row

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: one start at a time from a page; another Return while it waits starts nothing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Gallery: the switch design's group is a fieldset

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a new chat's run location defaults from its folder's newest chat

A folder whose newest chat went to a Cloud machine (a Cloud start or Move to
Cloud) opens new chats with Cloud picked; otherwise this Mac, as before. The
history is acpmux's chat list: a Cloud chat is matched to the folder by the
folder the app's copy made on the machine (CloudMoveFolder remoteName under
CloudMoveSetup workRoots). Labs only, and a pick in the pane always wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a new chat's carried-over Cloud is a default its folder may undo; archived chats are not history

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a carried-over Cloud is marked in the folder default's effect, per chat

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: no change while a Cloud start is out

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: the folder default looks again once a Cloud start ends

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud default: a chat starting here keeps the mode it starts with

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Composer Cloud: a chat starting in Cloud shows its progress under the message, as metadata

The card shows the message, a spinner with the step, and the folder, machine, secrets and network
as the host learns them (a cloudStartProgress push keyed by the start), never a modal. Three
layouts behind the cloud-start-look experiment (chips, fact rows, step list), compared in the
gallery's agent-pane.cloud-start. On the New Tab page it shows over the box, without the bubble.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: the host tells the page's card each step (machine, folder, opening) as the start reaches it

cloud.startChat pushes a cloudStartProgress event keyed by the page's send before it takes a
machine, copies the folder and opens the chat; the shared page host hands it to the bridge.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start card: spacing and sizes on the design token scale

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* AgentPageChats: the Cloud start runner's pane closure, typed (Xcode 26.6 could not type the map)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: the host pushes the folder and the machine's size; a failed card goes when the person picks another place

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start: format

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Environment picker: an Auto row and its scope line (1/2 of the #26151 fold)

The picker takes an `auto` choice from its caller: an Auto row at the top,
checked while Auto holds, and a scope line naming Auto's destination (an
experiment with three faces: destination with a quiet Auto tag, "Auto ·
destination", Auto's icon). Under Auto, Cloud is the folder's default, so
the Cloud row is not checked and Auto's row asks for the default back
(RunModeRows.onDefault) instead of a Persistent pick. Nothing passes
`auto` yet; the New Tab wiring is the next PR.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Environment picker Auto: its row shows checked; a machine row under Auto is an explicit pick

The Auto row draws its check while Auto holds. Under Auto, a machine row
that lands on a folder tells the caller the machine first (onComputer),
so the pick ends Auto, then the folder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Environment picker test: ⌥ New Cloud Machine is not the Cloud row

The Sandboxed test clicked the first Cloud-kind row, which since #26801
is the Cloud row heading the section (it failed the same way on
lane/run-location-default). It now clicks New Cloud Machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Auto scope gallery: the experiment's script opens the picker (an empty script does not load)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Auto scope gallery: covers AutoIcon

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Auto scope line: Auto · destination by default; the Cloud row's icon uncoloured

The captures show the tag face reading as "Cloud Auto" (the scope row's
text is already quiet, so the tag doesn't stand apart). "Auto · Cloud"
reads as one phrase and matches the picker's Auto row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Environment picker test: format

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* New Tab Auto: the folder's run location, moved only by an explicit request (2/2 of the #26151 fold)

Auto is selected on a new chat's New Tab page. It sends the prompt to the
folder's run location (Cloud when the folder's newest chat went to Cloud,
else this Mac), and only an explicit execution request moves it: a ready
machine's full name, an ask for cloud or remote work (the Cloud row), or
an ask to run locally. A Run as row, machine or saved environment ends
Auto; a folder pick keeps it; Auto picked again restores the folder
default in App. A Cloud refusal is said for the run it refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* New Tab Auto: the picker alone asks for the folder default; format

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* New Tab Auto: Auto reads the chip's folder; Cloud only when offered; a start out holds every send

- Auto's fallback is the run location of the folder the chip names, read
  on the page, so a folder picked there counts at once.
- Auto sends to the Cloud row only while Cloud is offered (App
  `cloudOffered`); `cloudStarting` reaches the page whatever Run as shows.
- A machine name before a sentence's full stop is a reference; one inside
  a longer host name is not.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* New Tab Auto: a possessive names the destination; a Cloud pick test picks on the page

"on my gpu-box", "on my remote server" and "on our VM" are destination
requests. The New Tab Cloud test picks Cloud on the page: under Auto, the
Cloud mode a tab comes with is a default, not a pick.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* Cloud start gallery: the experiment's script has one step (an empty one does not load)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6

* test(cloud): a start whose link came up while connecting asks the owner answer again

Red on feat-cmux-next: AgentSessionAttachClient.start reads the owner link
before it connects, so a new Cloud machine's first start (link not up yet)
or a down machine that reconnects on use fails closed with
agent_session.host_unverified, while Retry passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ca79ef955c62796a1ee

* Cloud agent start: ask the owner answer again on the live link instead of failing closed on a link that was coming up

Leo, on NEXT nightly 4113890 (classic link), New Agent Chat on a new Cloud
machine: "Couldn't start Codex: kind-aqua-sandpiper could not confirm what
kind of Cloud machine it is, so no agent chat starts there." Retry cleared it.

start() and trust() read CloudMachineLink.ownerLink before the connection.
When the link was not up yet, or came back while the call connected, that
read was nil or older than the link the call goes over, and the start was
refused. ownedConnection now drops that connection and takes both reads
again around a new one, at most 3 times with no wait: the answer still
brackets the making of the connection the call is sent on, and a link that
never answers owner (a team machine) is refused as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ca79ef955c62796a1ee

* test(cloud): an owner word goes only on a connection made inside the owner reads; an attachment is never told a retired one ended

Review (codex gpt-6-astra high) BLOCK at e038bc3: the first try could reuse
a connection made before the first read, and retiring a connection told an
attached page it ended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ca79ef955c62796a1ee

* Cloud agent start: count only a connection made after the first owner read, and retire a dropped one silently

Fixes the review's two blockers: a connection begun before the first read
(an earlier call's, or one joined in flight) is retired and remade inside the
reads, and a retired connection's close tells no attachment. A client with an
attachment keeps its connection and is refused instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-8ca79ef955c62796a1ee

* cloud.startChat: the machine's chat starts on the picked model; type the seed's Cloud runner for Xcode 26.6

next-review's P2: CloudStartChat built the remote seed with the harness and prompt only,
so the model the page picked was dropped. AgentPaneCloudStart.seed(cwd:) now builds it
with the model too, with a test. The request carries no effort, so there is none to forward.

AgentPageChats.seed's Cloud runner is written out with its type, as #26921 does: #26921
found Xcode 26.6 could not type the map form.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-22973a84aab760788504

* cloud.startChat: a retry opens the same tab on the machine; the folder check reads off the main thread

next-review's BLOCK at b3389d1 (Codex gpt-6-astra): CloudStartChat opened the machine's
chat tab with a fresh creation key, so a retry of the same send after a lost answer could
make a second chat and send the prompt twice. The tab's key is now the send's own
(AgentPaneCloudStart.tabKey), with a test that a retry's key matches and another send's
does not.

The folder check (FileManager.fileExists) ran on the main actor; it now runs in a
@Concurrent helper (guardrails main-blocking).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-22973a84aab760788504

* cloud.startChat: copy only a folder the pane may name, each send into its own copy on the machine

Two blocking findings from the Codex review of #28686, both in this PR's code:

- The page named the folder whose tree is copied to Cloud, and the host only checked that it was
  absolute. A page script could name any folder on this Mac. The hand-off now takes the folder's
  canonical path (realpath, off the main actor) only when it is inside one of the pane's roots by
  components, the same roots AcpmuxPathPolicy uses for a chat that starts here: the pane's own and
  the New Tab scan's, never home or above it, plus the folders the person added. Anything else is
  refused with transport.path_outside_roots before the hold and the gesture. No folder from the
  page still means the tab's own folder, which the host reads.
- Every Cloud start from the same folder synced into the same folder on a reused machine, and
  Move to Cloud's sync overwrites every file the machine changed, so a second Cloud chat could
  write over the first one's work. A start now copies into its own place under the work root
  (chats/<send key>). A retry of the same send lands in the same copy.

Tests: a folder outside the roots, a link out of a root, a `..` path out of it, a missing
folder, the disk's root, home, and a folder under home when the pane's folder is home are all
refused and never reach the runner. The root's own folder still starts with its canonical path,
and a send's place is its own and stable for a retry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-672a743921bc7917cca7

* fix(cloud.startChat): a first send takes this person's free machine, and its retry stays there

Leo (2026-10-30): "like the initial 0 to 1 chat auto it sends to cloud".

- The machine: never the team's first connected one (often someone's busy lane VM). A machine
  this person created that is free (no chat open, or idle-paused) or named for chats
  (cloud-chats[-N]), else a new one named cloud-chats. Lane-pool VMs (fs-lane-N, lane-vm-N)
  are never picked.
- #28845: CloudStartChat.Destinations pins each send key to the machine its first try took
  (newest 64, kept in the app's defaults), so a retry names that machine and its tab key gets
  the first try's tab back instead of a second chat with the prompt on another machine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(acpmux): a chat's first send that a revoked OAuth token failed goes again once, 2 s later

Leo (2026-10-30): "like the initial 0 to 1 chat auto it sends to cloud". On a fresh Cloud VM
the first Claude call failed once with "Failed to authenticate: OAuth token revoked" and the same
call 2 s later ran (cmux#28111 hand-walk, gap 5).

- claude_auth::is_revoked_token: only a revoked token, never expired/missing sign-in or an outage.
- hub/auto_resume/first_send.rs: on the chat's first turn only, and only for a prompt of its own
  (never a ~resume- attempt), the turn is resent once as P~resume-1 after 2 s through the Retry
  button's resend (retry_turn.rs resend_turn), under the chat's continuation mark, so Stop,
  close, a move or a person's prompt during the wait keep it from going. A retry that fails the
  same way is shown as before. Decisions are logged (first_send_retry, auto_resume_skipped).
- daemon/cloud_handoff.rs: such a turn is not reported failed before its retry is decided.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* test(cloud): cover signed NEXT DEV channel defaults

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* fix(cloud.startChat): copy only a checked upload root, never copy a finished send again, create under the send's key

router-review BLOCK at 8b117be (gpt-6-astra), all three findings:

- [P1] The copy uploads the Git working copy that holds the page's folder. The pane now checks
  that upload root against its roots too (AgentPaneHandOff), hands it on as
  AgentPaneCloudStart.uploadRoot, and the App copies only that folder (CloudStartChat.uploads):
  a grant of /repo/paint never uploads /repo.
- [P1] Destinations records, per send key and machine, that the send's copy finished. A retry
  whose copy finished opens its chat by its tab key without pushing again, which would overwrite
  what the chat already changed there.
- [P2] A new machine for a send is created under AgentPaneCloudStart.createKey (from the send
  key), so a retry after a lost create answer gets the same machine, never a second VM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* fix(cloud): default signed NEXT DEV to the development app-server link

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* fix(cloud.startChat): no await inside the upload root check's autoclosure (fleet compile)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-3bab30503f0b9a7059e5

* test(cloud): prevent signed DEV from restoring production credentials

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* fix(cloud): isolate signed DEV staging authentication persistence

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* cloud link: add authenticated credential socket producer

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* cloud link: relay connect info and dial tokens

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* cloud link: harden credential socket and generation fencing

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* cloud link: isolate endpoint lifecycle and add relay fences

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* cloud link: fix relay initializer call order

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* fix(web): allow signed NEXT DEV auth callbacks

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a43a05e083d615505d02

* fix(web): scope NEXT DEV callback to staging

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a43a05e083d615505d02

* cloud link: type startup continuation

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* Integrate NEXT Worker creator ownership from #28789

Carry the Worker-only changes from 90be2e6 and a8a78db into the held new Cloud DEV integration.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Port root-owned Native guest receiver authority and lifecycle

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Include signed Native receiver interoperability fixture

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Use checked filesystem access for the bounded Cloud upload-root search

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Keep every Cloud upload-root read off the main actor

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* cloud link: own relay work and use checked concurrency seams

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* Preserve authenticated token issue times at the daemon boundary

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* cloud link: fit private endpoint to Darwin runtime paths

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* cloud link: avoid async closure default argument

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* Attach the Native receiver to the root-owned daemon startup

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Keep guest-only parent channel gated to Linux

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* cloud image: opt in to the root Native receiver

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* Keep Native smoke clones owned during probe failures

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* Probe Native support through the host help verb

Agent-Session: https://cmux.com/deeplink/agent?id=aid-8d2fb03d72fa2712cb2f

* Record reviewed temporary Cloud composition exception

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Spawn the Native receiver through the descriptor-safe process wrapper

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Record the reviewed held-child identity check

Independent review confirmed that supervised.rs reads only the pid from the retained Child after try_wait, compares captured start ticks, and never enumerates processes or accepts an external pid. Keep this exact single-pid authentication read as the PID-reuse fence; retain the child handle and process_start checks.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Keep receiving service conversion non-panicking

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Exercise handshake capacity reclamation before valid admission

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* cloud: add native receiver policy and dial authorization

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* cloud: read native mesh metadata for receiver policy

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* cloud: expose team authority version helper for network peers

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* cloud: authorize Native connect info and link tokens

Agent-Session: https://cmux.com/deeplink/agent?id=aid-5731063c82fc91125b46

* cloud: attach VM API machines to pinned Native mesh

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: wire native link authority and network provider contract

Agent-Session: https://cmux.com/deeplink/agent?id=aid-5731063c82fc91125b46

* Include the private Unix descriptor transfer dependency

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* test(cloud): cover native link token through CloudDO route

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* test(cloud): add mesh machine fixture for native route

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* Preserve Native client and receiver claims in signed Cloud tokens

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* protocol: carry Native network and proof fields

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: expose TeamDO Native dial authority RPCs

Agent-Session: https://cmux.com/deeplink/agent?id=aid-5731063c82fc91125b46

* cloud link: wire outgoing Native broker

Agent-Session: https://cmux.com/deeplink/agent?id=aid-f0d3ce2f11e1a4c5b647

* test(protocol): validate Native network and proof schemas

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: persist confirmed network on create result

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* Dispatch Native receiver and device policy through owner objects

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* cloud: expose UserDO network identities with grant authority

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* fix(cloud): honor install authority while checking live grants

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* test(cloud): cover UserDO network identity projection

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* Accept the current Worker signed machine-role claim in Native tokens

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Route Native VM receiver operations through the Worker API

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Compose the Native device and owned link into Cloud lifecycle

Integrates the Swift route from ed12bb900b5ef2e651cd657f4cea8a8af73663ef and dc45703a91e4 with current resolver and composer code.

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Use the authenticated Worker team for Native app enrollment

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* cloud: persist install authority in UserDO state and principals

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* test(cloud): fence user identity after install revocation

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* fix(mac): add native broker descriptor and stream transport

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* cloud link: retain vm role on fresh grants

Agent-Session: https://cmux.com/deeplink/agent?id=aid-f0d3ce2f11e1a4c5b647

* protocol: expose host network target and policy reads

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: add install authority read and socket fanout helpers

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* cloud: consume install authority notices and fan out socket rechecks

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* Bind Native owner gates to the authenticated connection role

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c

* Preserve signed Native roles through the receiver handoff

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* Record reviewed Native lifecycle composition delta

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* fix(mac): route native startup blocking work through lanes

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* fix(mac): cancel native descriptor receive task

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* cloud: let owners recheck install authority sockets

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* cloud: stamp accepted sockets with install authority

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3a7046c2f0c9a8188eb8

* Use existing durable socket revocation for authority changes

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Retain socket attachment type in UserDO

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Scope Native blocking work to its route lifetime

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Close stale socket admission without throwing from the upgrade

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Admit signed Native owners through the first-chat carrier

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c

* Preserve bounded ChildProcess input initializer alongside Native sockets

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Test existing child stdin delivery alongside Native process support

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* fix(mac): narrow Native remote handshake capabilities

Agent-Session: https://cmux.com/deeplink/agent?id=aid-4a652051ce0456e674d7

* Drop unused historical writer after preserving bounded stdin API

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Apply Native handshake requirements to the app-server path

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Expose Native route session token type at package scope

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* cloud: fence membership authority changes

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* Scope client public-key discovery to its read grant

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Expose Foundation parameter types in Native route package API

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* fix(cloud): pass Native handshake capabilities in initializer order

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* fix(cloud): restore verified Native policy reads for callers

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* Carry GUI terminal attachment operations for signed Native owners

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c

* Limit Native terminal policy changes to the GUI latest mode

Agent-Session: https://cmux.com/deeplink/agent?id=aid-a488ee6f4b3a9aa8a31c

* Use the transfer host test fixture from its defining module

Agent-Session: https://cmux.com/deeplink/agent?id=aid-7874a399566b24c5caa4

* protocol: export Native VM receiver schemas and retain grants

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* fix(cloud): export personal tenant metadata and park

Agent-Session: https://cmux.com/deeplink/agent?id=aid-5731063c82fc91125b46

* cloud: consume team authority notices and close receivers

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: fence all receivers on member authority changes

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* cloud: paginate receiver authority fences

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* test(cloud): cover reducer membership ABA authority

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* test(cloud): persist authority reducer ABA state

Agent-Session: https://cmux.com/deeplink/agent?id=aid-3c1de57a1d612657bbf7

* protocol: regenerate network grant clients

Agent-Session: https://cmux.com/deeplink/agent?id=aid-34a78e5e41128ce4751e

* fix(cloud): deduplicate receiver store import after authority integration

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* ci: add NEXT new-link cloud create E2E

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* ci: route cloud e2e through linux picker

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* ci: use the fleet Linux runner picker

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* ci: run cloud new-link e2e on integration pushes

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* ci: use available overflow size for cloud e2e

Agent-Session: https://cmux.com/deeplink/agent?id=aid-507297375d7253744aa7

* cmux-link: declare sign_clone again (macOS builds)

An earlier integration merge dropped `mod sign_clone` from lib.rs while
caller_macos.rs still uses it, so both macOS cmux-tui artifact builds failed
with E0433 (run 41221404196).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* Native link: check the bundle's signature on the blocking lane

NativeCloudExecutable's SecStaticCodeCheckValidity hashes the app bundle and
cmux-tui. NativeCloudLinkChild.launch built it on the actor's executor; it now
runs on the child's BackgroundWork lane (mayBlock: .system), and the call
carries the reviewed concurrency-allow the main-thread checker asks for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* backend: a host network binding keeps the install grant Native dials check

host-network-bind passed the grant, but HostNetworkBoundParams dropped it and
reduceHostNetworkBound never wrote network.install_grant, so every binding
failed cloud-native-dial's grant check and no Native token was issued
(router-review BLOCK at 1d89f03). The params carry the grant (optional,
so older ledger entries decode), and a confirmed binding under a new or
missing grant records it instead of answering unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cmux-app-host: regenerate the app global after the base merge

bun tools/gen-cmux-global.ts: ops.json, scopes.json and cmux-app.d.ts were
stale (app platform check at 1d89f03).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* ci and app platform: fix reds that surfaced once the PR merged cleanly

- cloud-newlink-e2e.yml: the upload-artifact pin dropped one character of
  v7.0.1's sha (workflows.test.ts).
- cmux-tui-spec.yml: push and pull_request paths include schemas/link-token
  native.json and vectors.json, inputs of acpmux's tests
  (test_cargo_test_verdict.py); native.json joins the tree key inputs.
- CmuxNextApps AppPlatform scopes.json synced from the regenerated app global
  (scripts/cmux-next/sync-app-runtime.sh).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: every non-production build defaults to the new cloud, no env vars

Leo: "i dont wanna do this / make it more ergonomic" (on launching a DEV build
with CMUX_NEXT_CLOUD_LINK=app). Debug and tagged fleet builds now default to the
app-server link, staging sign-in and the development Worker
(https://cmux-api-development.debussy.workers.dev). Baked loopback origins are
ignored unless the launch sets CMUX_NEXT_CLOUD_BACKEND=local; non-loopback env
values, CMUX_NEXT_CLOUD_LINK=legacy and CMUX_NEXT_FEED_API_URL stay overrides.
Staging sign-in accepts the cmux-dev and cmux-dev-<tag> callback schemes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* tests: drop the test that asserted the classic link is the Debug default

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cmux-tui CLI: test that every waitsForPerson action gets the person timeout

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cmux-tui CLI: cloud start-session waits the person deadline, not 45 s

The app gives cloudStartSession (and app install/remove, classic import)
personDeadline (200 s), but the CLI gave up at 45 s, so a start-session on
a machine still coming up answered mutation.outcome_unknown and opened no
chat (pr-capture-cloud run 41267442022).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: the app server link runs cmux link again; the Native route is opt-in

3ec47d8 swapped base's CloudLinkLauncher for CloudNativeRouteHolder on
every app-server build. That holder first reads the team's Native mesh
(host.network.target); the dev Worker answers 400 for an account without
one, so 'cloud link ensure failed: refused(400)', the link never starts and
every machine connect fails (cloud start-session: "didn't connect";
pr-capture-cloud at b9a327f). The Native route stays available behind
CMUX_NEXT_CLOUD_NATIVE_LINK=1, as #28947 describes it (opt-in).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* wip: native default

Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* wip: drop Auto webview (lives in #26941)

Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* protocol: regenerate the catalog and clients after the base merge

Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: a non-production build takes the Native route first, cmux link as its fallback

The capture team's development Worker now has a Native mesh (cmux-platform #405), so a
non-production build's app server link takes the Native device route by default. A team the
Worker has no Native mesh for keeps a machine: the first Native failure falls back to
`cmux link` until sign-out. Production keeps `cmux link`. CMUX_NEXT_CLOUD_NATIVE_LINK=0 keeps
`cmux link`, =1 forces Native with no fallback.

Not run: CloudNativeFirstLauncherTests (fleet step pending).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* merge repair: drop blocks the base merge doubled; cmux backend/apps stays base's

The -X theirs base merge kept both copies of code that both sides added
(CloudLinkLauncher's credential socket helpers, cmux-host's test modules,
server.rs's native_owner, user.ts's liveInstallGrant). The cmux backend/apps
changes this branch carried landed through their own PRs and cmux-platform, so
they take base's copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* merge repair: fs_wire's admit_native_owner was doubled by the base merge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: name the link's build apart from init's own build local

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* merge repair: the Mac link's Native broker wiring and start-session's person timeout

The -X theirs base merge took base's side of the conflicting hunks, which
dropped this branch's outgoing Native broker (cloud_broker channel and run,
native_broker and native_route modules, CloudSource, serve's broker) and
cloud start-session's place in PERSON_ACTIONS with its catalog test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: the Native route is opt-in again, with cmux link as its fallback

Review at 30a7996 (BLOCK, P1): a team that has a Native mesh can still hold
machines made on the direct transport. Their connect_info carries no Native network,
and the Native link cannot dial them, while a startup-only fallback never reaches
cmux link. Development also took the capture team back off the VM API (cmux-platform
#471), so Native is not the default for any build. CMUX_NEXT_CLOUD_NATIVE_LINK=1
takes Native first, and falls back to cmux link when it does not start.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: a debug build's owner API is the development Worker in CloudShareAPITests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

* cloud: a development Cloud owner's previews come from cmux-platform-development

#28950 made debug builds' owner API the development Worker, so platformPreviewAPIBaseURL
(staging-only) returned nil and CloudLivePreviewTests failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — d1838f32 Deployed Oct 28, 2026 by teamleaderleo via wait for same-key tree publisher #70908
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant