Skip to content

Cloud start: no Cloud default in a fresh SSH or peer tab; translate the Start New Chats In: Cloud choice - #29109

Merged
teamleaderleo merged 58 commits into
feat-cmux-nextfrom
lane/start-chats-in-cloud
Nov 1, 2026
Merged

teamleaderleo merged 58 commits into
feat-cmux-nextfrom
lane/start-chats-in-cloud

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to #29669, which carried this PR's feature (Settings > General > Agent Chat > Start New Chats In: This Mac / Cloud) onto feat-cmux-next. After merging base, this PR keeps base for everything #29669 landed and adds only two things on top:

  1. No Cloud default in a tab on another machine, even before its summary arrives (Start New Chats In: Cloud should not apply to new tabs on remote panes #29144). With Start New Chats In set to Cloud, a fresh SSH or peer tab could pick the Cloud run default before its summary said it was remote, so its first send would go to cloud.startChat, which the host refuses there. webviews/src/agent-session/acpmux/App.tsx now also reads the snapshot's origin (remote or peer), which a fresh connection has before any summary.
  2. The Cloud choice translated. settings.choice.newChatsInCloud was "Cloud" in every locale; it now has a translation in each (still needs_review). de, fr and it keep "Cloud", with the reason recorded in scripts/localization-allowed-omissions.json.

agentPane.newChatsIn stays refused to agents, the way base has it (.privacy in the agent policy, agent_settable: false in schemas/settings/settings-schema.json). The branch's earlier commit that let agents set it is gone in the merge: an agent could have sent future chats to Cloud, which goes against the setting's privacy policy (review BLOCK at 64edec6). The merge also keeps #29582 (cloud.startChat's pick moved into cmux-tui; this branch's now-unused chats-machine name helpers are dropped), #29785, #29789, #29771 and #29529's eased-follow test tolerance.

Leo, 2026-10-31: "whenever i start a chat it should be able to send me to cloud autommatically keep launching/downloading new dev builds and such".

Risk: small. One web conditional and localization data. No Swift source changes compared with base.

Agent session: agent session
🤖 Generated with Claude Code

teamleaderleo and others added 30 commits October 28, 2026 00:23
…ze, 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
…o 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
…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
…t 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
…he 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
…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
…, 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
…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
…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
…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
… 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
…r, 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
…6.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
…led 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
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…ne does not load)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-4ba8980ae4e8eecb82d6
…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
@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@cmux-bot cmux-bot Bot removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
The localization debt ratchet counted the new Cloud choice as copied
English in every locale. Use the translations the other Cloud labels
already use, and document Cloud as the established noun in de, fr and it.

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

Copy link
Copy Markdown
Collaborator Author

Awareness note from an agent lane that does not own this PR; it is not a review or a request to take the PR over.


Carried with the original commits and authorship into #29669 to finish landing after the original lane retired. The carry restores the base streaming-animation test tolerance and is receiving an independent head review and fleet validation. This PR remains open for its owner to close.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at f027666

BLOCK at f027666

Visual verdict: no images; Leo tries the build

  1. [P1][blocking] schemas/settings/settings-schema.json:88094 is stale. SettingsSchema+AgentPolicy.swift:331 marks agentPane.newChatsIn as .privacy, so SettingsSchemaExportTests.exportIsFresh regenerates "agent_refusal": "privacy", while the checked-in export has null. The settings export CI test will fail.

  2. [P1][follow-up] Fresh SSH/Cloud tabs can still default to Cloud. App.tsx:8016 detects remote chats only from summary.peer/hostKind; fresh remote connections expose snapshot.origin before a summary exists. folderRunDefault then enables Cloud at line 8365, and the first send calls cloud.startChat, which the host rejects instead of keeping the chat on its current machine.

Follow-ups:

  • [P1][follow-up] Include snapshot.origin === "remote" || snapshot.origin === "peer" in the remote-chat guard.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
teamleaderleo added a commit that referenced this pull request Oct 31, 2026
…arry #29109) (#29669)

* 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

* feat(cloud): Start New Chats In: This Mac / Cloud (agentPane.newChatsIn)

Leo, 2026-10-31: "whenever i start a chat it should be able to send me to cloud
autommatically". A setting, off (This Mac) by default; set to Cloud, a new chat's
run location defaults to Cloud and its first send runs cloud.startChat. The
composer's environment picker (This Mac / Cloud) overrides it for one chat.
A chat with no project starts in the machine's own folder with nothing copied.
Cloud's start is no longer behind Labs.

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

* chore(settings): regenerate exports for agentPane.newChatsIn

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

* fix(cloud): Sandboxed stays behind Labs when only the setting offers Cloud; no copy step for a no-project start

Review BLOCK at 4f6d4a5 (router-review, gpt-6-astra): [P1] Start New Chats In: Cloud
exposed Sandboxed with Labs off; [P2] a no-project start's step list showed the copy step.

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

* test(cloud): the Cloud-only picker test takes KeyboardEvent from its DOM

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

* fix(cloud start): a no-project start compiles, rechecks the account, and never copies agent-home

The review of #29109 at 21b19e1 blocked on three:
- runHome called machine(for:invocation:pick:) without the `account:`
  base added, so the target did not compile.
- runHome did not check the account after the machine connected; it now
  does, as a start with a folder does, so an account switch meanwhile
  opens nothing on the old account's machine.
- cloudStartFolder sent a no-project chat's private agent-home folder as
  a project to copy; it is `home` now (sessionList.ts isAgentHome).

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

