Skip to content

cmux NEXT Cloud: a person's own Cloud send creates the machine with no second approval prompt - #32270

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/cloud-person-create-no-approval-prompt
Nov 2, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
lane/cloud-person-create-no-approval-prompt

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

Picking Cloud in the composer and sending now creates the machine and starts the chat with no second "Create a Cloud machine?" dialog.

Leo: "we have the roadmap in place to have it go more like chatgpt work right where you just pick the cloud button or whatever and then it just works?" and "i don't really give a stuff about tests or whatever im just trying to use the thing / in the gui".

Why it stopped

Since #28950 / #28899, DEV and nightly builds create Cloud machines through the app-server link, so the Mac relay sends cloud.machine.create with its install token. The backend holds every install's money op for the person's approval (approval.pending), by design. CloudMachineCreateFlow.create set confirmed = !startedByPerson, so for the person's own Cloud send it showed the native "Create a Cloud machine?" confirmation on that hold. The Cloud start-chat capture passed at 51832a5 (legacy create, reply read back) and sat on that dialog at 1e057e0.

Fix

A create the person started (the composer's Cloud send, a menu, the palette, invocation.origin == .user) counts as their confirmation, so the flow answers the hold as the person's session right away. Unchanged:

  • Creates nobody started (agents, the CLI, scripts: startedByPerson == false) still show the agent-request confirmation first, and a no sends nothing.
  • The server's approval stays: the install still cannot create on its own; the answer goes as the person's session for exactly that request.
  • Plan and billing gates (.upgrade, plan_required, limits) are unchanged.
  • approvedCall (environment build and delete) still asks.

Takes back #32271: a person's create no longer shows the approval sheet its watch closed.
Takes back #32300: the same watch's follow-up; the answered-elsewhere case is now handled in the approval loop (a closed feed item goes to the same-key retries).

#32271 and #32300 closed the "Create a Cloud machine?" approval sheet when the hold was answered on another device. A person's create no longer shows that sheet, so nothing reached the watch; its code (CloudMachineCreateFlow.confirmUnlessAnsweredElsewhere, watchPause, CloudWait.firstAnswer/untilAnswered), its test suite and its arch exception go. CmuxDialogCenter's cancel-to-dismiss stays.

Test

CloudPersonCreateApprovalTests (new): a person's held create gets no prompt and is answered once; an agent's create asks once; a declined agent request sends nothing. Red at the test commit 42d8875, green at the head (fleet runs below).

Observed / Not run

  • Fleet Swift (run-swift-testing-suites.sh, suites CloudPersonCreateApprovalTests, CloudEnvironmentBootFlowTests, CloudCreateRetryKeyTests): red at 42d8875 (CloudPersonCreateApprovalTests failed, the other two passed), all three pass at fa2c09d, 21eb537 and 81df298 (with the answered-elsewhere tests aHoldAnsweredElsewhereFirstGoesOnWithTheSameKey, aClosedItemWhoseHoldStaysPendingEndsStillPending, added for the router-review BLOCK at 21eb537).
  • Cloud start-chat capture at fa2c09d (fixture team): no dialog after the send (debug.dialog empty at 1, 2.5 and 4 min); the create went through approval and made machine cloud-chats-2, whose start then failed with "cloud-chats-2 didn't connect. Retry once it's online." That later failure is a separate issue, not caused by this change.

Changelog

Fixed: Sending a new chat to Cloud no longer stops on a second "Create a Cloud machine?" confirmation.

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 3 commits November 2, 2026 04:43
… no second prompt

The composer's Cloud send (and every other create a person starts) already is the
person's confirmation. On the app-server link the backend holds an install's
cloud.machine.create for G8 approval; the flow now answers that request as the
person's session without showing "Create a Cloud machine?" again. Creates nobody
started (agents, CLI, scripts) still ask first, and a no sends nothing.

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>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240
@teamleaderleo teamleaderleo added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 2, 2026
@cursor

cursor Bot commented Nov 2, 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.

@github-actions

github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

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

Review 4e39e0c: HQ feed card · gallery before/after runs · checks

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

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr32270 -f ref=lane/cloud-person-create-no-approval-prompt -f platform=macos -f backend_mode=local

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@blacksmith-sh

blacksmith-sh Bot commented Nov 2, 2026

Copy link
Copy Markdown

Found 1 test failure on Blacksmith runners:

Failure

Test View Logs
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)/
test_the_nightly_is_covered (main.NightlyStepCoverageTests.test_the_nightly_is_cove
red)
View Logs

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

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at fa2c09d

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

