perf(recovery): skip unchanged retained workspace evidence writes (#17650)

Guard the retained-evidence update with its existing JSONB comparison. Reuse the full first result when evidence is unchanged, while preserving new evidence delivery, source-bound retention, cleanup, and recovery holds.

Verified with 199 recovery and retention tests, full workspace typechecking, the server build, green CI, and exact-head Apex5/5.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Devin FoleyandPaperclip authored and GitHub committed 2026-10-25 12:58:50 -07:00
1 parent 1949e726f8
commit 67aa87a93b
3 files changed
+44 -5

No files matched your search

+4 -1
View File
@@ -99,7 +99,7 @@ process-field update remain in the same transaction.
Legacy terminalization locks runtime mode, status, full result evidence, and the
status-delivery token without loading unused input, profile, or log bodies.
It keeps the existing lock, writes, full returned run, workspace-retention
It keeps the existing lock, full returned run, workspace-retention
receipts, and source-bound recovery holds. Stored payloads remain unchanged.
Conversation ownership checks select process identity and full recovery result
@@ -281,6 +281,9 @@ Legacy recovery also retains the pending delivery when status is unchanged and
no patch was supplied. Explicit patches, new terminal statuses, and newly
retained workspace evidence still create a delivery. File retention, ownership
checks, failed write conditions, lock cleanup, and recovery holds still apply.
The retention-evidence write returns another full run only when that evidence
changes. An unchanged retry keeps the full run returned by the first write and
still processes retained leases and recovery holds.
Agent lists read the complete company roster once and use that same snapshot for
termination filtering and organization-chain normalization. Detail and plugin runtime reads
@@ -73,6 +73,41 @@ const support = externalTestDatabaseUrl ? { supported: true } : await getEmbedde
expect(JSON.stringify(events)).not.toContain(bulk.slice(0, 64));
});
it.each(["legacy", "native"])("returns one complete run when retained workspace evidence is unchanged for %s", async (runtimeMode) => {
const f = await seed();
const bulk = randomBytes(128 * 1024).toString("base64");
const [saved] = await db.update(heartbeatRuns).set({ runtimeMode, status: "failed", finishedAt: new Date(),
contextSnapshot: { ...f.run.contextSnapshot, savedInput: bulk }, runnerProfileJson: { savedProfile: bulk },
stdoutExcerpt: bulk, stderrExcerpt: bulk,
}).where(eq(heartbeatRuns.id, f.runId)).returning();
const recordRestoreFailureOnly = runtimeMode === "native";
const failed = (await terminalizeLegacyExecution({ db, run: saved!, status: "failed", recordRestoreFailureOnly,
workspaceRestoreSource: f.lease,
patch: { resultJson: { workspaceRestoreFailure: "restore_failed", futureResult: bulk } },
}))!;
const events: Array<Record<string, unknown>> = [], now = Date.now();
const capture = createDatabaseResponseCapture({ start: now - 100, end: now + 59_000 }, event => events.push(event));
installDatabaseResponseCapture(db, { heartbeatRuns }, capture);
let returned: Awaited<ReturnType<typeof terminalizeLegacyExecution>>;
try { returned = await terminalizeLegacyExecution({ db, run: failed, status: "failed", recordRestoreFailureOnly,
workspaceRestoreSource: f.lease,
...(recordRestoreFailureOnly ? { patch: { resultJson: failed.resultJson } } : {}),
}); }
finally { capture.flush(); }
const writes = events.filter(event => event.event === "paperclip.db_response_capture.entry.v1"
&& event.table === "heartbeat_runs" && event.operation === "update");
expect(writes.reduce((sum, group) => sum + Number(group.rows), 0)).toBe(1);
expect(returned).toMatchObject({ id: f.runId, status: "failed", finishedAt: failed.finishedAt,
contextSnapshot: failed.contextSnapshot, runnerProfileJson: failed.runnerProfileJson, resultJson: failed.resultJson,
stdoutExcerpt: bulk, stderrExcerpt: bulk });
if (!recordRestoreFailureOnly) expect(returned!.executionStatusDeliveryId).toBe(failed.executionStatusDeliveryId);
expect((await db.select().from(heartbeatRuns).where(eq(heartbeatRuns.id, f.runId)))[0]).toEqual(returned);
expect(await readLease(f.lease.id)).toMatchObject({ status: "pending_cleanup", leasePolicy: "retain_on_failure" });
expect(await db.select().from(issueRecoveryActions).where(eq(issueRecoveryActions.sourceIssueId, f.issueId)))
.toEqual([expect.objectContaining({ evidence: expect.objectContaining({ runId: f.runId }), ownerType: "board" })]);
expect(JSON.stringify(events)).not.toContain(bulk.slice(0, 64));
});
it("preserves pending and acknowledged status delivery on unpatched legacy recovery retries", async () => {
await deliverExecutionStatuses(db, { publish: vi.fn() });
const f = await seed();
@@ -156,11 +156,12 @@ export async function terminalizeLegacyExecution(input: {
...updated.resultJson,
workspaceRestoreRecovery: { schema: LEGACY_WORKSPACE_RECOVERY_SCHEMA, leaseIds: [...retainedLeaseIds].sort() },
};
[updated] = await tx.update(heartbeatRuns).set({
const [retained] = await tx.update(heartbeatRuns).set({
resultJson: retainedResult,
executionStatusDeliveryId: sql`case when ${heartbeatRuns.resultJson} is distinct from ${JSON.stringify(retainedResult)}::jsonb
then ${randomUUID()}::uuid else ${heartbeatRuns.executionStatusDeliveryId} end`,
}).where(and(eq(heartbeatRuns.id, updated.id), eq(heartbeatRuns.companyId, updated.companyId))).returning();
executionStatusDeliveryId: randomUUID(),
}).where(and(eq(heartbeatRuns.id, updated.id), eq(heartbeatRuns.companyId, updated.companyId),
sql`${heartbeatRuns.resultJson} is distinct from ${JSON.stringify(retainedResult)}::jsonb`)).returning();
if (retained) updated = retained;
}
const needsRecovery = input.recordRestoreFailureOnly
? retainedLeaseIds.length > 0 || hasRequiredWorkspaceRecovery(updated.resultJson)