diff --git a/server/src/modules/run-dispatch/domain/wake-context.test.ts b/server/src/modules/run-dispatch/domain/wake-context.test.ts index ac6b84eb68..83ae2dcc79 100644 --- a/server/src/modules/run-dispatch/domain/wake-context.test.ts +++ b/server/src/modules/run-dispatch/domain/wake-context.test.ts @@ -9,6 +9,15 @@ import { } from "./wake-context.js"; describe("wake context", () => { + it("requires the computer-specific non-assignee receipt for a computer wait", () => { + expect(isNonAssigneeWorkspaceBusyRetry("computer_admission_wait", { + computerAdmissionDeferredWhileAssignee: false, + })).toBe(true); + for (const context of [{}, { computerAdmissionDeferredWhileAssignee: true }, { workspaceBusyDeferredWhileAssignee: false }, { aiConnectionBusyDeferredWhileAssignee: false }]) { + expect(isNonAssigneeWorkspaceBusyRetry("computer_admission_wait", context)).toBe(false); + } + expect(isNonAssigneeWorkspaceBusyRetry("transient_failure", { computerAdmissionDeferredWhileAssignee: false })).toBe(false); + }); it("requires the subscription-specific non-assignee receipt for a subscription wait", () => { expect(isNonAssigneeWorkspaceBusyRetry("ai_connection_busy", { aiConnectionBusyDeferredWhileAssignee: false, diff --git a/server/src/services/execution-recovery-attempt.test.ts b/server/src/services/execution-recovery-attempt.test.ts index d71efa9dd9..b3e2778936 100644 --- a/server/src/services/execution-recovery-attempt.test.ts +++ b/server/src/services/execution-recovery-attempt.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "vitest"; -import { executionFailureRetryCount } from "./execution-recovery-attempt.js"; +import { executionFailureRetryCount, isComputerAdmissionWait } from "./execution-recovery-attempt.js"; describe("failure attempts across resource waits", () => { it("preserves prior failures through subscription waits without trusting unrelated context", () => { @@ -43,3 +43,45 @@ describe("persisted independent accounting", () => { })).toBe(2); }); }); + + +describe("structural computer admission wait receipt", () => { + function receipt() { + return { + id: "run-1", companyId: "company-1", status: "cancelled", runtimeMode: "legacy", + errorCode: "computer_admission_wait", + resultJson: { + executionRecovery: { kind: "computer_admission_wait", providerWorkStarted: false }, + cancellation: { expected: true, source: "control_plane", initiator: { type: "system" } }, + computerAdmission: { + runId: "run-1", companyId: "company-1", + computerId: "11111111-1111-4111-8111-111111111111", + environmentId: "22222222-2222-4222-8222-222222222222", stopId: "stop-1", + }, + }, + }; + } + + it("recognizes the recorded never-dispatched wait without treating a code alone as proof", () => { + const run = receipt(); + expect(isComputerAdmissionWait(run)).toBe(true); + expect(isComputerAdmissionWait({ ...run, resultJson: {} })).toBe(false); + expect(isComputerAdmissionWait({ ...run, resultJson: { ...run.resultJson, executionRecovery: { kind: "computer_admission_wait", providerWorkStarted: true } } })).toBe(false); + expect(isComputerAdmissionWait({ ...run, resultJson: { ...run.resultJson, cancellation: { ...run.resultJson.cancellation, initiator: { type: "user" } } } })).toBe(false); + }); + + it("rejects foreign run/company receipts, invalid identities and already settled retries", () => { + const run = receipt(); + for (const computerAdmission of [ + { ...run.resultJson.computerAdmission, runId: "another-run" }, + { ...run.resultJson.computerAdmission, companyId: "another-company" }, + { ...run.resultJson.computerAdmission, computerId: "invalid" }, + { ...run.resultJson.computerAdmission, environmentId: "invalid" }, + { ...run.resultJson.computerAdmission, stopId: "" }, + ]) expect(isComputerAdmissionWait({ ...run, resultJson: { ...run.resultJson, computerAdmission } })).toBe(false); + expect(isComputerAdmissionWait({ ...run, resultJson: { ...run.resultJson, computerAdmissionRetryOutcome: "superseded" } })).toBe(false); + expect(isComputerAdmissionWait({ ...run, runnerProfileJson: { nativeExecutionInput: { version: 1 } } })).toBe(false); + expect(isComputerAdmissionWait({ ...run, runtimeMode: "native" })).toBe(false); + expect(isComputerAdmissionWait({ ...run, status: "failed" })).toBe(false); + }); +});