SHIP at fa2c09d

Visual verdict: no images; Leo tries the build

Checked the approval flow, app-server call sites, retry/environment behavior, and added tests; found no correctness issues.

Follow-ups: none

cmux-bot[bot]
cmux-bot Bot previously approved these changes Nov 2, 2026

@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 fa2c09d: 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.

@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 2, 2026 13:04 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 2, 2026 13:04 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 2, 2026 13:05 Inactive
@cmux-bot
cmux-bot Bot dismissed their stale review November 2, 2026 13:15

A newer verdict blocks 2514c0d (no independent SHIP at the head).

…he sheet's answered-elsewhere watch goes

Takes back #32271 and #32300: their watch raced the "Create a Cloud machine?" approval sheet
against an answer from another device. A create the person started now shows no such sheet
(their own gesture is the confirmation), so nothing reaches the watch; its code, tests and
arch exception go. CmuxDialogCenter's cancel-to-dismiss stays.

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

Copy link
Copy Markdown
Collaborator Author

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

BLOCK at 21eb537

Visual verdict: no images; Leo tries the build

  1. [P1][blocking] CloudMachineCreateFlow.swift:154 — Removing the answered-elsewhere watcher regresses concurrent approvals. If another device answers after approval.pending but before this Mac lists the feed item, approve throws .mismatch(..., closedItem). The catch only treats closedItem as success when answering is already persisted, so the initial create fails even though the backend proceeds. Preserve a same-key retry/answered-elsewhere path for this race.

…on with the same key

Review (gpt-6-astra) on #32270: with the sheet gone, a hold the person answered on another
device in the moment before this Mac lists its feed item made approve throw a closed-item
mismatch and failed the create. Now the bounded same-key retries read the op's answer; nothing
is recorded as answered here, and a hold that stays pending still ends stillPending.

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

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 81df298

Reviewer: codex gpt-6-astra high, fast tier.

SHIP at 81df298

Visual verdict: no images; Leo tries the build

Checked flow, call sites, retry state, and removed API references. Swift/Xcode tests were unavailable in this environment.

Follow-ups: none

…person-create-no-approval-prompt

# Conflicts:
#	Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/CloudApprovalAnsweredElsewhereTests.swift
@cursor

cursor Bot commented Nov 2, 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.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex, router-review): SHIP at 4e39e0c

Reviewer: codex gpt-6-astra high, fast tier.

SHIP at 4e39e0c

Visual verdict: no images; Leo tries the build

No correctness findings.

Follow-ups: none

@teamleaderleo
teamleaderleo merged commit 3626cb1 into feat-cmux-next Nov 2, 2026
206 of 211 checks passed
@teamleaderleo
teamleaderleo deleted the lane/cloud-person-create-no-approval-prompt branch November 2, 2026 14:14
lawrencecchen added a commit that referenced this pull request Nov 2, 2026
…closed item mean answered; another team's still fails (#32354)

After merging #32270 (no sheet for a person's create; every closed-item
mismatch went to the same-key retries):
- CloudApprovalAnswer answers .answered(request) for this team's closed
  item and for a hold the feed push already shows answered (no lookup,
  no answer); another team's item stays the closed-item mismatch.
- The flow's answered-elsewhere path takes only .answered, so a true team
  mismatch fails at once again instead of retrying into stillPending.
- alreadyAnswered/answeredElsewhere move to CloudApprovalAnswer.Failure
  (CmuxNextDaemonService); CloudApprovalSheet goes (no sheet to race).
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
…wered left base with #32270)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-b3ddf8ea0a5ba6fad749
teamleaderleo added a commit that referenced this pull request Nov 2, 2026
… creator first (#32418)

* Cloud: a start waits for a new machine to run, and running retries a connect that failed while provisioning

v9 capture (app link, development): the made machine read provisioning; the
start's connect failed at once (no daemon yet) and stayed failed, because the
app reads the list only on events and applyRecord retried only starting -> running.
Now CloudMove.connected reads the record (forced, bounded) until it runs, and a
provisioning -> running edge retries the connect.

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

* Cloud: ensure the creator's user record before an app-link create

A Worker machine binds by registering its VM install in the creator's UserDO,
which refuses a user it has no record of ("call user.ensure first"); the bind
is answered 503 and the machine stays provisioning. The app ensured only after
pairing or Home refusals, never before a create. user.ensure is idempotent.

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

* Cloud: untilRunning reads in its own bounded loop (CloudWait.untilAnswered left base with #32270)

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

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
cmux-bot Bot added a commit that referenced this pull request Nov 2, 2026
…a poll (#32354) (#32368)

* test(cloud): a yes on the Mac after the phone answered the hold must not fail the create (#32354)

Red first: answered on the phone, then yes in the Mac sheet before the
next watch check. The approved op still reads pending, its feed item is
closed, so the answer finds no open item and the create fails with the
closed-item mismatch. A hold of another team must still fail.

* fix(cloud): the Mac hears a hold answered elsewhere from the feed push, not a poll (#32354)

The person answers a Cloud create's approval hold on the phone; the
approve item in their FeedDO closes in that commit, and the owner pushes
the event to the Mac's feed mirror at once. The feed decode dropped the
item's approval reference, so the create flow could not use it and
waited for its same-key watch (1 to 8 s). A yes in the sheet before that
check answered the hold again and failed with the closed-item mismatch.

- CmuxNextFeed keeps the approve action's hold ({request, team}) and
  FeedItem.cloudHoldRequest reads it only for the team's Cloud owner's
  cloud item.
- CloudApprovalHolds (CmuxNextCloud) records each closed hold from the
  feed mirror; CloudApprovalSheet (moved out of the App flow) ends the
  sheet on the push, the click or the watch, whichever comes first, and
  reads a yes against the hold's state.
- CloudApprovalAnswer: when no open item carries the request, the same
  team's closed item means answered elsewhere (.answered); another
  team's item still fails with the mismatch.

App lines: +24 -34.

* fix(cloud): CloudApprovalHolds imports Observation publicly (public @observable)

* test(cloud): the watch-check stub compiles (AsyncStream.makeStream); doc comments name the answered case

* fix(cloud): on feat's no-sheet create, the feed push and this team's closed item mean answered; another team's still fails (#32354)

After merging #32270 (no sheet for a person's create; every closed-item
mismatch went to the same-key retries):
- CloudApprovalAnswer answers .answered(request) for this team's closed
  item and for a hold the feed push already shows answered (no lookup,
  no answer); another team's item stays the closed-item mismatch.
- The flow's answered-elsewhere path takes only .answered, so a true team
  mismatch fails at once again instead of retrying into stillPending.
- alreadyAnswered/answeredElsewhere move to CloudApprovalAnswer.Failure
  (CmuxNextDaemonService); CloudApprovalSheet goes (no sheet to race).

* fix(cloud): CloudApprovalAnswer's feed predicate is optional (no async closure default)

* fix(cloud): a hold the feed shows answered counts only for the create's own team (review on #32368)

CloudApprovalHolds keeps each closed hold's team, FeedItem.cloudHold
carries it, and CloudApprovalAnswer's feed predicate takes the create's
team: another team's closed hold on the phone still ends in the
closed-item mismatch. Test: anotherTeamsHoldTheFeedShowsAnsweredStillFailsAtOnce.

---------

Co-authored-by: cmux-bot[bot] <348531757+cmux-bot[bot]@users.noreply.github.com>

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 4e39e0ca Deployed Nov 2, 2026 by teamleaderleo via wait for same-key tree publisher #101571
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