From 67bde2fc3f8502105ffda2ca30acbf7b55e60a0d Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 31 Jul 2026 04:48:30 -0700 Subject: [PATCH] fix(ci): keep workload routing broker-only --- scripts/crabbox-wrapper.mjs | 26 +++++++++----------------- test/scripts/crabbox-wrapper.test.ts | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/scripts/crabbox-wrapper.mjs b/scripts/crabbox-wrapper.mjs index c76d23412b17..11714416acf6 100755 --- a/scripts/crabbox-wrapper.mjs +++ b/scripts/crabbox-wrapper.mjs @@ -880,7 +880,6 @@ function crabboxProviderReadiness(providerName, versionText, targetContext) { } if ( canonicalProvider === "daytona" && - !directCloudOverrideEnabled(canonicalProvider) && !satisfiesMinimumCrabboxVersion(versionText, minimumBrokeredDaytonaCrabboxVersion) ) { return { @@ -888,11 +887,7 @@ function crabboxProviderReadiness(providerName, versionText, targetContext) { reason: `requires Crabbox >= ${formatVersionTuple(minimumBrokeredDaytonaCrabboxVersion)} for brokered Daytona`, }; } - if ( - ["aws", "azure", "daytona"].includes(canonicalProvider) && - !directCloudOverrideEnabled(canonicalProvider) && - !managedBrokerAuthConfigured() - ) { + if (["aws", "azure", "daytona"].includes(canonicalProvider) && !managedBrokerAuthConfigured()) { return { ready: false, reason: "managed Crabbox broker auth unavailable" }; } const doctorArgs = ["doctor", "--provider", canonicalProvider]; @@ -917,30 +912,27 @@ function formatProviderReadiness(readiness) { } function shouldRequireBrokeredCloud(commandArgs, providerName) { - if (directCloudOverrideEnabled(providerName)) { - return false; - } const canonicalProvider = canonicalProviderName(providerName); if (!["aws", "azure", "daytona"].includes(canonicalProvider)) { // Blacksmith Testbox is provider-owned and does not use the managed // coordinator auth required by brokered cloud capacity. return false; } + if (requestedWorkload(commandArgs)) { + return true; + } + if (directCloudOverrideEnabled(providerName)) { + return false; + } if (commandArgs[0] === "run" || commandArgs[0] === "warmup") { // Workload routing never consumes local cloud credentials. Keep the // shipped direct Azure/Daytona path only for commands outside that policy. - return ( - canonicalProvider === "aws" || - Boolean(requestedWorkload(commandArgs)) || - managedBrokerRequested() - ); + return canonicalProvider === "aws" || managedBrokerRequested(); } return ( commandArgs[0] === "actions" && commandArgs[1] === "hydrate" && - (canonicalProvider === "aws" || - Boolean(requestedWorkload(commandArgs)) || - managedBrokerRequested()) + (canonicalProvider === "aws" || managedBrokerRequested()) ); } diff --git a/test/scripts/crabbox-wrapper.test.ts b/test/scripts/crabbox-wrapper.test.ts index 464c81c08c11..1322aa662eed 100644 --- a/test/scripts/crabbox-wrapper.test.ts +++ b/test/scripts/crabbox-wrapper.test.ts @@ -1091,7 +1091,7 @@ describe("scripts/crabbox-wrapper", () => { ); }); - it("honors direct-cloud debugging during automatic readiness checks", () => { + it("ignores direct-cloud debugging during automatic readiness checks", () => { const result = runWrapper( "provider: aws, azure, blacksmith-testbox, or daytona\n", ["run", "--workload", "desktop", "--", "echo ok"], @@ -1104,9 +1104,10 @@ describe("scripts/crabbox-wrapper", () => { }, ); - expect(result.status).toBe(0); - expect(parseFakeCrabboxOutput(result).args).toContain("azure"); - expect(result.stderr).toContain("selected=azure"); + expect(result.status).toBe(2); + expect(result.stdout).toBe(""); + expect(result.stderr).toContain("no ready provider for workload=desktop"); + expect(result.stderr).toContain("managed Crabbox broker auth unavailable"); }); it("keeps workload configuration away from administrative commands", () => { @@ -1234,22 +1235,23 @@ describe("scripts/crabbox-wrapper", () => { expect(parseFakeCrabboxOutput(result).args).toContain("daytona"); }); - it("allows automatic direct Daytona routing on older Crabbox versions", () => { + it("does not allow direct cloud overrides inside workload routing", () => { const result = runWrapper( "provider: aws, azure, blacksmith-testbox, or daytona\n", ["run", "--workload", "interactive", "--", "echo ok"], { configJson: { coordinator: "", brokerAuth: "missing" }, env: { - OPENCLAW_FAKE_CRABBOX_VERSION: "crabbox 0.39.9", + OPENCLAW_FAKE_CRABBOX_VERSION: "crabbox 0.40.0", OPENCLAW_CRABBOX_ALLOW_DIRECT_CLOUD: "1", }, }, ); - expect(result.status).toBe(0); - expect(parseFakeCrabboxOutput(result).args).toContain("daytona"); - expect(result.stderr).toContain("selected=daytona"); + expect(result.status).toBe(2); + expect(result.stdout).toBe(""); + expect(result.stderr).toContain("no ready provider for workload=interactive"); + expect(result.stderr).toContain("managed Crabbox broker auth unavailable"); }); it("fails closed when no policy provider is ready", () => {