Skip to content

cloud: the app server link connects through the Native route - #32472

Merged
teamleaderleo merged 7 commits into
feat-cmux-nextfrom
cloud-demo/native-link-default
Nov 2, 2026
Merged

teamleaderleo merged 7 commits into
feat-cmux-nextfrom
cloud-demo/native-link-default

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

NEXT Cloud's app server link never connected to a machine. With this PR it takes the Native device route by default, and that route can start now.

Why

Every app-link Cloud chat start made a machine, then stopped at "cloud-chats-N didn't connect. Retry once it's online." The capture's app log (HQ run 41477973186) shows why:

app.cloud  created machine vm_e8e9020cfe675c530a5e
cloud      cloud link ended: Disconnected from the Cloud machine (cmux link refused the dial: unreachable).
app.cloud  cloud start chat failed: cloud-chats didn't connect. Retry once it's online.

Two causes:

  1. cmux link over the relay can't reach any machine. cloud.machine.connect_info answers gateway, vpc_endpoint and public_ipv6 as null, so choose_route (mesh_cloud.rs) returns CloudRoute::None and every dial is refused as unreachable. A vm-api machine's network routes through the enrolled mesh tunnel (native_route.rs for_vm), and only the Native link has that route. Native was opt-in (CMUX_NEXT_CLOUD_NATIVE_LINK=1); it is now the default, and =0 turns it off. When Native does not start, cmux link is still the fallback.
  2. The Native route never started. With Native turned on, a capture showed host.network.target refused 400: validation.invalid: unknown read host.network.target (HQ run 41492846764; the log line comes from the diagnostics in this PR). Since backend: UserDO/TeamDO network identity and Native dial RPCs for the platform CloudDO #30399 that read is served by the platform's own GET /v1/host/network/target (cmux-platform NativeNetwork.ts). The app still posted it to /v1/read, where TeamDO refuses it. The app now GETs the platform route, and cmux-api's forwarder sends that path to the platform along with NEXT Cloud's other routes.

Native refusals also log their stable code and message now, not a bare status, so a route that fails to start says why.

Review at 1de33d1 (BLOCK): the Native default can't dial machines whose connect_info has no network. That's true, but cmux link can't dial them either while connect_info returns no route. The development Worker's connect_info comes from cmux-platform's CloudDO (Connect.ts), which does return network for vm-api machines.

Leo, on the env-var setup: "i dont wanna do this make it more ergonomic".

Testing

  • Fleet, at bcafa32: package-test-lane.sh suite Packages/macOS/CmuxNext NativeNetworkTargetTests,CloudNativeFirstLauncherTests,NativeDeviceEnrollmentTests: all 3 suites pass. NativeNetworkTargetTests now asserts the GET path, with and without a mesh. The test world refuses the old /v1/read, so the old client fails it.
  • Fast checks: bunx vitest run test/platform-forward.test.ts: 10/10 pass, including the new forwarded route.

Observed / Not run

  • End to end: the forwarder takes effect when this merges and the development Worker deploys. A builtin:cloud-start-chat capture at the merge follows in a comment.

Changelog

  • Fixed: NEXT Cloud's app server link connects to Cloud machines through the Native device route.

Agent session: agent session

teamleaderleo and others added 2 commits November 2, 2026 09:02
connect_info answers no gateway, VPC endpoint or public address, so cmux link
over the relay finds no route to any Worker machine and every app-link Cloud
start ended in "cmux link refused the dial: unreachable". A vm-api machine's
Native network routes through the enrolled mesh tunnel, so Native first (with
cmux link as its fallback when Native does not start) is the route that
connects. CMUX_NEXT_CLOUD_NATIVE_LINK=0 turns it off.

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
@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 8f2cd27: 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=pr32472 -f ref=cloud-demo/native-link-default -f platform=macos -f backend_mode=local

Default changes

This pull request changes 1 default at 8f2cd27a39ba (what everyone gets without configuring anything):

  • tunable-source.CmuxNextCloudCredentials/CloudNativeRouteHolder.swift:choice: "f2195126a0f1c3a2690eb72247d4f709f02c9397c072b13657b8a178c3d91bc1" -> "3c5cd0296c1290087642e549a9d5eaec5df01a7de68225b35f52a2915b12f7a5"

Signed off on this commit by review (codex gpt-6.1-sol xhigh, router-review).

Merge receipt: merged as 69e0f313a038 with these defaults changed, signed off by review (codex gpt-6.1-sol xhigh, router-review).

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

Shipped in:

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Owned by an agent session · session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): BLOCK at 1de33d1

BLOCK at 1de33d1

Visual verdict: no images; Leo tries the build

  1. [P1] [blocking] The new Native default cannot reach the current Cloud machines. CloudNativeRouteHolder.swift:84-86 selects Native by default, but backend/apps/api/src/cloud-connect.ts:102-110 omits network and returns null gateway/endpoints; native_route.rs:107-120 rejects every VM without that network. The fallback only handles Native launcher startup errors (CloudNativeRouteHolder.swift:94-105), so the later per-machine dial failure never switches to cmux link.

Follow-ups:

  • [P2] [follow-up] No after screenshots or gallery artifact were available in review/images/ for visual comparison.

The Native route's refusals reached the log as a bare status ("refused(400)"),
so a team whose route did not start could not say why. Log the refusal's
stable code and message (server text, no credential) at each step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-548f18c0a6d1ebb48240
The Native route never started: the app read host.network.target as an op on
/v1/read, and TeamDO answers that "unknown read host.network.target" (400),
since #30399 moved the read to the platform's own GET /v1/host/network/target.
The app now GETs that route, and cmux-api forwards it to the platform with the
rest of NEXT Cloud's routes.

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

This comment has been minimized.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol high, sweep, via the review router; full diff from merge base 4b1f655 to this head): SHIP at bcafa32

No P1/P2 findings.

@teamleaderleo teamleaderleo changed the title cloud: the app server link takes the Native route by default cloud: the app server link connects through the Native route Nov 2, 2026
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 2, 2026 18:51 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent November 2, 2026 18:51 Inactive
#32472 review follow-up (gpt-6.1-sol at bcafa32).

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 7d23d92

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

SHIP at 7d23d92

Visual verdict: no images; Leo tries the build

I found no correctness, regression, security, or test-breaking issues in the changed routing and transport paths.

Follow-ups: none

Resolves #32525's step-named refusals with this branch's refusal logging and
the platform target route.

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.1-sol xhigh, router-review): SHIP at 8f2cd27

Visual verdict: no images; Leo tries the build

Reviewed the changed Swift native-target/launcher flow and platform-forward routing; no correctness or regression issues found.

Follow-ups: none

Fleet: NativeNetworkTargetTests, CloudNativeFirstLauncherTests, NativeDeviceEnrollmentTests pass at this head.

@teamleaderleo
teamleaderleo merged commit 69e0f31 into feat-cmux-next Nov 2, 2026
161 of 165 checks passed
@teamleaderleo
teamleaderleo deleted the cloud-demo/native-link-default branch November 2, 2026 19:38
@lawrencecchen

Copy link
Copy Markdown
Contributor

Swift logic follow-up (tip watcher swift-logic row, STATUS 13027 "SWIFT LOGIC CULPRITS"; lead order).

This PR raised swift_logic_lines by +45 at its merge commit 69e0f31: scripts/cmux-next/swift-logic-lines.py before and after the merge, with the same table (the tip's, c6be943). The largest declarations of the rise:

  • struct NativeNetworkRefusal in Packages/macOS/CmuxNext/Sources/CmuxNextCloud/Network/NativeNetworkTarget.swift: +15 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)
  • actor NativeDeviceEnrollment in Packages/macOS/CmuxNext/Sources/CmuxNextCloud/Network/NativeDeviceEnrollment.swift: +10 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)
  • actor MacInstallIdentity in Packages/macOS/CmuxNext/Sources/CmuxNextCloud/Identity/MacInstallIdentity.swift: +8 lines counted as Swift logic (its row counts it as logic)
  • extension MacInstallIdentity in Packages/macOS/CmuxNext/Sources/CmuxNextCloud/Network/NativeNetworkTarget.swift: +6 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)

plans/cmux-next/layer-ownership.md says Rust owns every state, list and rule and Swift is the platform shell. Please move the new logic of this PR in a follow-up: to Rust (the crate that owns the area; the owner lists in STATUS 12147-12165 name the target per area), or at least out of the app into its package. If a declaration above is platform code (AppKit, Core Animation, OS calls, strings, tokens, DEBUG tooling), reply here and the table gets a PLATFORM row with your reason instead.

The swift-logic row is a report, not a gate: nothing blocks on this comment.

This branch was previously deployed

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

2 participants