diff --git a/server/src/services/native-runtime/paperclip-control-plane-port.test.ts b/server/src/services/native-runtime/paperclip-control-plane-port.test.ts index bae43dd7f39..1de7c9a6b37 100644 --- a/server/src/services/native-runtime/paperclip-control-plane-port.test.ts +++ b/server/src/services/native-runtime/paperclip-control-plane-port.test.ts @@ -390,7 +390,7 @@ describe("PaperclipControlPlanePort conformance", () => { }; }, }; const options = { backend, controlPlane: port, timeoutMs: 2_000, - ...(mode === "checkpoint timeout" ? { checkpointTimeoutMs: 100 } : {}), + ...(mode === "checkpoint timeout" ? { checkpointTimeoutMs: 1_000 } : {}), runnerInstanceId: runnerId, controlPlaneInstanceId: "park-control", input: parseNativeExecutionInput({ schema: "paperclip.native-execution-input.v1", binding: { companyId: identity.companyId, runId: identity.runId, issueId: identity.issueId, agentId: identity.agentId, executionWorkspaceId: "park-workspace" }, @@ -414,13 +414,13 @@ describe("PaperclipControlPlanePort conformance", () => { expect(rows.some(row => row.eventType === "turn.interrupted")).toBe(true); expect(triggerConsumed).toBe(true); if (mode !== "unscoped terminal") { - await new Promise(resolve => setTimeout(resolve, 700)); + if (mode === "settles") await new Promise(resolve => setTimeout(resolve, 700)); + else expect(await outcome).toMatchObject({ error: { message: "native session checkpoint timed out after 1000ms" } }); expect(await db.select().from(nativeRunResults).where(eq(nativeRunResults.runId, identity.runId))).toEqual([]); releaseObserver(); await observerDone; if (mode === "settles") expect(await outcome).not.toHaveProperty("error"); else { - expect(await outcome).toMatchObject({ error: { message: "native session checkpoint timed out after 100ms" } }); expect(await db.select().from(nativeRunResults).where(eq(nativeRunResults.runId, identity.runId))).toEqual([]); const restored = new PaperclipControlPlanePort(db, { ...identity, completionContractId: fixtureContractId, completionContractSha256: contractSha, sourceInstanceId: runnerId, controlPlaneSourceInstanceId: "park-control" }); diff --git a/server/src/services/workspace-recovery.test.ts b/server/src/services/workspace-recovery.test.ts index 580a10b3263..b99542a255b 100644 --- a/server/src/services/workspace-recovery.test.ts +++ b/server/src/services/workspace-recovery.test.ts @@ -627,6 +627,12 @@ describe("automatic retained workspace recovery", () => { return app; } + function receiptOnlyRecoveryApp(actor?: Parameters[0]) { + const routeHeartbeat = heartbeatService(db); + vi.spyOn(routeHeartbeat, "resumeTaskRetry").mockImplementation(async () => undefined as never); + return boardRecoveryApp(actor, routeHeartbeat); + } + type RecoverySourceLayout = "retained" | "published" | "raw"; async function acceptedRemoteExport(sourceLayout: RecoverySourceLayout = "retained") { @@ -1425,7 +1431,7 @@ describe("automatic retained workspace recovery", () => { "keeps ancestor Retry held when current proof changes: %s", async gate => { const f = await recoveredPreparationRetryChain(["warning_reason", "provider_warning", "extra_after_warning"].includes(gate) ? "historical_warning" : "inherited_session"); - const heartbeat = heartbeatService(db), app = boardRecoveryApp(); + const heartbeat = heartbeatService(db), app = receiptOnlyRecoveryApp(); const original = readSystemRecovery((await action(f.actionId)).evidence)!; const receipt = (await request(app).post(`/api/issues/${f.issueId}/retry`) .send({ observedRunId: f.failed.id, idempotencyKey: randomUUID() }).expect(202)).body; @@ -1607,7 +1613,7 @@ describe("automatic retained workspace recovery", () => { await db.insert(authUsers).values({ id: actorId, name: "Retry owner", email: `${actorId}@example.invalid`, createdAt: new Date(), updatedAt: new Date() }); await db.insert(companyMemberships).values({ companyId: f.companyId, principalType: "user", principalId: actorId, membershipRole: "owner" }); } - const app = boardRecoveryApp({ userId: actorId, source: gate === "actor_permission_revoked" ? "session" : "local_implicit", companyIds: [f.companyId] }); + const app = receiptOnlyRecoveryApp({ userId: actorId, source: gate === "actor_permission_revoked" ? "session" : "local_implicit", companyIds: [f.companyId] }); const receipt = (await request(app).post(`/api/issues/${f.issueId}/retry`) .send({ observedRunId: f.runId, idempotencyKey: randomUUID() }).expect(202)).body; if (gate === "delayed_provider_event") await appendHeartbeatRunEvent(db, { companyId: f.companyId, runId: f.runId,