fix(runner): send the prepared task scope with retained release and resume (#19896)

This commit is contained in:
Nicky Leach authored and GitHub committed 2026-11-07 14:50:31 -08:00
1 parent 5020f38f90
commit 91b044858c
2 files changed
+34 -2

No files matched your search

@@ -390,6 +390,34 @@ describe("plugin-provided Runner execution", () => {
await executeEnvironmentTask(database(value).db, workers as never, { companyId: "company", leaseId, operation: { ...submit, projectIds: [] } });
expect(workers.call).toHaveBeenCalledWith("original", "environmentTask", expect.objectContaining({ projectIds: [] }), 15_000);
});
it.each(["release", "resume"] as const)("sends the prepared project and fresh scope with a retained %s", async kind => {
const identity = { runnerInstanceId: "runner", environmentLeaseId: leaseId, runId: "run", normalizedSessionId: "session", turnId: "turn", itemId: "item" };
const operation = kind === "release" ? { kind, identity } : { kind, identity, bootstrapTicket: "transient-test-ticket" };
const result = kind === "release" ? { kind: "released", taskId: "attempt-1" } : { kind: "resume", taskId: "attempt-1", outcome: "resumed" };
const fresh = { attemptId: leaseId, sourceRunId: secondProjectId, previousWorkspaceId: null, recoverySnapshots: [] };
const value = row(); value.lease.status = "retained"; value.run!.status = "succeeded";
Object.assign(value.lease.metadata, { runnerTaskProjectIds: [projectId, secondProjectId], freshWorkspace: fresh });
const { db, query } = database(value, [{ id: projectId }, { id: secondProjectId }]);
const workers = worker(result);
await expect(executeEnvironmentTask(db, workers as never, { companyId: "company", leaseId, operation })).resolves.toEqual(result);
expect(workers.call).toHaveBeenCalledWith("original", "environmentTask", expect.objectContaining({
projectIds: [projectId, secondProjectId], fresh, operation }), 15_000);
const scope = new PgDialect().sqlToQuery(query.where.mock.calls[1][0]);
expect(scope.sql).toContain('"projects"."company_id" =');
expect(scope.params).toEqual(["company", projectId, secondProjectId]);
const unscoped = row(); unscoped.lease.status = "retained";
const plain = worker(result);
await executeEnvironmentTask(database(unscoped, []).db, plain as never, { companyId: "company", leaseId, operation });
const sent = (plain.call.mock.calls[0] as unknown as any[])[2];
expect(sent.projectIds).toEqual([]);
expect(sent).not.toHaveProperty("fresh");
const rejected = worker(result);
await expect(executeEnvironmentTask(database(value, [{ id: projectId }]).db, rejected as never, { companyId: "company", leaseId, operation }))
.rejects.toThrow("project unavailable");
expect(rejected.call).not.toHaveBeenCalled();
});
it("rejects an absent or cross-company lease before calling a worker", async () => {
const workers = worker();
await expect(executeEnvironmentTask(database(null).db, workers as never, { companyId: "other", leaseId, operation: submit })).rejects.toThrow("lease unavailable");