* refactor(cloud start): a no-project start shares run's open step; the chats machine names move to CmuxNextAgentPane

runHome duplicated run's tail (open the chat on the machine, select it,
close this Mac's tab); both now call one `open(_:tab:on:cwd:)`. With the
pure machine-name rules (chatsName, isMarkedForChats, isLanePool,
newMachineName) moved to CmuxNextAgentPane beside #29566's Step and
sizeText, CmuxNextApp is 8 lines smaller than base, so arch-ratchet's
app_lines row (which #28686 tripped) holds.

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

* refactor(cloud start): drop RunModeRows.cloudOnly; Sandboxed is not behind Labs since #29059

cloudOnly kept Sandboxed out of the picker when only the setting offered
Cloud, because the host refused sandbox.run without Labs. #29059 took
that gate out, so nothing set it and the guard was unreachable (the
review at 01d58a2). The picker is base's again.

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

* fix(cloud start): newChatsIn has an agent policy; a tab on another machine never defaults to Cloud

The review at 3c558fc blocked on two:
- agentPane.newChatsIn was in neither agent-policy table, so
  SettingsSchemaExportTests.everyKeyHasAnExplicitAgentPolicy failed. It is
  refused to agents as .privacy: it decides whether a chat's project is
  copied to a Cloud machine.
- With Start New Chats In: Cloud, a fresh SSH or Cloud tab defaulted to
  Cloud, and its first send went to cloud.startChat, which the host
  refuses there. The run-location default now applies only to tabs on
  this Mac.

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

* Keep the base streaming test tolerance in Cloud first-send carry

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

---------

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

- agentPane.newChatsIn joins the agent-settable composer keys, so
  `cmux settings set agentPane.newChatsIn cloud` works from a lane or an
  agent; each chat's composer still shows and can change the choice.
  The settings export says agent_settable, and a test sets it through
  the cli and mcp writers.
- The Cloud run default also stays off in a fresh SSH or peer tab whose
  origin is known before its summary (review follow-up on #29109).

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

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, router-review): BLOCK at 64edec6

BLOCK at 64edec6

Visual verdict: no images; Leo tries the build

  1. [P1][blocking] Generated settings schema is stale. agentPane.newChatsIn is marked agent-settable in Swift, but schemas/settings/settings-schema.json:88173-88189 still exposes only MCP read operations and says agent_settable_false. SettingsSchemaExportTests will fail, and MCP clients cannot set the setting as intended.

  2. [P1][blocking] Agents can redirect future chats to Cloud despite the PR’s privacy policy. AgentPaneComposerSetting.swift:204-210 adds newChatsIn to agent-settable keys, and the test explicitly permits an MCP writer (AgentPaneNewChatsInSettingTests.swift:50-54). An agent can persist "cloud"; subsequent fresh chats then default to Cloud and copy their projects there (App.tsx:8363-8369). The PR description says this setting is refused to agents because it controls private data egress.

Follow-ups: none

…refused to agents

#29669 already landed this PR's feature on base, with agentPane.newChatsIn refused to
agents (.privacy) and the settings export saying agent_settable false. The merge keeps
base for every conflict, which also drops this branch's 64edec6 change that made the
key agent-settable (review BLOCK at 64edec6: it lets an agent send future chats to
Cloud). It keeps #29582's cmux-tui pick (the now-dead chats machine helpers go) and
#29529's eased follow tolerance.

What this PR still adds over base:
- the Cloud run default stays off in a fresh SSH or peer tab whose origin is known
  before its summary (#29144);
- the Start New Chats In: Cloud choice translated, with de/fr/it identity reasons.

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

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 4263fc1

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

Follow-ups: 1. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at 4263fc1
Visual verdict: no images; Leo tries the build

No correctness findings. Catalog lint and targeted routing checks passed. The localization-debt failure also exists in the reconstructed base. Full web tests were unavailable because Bun and dependencies are absent.

  1. [P2] [follow-up] App.tsx:8562: No after screenshots were supplied. Verify fresh SSH and Cloud tabs with “Start New Chats In: Cloud” enabled.

Follow-ups:

  • Verify those remote-tab states in the build and capture screenshots.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 83b17bd

Reviewer: codex gpt-6.1-sol xhigh, fast tier.

Follow-ups: 2. Each lands as an issue in this repo that links this receipt; the lane that opened the PR fixes it forward.

SHIP at 83b17bd

Visual verdict: no images; Leo tries the build

  1. [P1] [follow-up] [App.tsx:8613] Seeded peer tabs still appear local before their summary: snapshot.origin is local, while the destination remains in newChatPeer(). With newChatsIn=cloud, the pane still defaults to Cloud and the first send reaches cloud.startChat, which the native host rejects for remote tabs.

  2. [P2] [follow-up] [review/images/README.txt] No after screenshots were supplied, so visual comparison was unavailable.

Follow-ups:

  • [P1] [follow-up] Include the pending peer destination when computing onOtherMachine.
  • [P2] [follow-up] Provide after screenshots for visual review.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cmux-bot approves 83b17bd: an independent review passed this exact head (router-review receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

This branch was previously deployed

3 inactive (2 outdated) deployments
ci-routing-agent — 83b17bdd Deployed Nov 1, 2026 by teamleaderleo via wait for same-key tree publisher #93228
artifacts — 64edec6c Deployed Oct 31, 2026 by teamleaderleo via add the Windows daemon to the tree #91775
sentry-dsyms — 64edec6c Deployed Oct 31, 2026 by teamleaderleo via upload cmux-tui dSYMs to Sentry #91775
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant