Repository navigation
cmux NEXT Cloud: a person's own Cloud send creates the machine with no second approval prompt - #32270
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240
… 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
Bugbot needs on-demand usage enabledBugbot 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. |
|
cmux status (one comment, edited in place; each line is updated by the job that owns it) Review App of this head (app.zip, kept 1 day)
Shipped in:
|
|
Owned by an agent session · session |
|
Found 1 test failure on Blacksmith runners: Failure
|
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
|
Review (codex gpt-6-astra high, router-review): BLOCK at 21eb537 BLOCK at 21eb537 Visual verdict: no images; Leo tries the build
|
…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
…person-create-no-approval-prompt # Conflicts: # Packages/macOS/CmuxNext/Tests/CmuxNextAppTests/CloudApprovalAnsweredElsewhereTests.swift
Bugbot needs on-demand usage enabledBugbot 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. |
…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).
…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
… 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>
…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>
![Fix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/fix-with-codesmith-light-3x.png)
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.createwith its install token. The backend holds every install's money op for the person's approval (approval.pending), by design.CloudMachineCreateFlow.createsetconfirmed = !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:startedByPerson == false) still show the agent-request confirmation first, and a no sends nothing..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
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 testsaHoldAnsweredElsewhereFirstGoesOnWithTheSameKey,aClosedItemWhoseHoldStaysPendingEndsStillPending, added for the router-review BLOCK at 21eb537).debug.dialogempty at 1, 2.5 and 4 min); the create went through approval and made machinecloud-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