diff --git a/backend/apps/api/test/platform-cloud-development.test.ts b/backend/apps/api/test/platform-cloud-development.test.ts index 81a3f865e5b3..e917cb0fb887 100644 --- a/backend/apps/api/test/platform-cloud-development.test.ts +++ b/backend/apps/api/test/platform-cloud-development.test.ts @@ -57,4 +57,13 @@ describe("development routes NEXT Cloud to cmux-platform-development", () => { expect(JSON.stringify(e.services ?? []), name).not.toContain("cmux-platform-development") } }) + + it("forwards production's cloud surface to cmux-platform-production, which binds this Worker's objects", () => { + const prod = envs().production! + expect(prod.name).toBe("cmux-api") + expect(prod.vars.PLATFORM_SURFACES).toBe("cloud") + expect(prod.services).toEqual([{ binding: "PLATFORM", service: "cmux-platform-production" }]) + // The platform binds cmux-api's own CloudDO (script_name "cmux-api"), so the class and its data stay here. + expect(cloudDo(prod)).toEqual({ name: "CLOUD_DO", class_name: "CloudDO" }) + }) }) diff --git a/backend/apps/api/wrangler.jsonc b/backend/apps/api/wrangler.jsonc index 2bbb051332b6..0ec4012f9c54 100644 --- a/backend/apps/api/wrangler.jsonc +++ b/backend/apps/api/wrangler.jsonc @@ -152,7 +152,7 @@ // turn nodes are tag:lawrence-chief (Lawrence's Chief only; its CHIEF_CC_TS_OAUTH client owns that tag), which reaches // sr2, the controller, the hub and the Mac gate (hq acl.manaflow.hujson). Secrets CHIEF_CC_TURN_FILES (Mac gate and // hub tokens) and CHIEF_CC_GITHUB_TOKEN are production only. - "vars": { "ENVIRONMENT": "production", "INFERENCE_MODEL_ALLOWLIST": "deepseek/deepseek-v4.1-flash-1017,deepseek/deepseek-v4.1-flash,deepseek/deepseek-v4-flash,deepseek/deepseek-v4-pro", "INFERENCE_PRIMARY_PROVIDER": "vercel", "INFERENCE_CF_GATEWAY_ID": "cmux-ai-proxy", "INFERENCE_AZURE_ENDPOINT": "https://lawrence-1614-resource.services.ai.azure.com", "INFERENCE_VERCEL_RELAY_URL": "https://console.cmux.dev/api/ai-gateway/chat/completions", "CHIEF_CC_ENABLED": "1", "CHIEF_CC_OWNERS": "team_2fcc617e7ba8be229bcb", "CHIEF_CC_TS_TAG": "tag:lawrence-chief", "CHIEF_CC_SNAPSHOT": "sh-e4d3df6380b547e4b59b9d59b6439911", "CHIEF_BRAIN_ENABLED": "1", "CHIEF_BRAIN_MODEL": "claude-opus-5-5", "CHIEF_BRAIN_CLAUDE_AUTH": "service-key", "CHIEF_BRAIN_CLAUDE_MODELS": "claude-opus-5-5,claude-sonnet-5-5,claude-haiku-5-5", "CHIEF_BRAIN_CLAUDE_OWNERS": "team_2fcc617e7ba8be229bcb,team_6197db2f4b9d28c7115a,team_7648bed712529f7a64fa,team_760c83ddd31c6360c927", "CHIEF_BRAIN_FALLBACK_MODEL": "claude-haiku-5-5", "CHIEF_BRAIN_COMPACTOR_MODEL": "claude-haiku-5-5", "CHIEF_RUN_TOKEN_CAP_USD": "5", "HOME_INVITE_ORIGIN": "https://console.cmux.dev", "HOME_INVITES_SEND": "on", "HOME_INVITES_TEXT": "off", "INFERENCE_ENABLED": "1", "INFERENCE_FREE_ENABLED": "0", "INFERENCE_DAILY_CAP_USD": "20", "INFERENCE_FREE_DAILY_CAP_USD": "10", "CLOUD_API_ORIGIN": "https://cloud-api.cmux.dev", "PLATFORM_MACHINES": "on", "CLOUD_NAME_PREFIX": "cmuxnp-prod-cld-", "WORKER_NAME": "cmux-api", "TEAM_VM_SLUG_PREFIX": "cmux-tvm-", "DASHBOARD_ORIGIN": "https://console.cmux.dev", "API_VERSION": "0.1.0", "IOS_APP_ID": "7WLXT3NR37.com.cmux.app", "STACK_PROJECT_ID": "9790718f-14cd-4f7e-824d-eaf527a82b82", "PROJECTION_SHADOW": "mysql", "PROJECTION_READS": "shadow" }, + "vars": { "ENVIRONMENT": "production", "INFERENCE_MODEL_ALLOWLIST": "deepseek/deepseek-v4.1-flash-1017,deepseek/deepseek-v4.1-flash,deepseek/deepseek-v4-flash,deepseek/deepseek-v4-pro", "INFERENCE_PRIMARY_PROVIDER": "vercel", "INFERENCE_CF_GATEWAY_ID": "cmux-ai-proxy", "INFERENCE_AZURE_ENDPOINT": "https://lawrence-1614-resource.services.ai.azure.com", "INFERENCE_VERCEL_RELAY_URL": "https://console.cmux.dev/api/ai-gateway/chat/completions", "CHIEF_CC_ENABLED": "1", "CHIEF_CC_OWNERS": "team_2fcc617e7ba8be229bcb", "CHIEF_CC_TS_TAG": "tag:lawrence-chief", "CHIEF_CC_SNAPSHOT": "sh-e4d3df6380b547e4b59b9d59b6439911", "CHIEF_BRAIN_ENABLED": "1", "CHIEF_BRAIN_MODEL": "claude-opus-5-5", "CHIEF_BRAIN_CLAUDE_AUTH": "service-key", "CHIEF_BRAIN_CLAUDE_MODELS": "claude-opus-5-5,claude-sonnet-5-5,claude-haiku-5-5", "CHIEF_BRAIN_CLAUDE_OWNERS": "team_2fcc617e7ba8be229bcb,team_6197db2f4b9d28c7115a,team_7648bed712529f7a64fa,team_760c83ddd31c6360c927", "CHIEF_BRAIN_FALLBACK_MODEL": "claude-haiku-5-5", "CHIEF_BRAIN_COMPACTOR_MODEL": "claude-haiku-5-5", "CHIEF_RUN_TOKEN_CAP_USD": "5", "HOME_INVITE_ORIGIN": "https://console.cmux.dev", "HOME_INVITES_SEND": "on", "HOME_INVITES_TEXT": "off", "INFERENCE_ENABLED": "1", "INFERENCE_FREE_ENABLED": "0", "INFERENCE_DAILY_CAP_USD": "20", "INFERENCE_FREE_DAILY_CAP_USD": "10", "CLOUD_API_ORIGIN": "https://cloud-api.cmux.dev", "PLATFORM_MACHINES": "on", "CLOUD_NAME_PREFIX": "cmuxnp-prod-cld-", "WORKER_NAME": "cmux-api", "TEAM_VM_SLUG_PREFIX": "cmux-tvm-", "DASHBOARD_ORIGIN": "https://console.cmux.dev", "API_VERSION": "0.1.0", "IOS_APP_ID": "7WLXT3NR37.com.cmux.app", "STACK_PROJECT_ID": "9790718f-14cd-4f7e-824d-eaf527a82b82", "PROJECTION_SHADOW": "mysql", "PROJECTION_READS": "shadow", "PLATFORM_SURFACES": "cloud" }, "durable_objects": { "bindings": [ { "name": "USER_DO", "class_name": "UserDO" }, @@ -180,7 +180,12 @@ // Hyperdrive cmux-next-vitess-production / cmux-next-vitess-ro-production (caching disabled). Shadow writes and reads // (vitess-migration-DESIGN.md section 4 step 4); Postgres stays primary until the production cutover. "hyperdrive": [{ "binding": "HYPERDRIVE", "id": "ef387ca3b20b4ea7878e02746d9545ef" }, { "binding": "HYPERDRIVE_RO", "id": "6badee5cbb964e9f9c09c6f175a14c85" }, { "binding": "PS_MYSQL", "id": "0533eedddc1e4195adf0d42a4c325fce" }, { "binding": "PS_MYSQL_RO", "id": "d3bc1fb86f494cd09810b4872238ceb1" }], - "routes": [{ "pattern": "cloud-api.cmux.dev", "custom_domain": true }] + "routes": [{ "pattern": "cloud-api.cmux.dev", "custom_domain": true }], + // The platform forwarder (src/platform-forward.ts; cmux-platform docs/port-cloud-worker.md 3.1, 3.2): PLATFORM_SURFACES + // "cloud" above sends NEXT Cloud's ops and machine routes to cmux-platform-production, which binds this Worker's own + // CloudDO, UserDO, TeamDO and DomainDO by script_name (no data moves; CLOUD_DO stays this Worker's class). Rollback: + // drop the var (with the binding absent the forwarder serves locally and logs platform.forward.unbound). + "services": [{ "binding": "PLATFORM", "service": "cmux-platform-production" }] } } }