Files
PaperClipAI/tests/runner-e2e/cleanup-verification.ts
DottaandPaperclip fe92554788 Wire native Daytona qualification and warm ACP journeys
Withhold native tasks until exact owned observers are armed, preserve sealed retirement proof before environment teardown, and register explicit local and Daytona warm continuity cases.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-09-29 17:26:29 -05:00

38 lines
1.8 KiB
TypeScript

export interface CleanupCheck { id: string; passed: boolean; detail: string }
export type CleanupAssertion = () => Promise<CleanupCheck[]>;
/** Always finish every registered observer, even when an earlier proof fails. */
export async function verifyCleanupAssertions(assertions: readonly CleanupAssertion[]) {
const checks: CleanupCheck[] = [], errors: unknown[] = [];
for (const [index, assertion] of assertions.entries()) {
try {
const result = await assertion();
if (!Array.isArray(result) || result.length === 0 || result.some(check =>
!check || typeof check.id !== "string" || !check.id || typeof check.passed !== "boolean" || typeof check.detail !== "string")) {
throw new Error("Cleanup assertion did not return complete checks");
}
checks.push(...result);
if (result.some(check => !check.passed)) throw new Error("Cleanup assertion reported a failed check");
} catch (error) {
errors.push(error);
checks.push({ id: `assertion-${index}-completed`, passed: false, detail: error instanceof Error ? error.message : "Cleanup assertion failed" });
}
}
return { checks, errors };
}
/** Collect remote proof before destroying its environment, even if cancellation
* fails. A missing proof fails qualification but never skips owned teardown. */
export async function runCleanupWithObservers(input: {
retireRuns(): Promise<void>;
assertions: readonly CleanupAssertion[];
teardown(): Promise<void>;
}) {
const errors: unknown[] = [];
try { await input.retireRuns(); } catch (error) { errors.push(error); }
const verification = await verifyCleanupAssertions(input.assertions);
errors.push(...verification.errors);
try { await input.teardown(); } catch (error) { errors.push(error); }
return { checks: verification.checks, errors };
}