declare const Deno: { test(name: string, fn: () => void | Promise): void; }; import { parseWorkingDirectoryRemovalResponse } from "../src/lib/workspace/api/workdirs.ts"; import { canRemoveWorkdir, removalCause, removeWorkdir, } from "../src/lib/workspace/settings/workdir-removal.ts"; import type { CleanupWorkdirCandidate, WorkingDirectorySummary, } from "../src/lib/workspace/sidebar/types.ts"; function assert(value: unknown, message = "assertion failed"): asserts value { if (!value) throw new Error(message); } Deno.test("removal wire boundary rejects malformed results and mismatched identities", async () => { for ( const extra of [ { retryable: "true" }, { disposition: "forgotten" }, { failure_category: {} }, { failure_category: "x".repeat(129) }, { working_directory_id: "x".repeat(129) }, { unexpected: true }, ] ) { let rejected = false; try { parseWorkingDirectoryRemovalResponse({ working_directory_id: "dir", disposition: "retained", retryable: true, ...extra, }); } catch { rejected = true; } assert( rejected, `accepted malformed removal result: ${JSON.stringify(extra)}`, ); } let rejected = false; try { await removeWorkdir( (() => Promise.resolve( Response.json({ working_directory_id: "other", disposition: "removed", retryable: false, }), )) as typeof fetch, "workspace", "runtime", "dir", ); } catch { rejected = true; } assert(rejected, "accepted removal evidence for a different Workdir"); }); Deno.test("removal response size is bounded before decoding provider content", async () => { let rejected = false; try { await removeWorkdir( (() => Promise.resolve(new Response("x".repeat(4097)))) as typeof fetch, "workspace", "runtime", "dir", ); } catch { rejected = true; } assert(rejected, "accepted an oversized removal response"); }); Deno.test("removal causes give bounded actions without echoing untrusted provider details", () => { const categories = [ "mount_present", "mount_check_unavailable", "permission_denied", "resource_busy", "storage_unavailable", "ownership_unknown", "changes_present", "changes_unknown", "provider_cleanup_failed", "provider_observation_unknown", "provider_cleanup_outcome_unknown", "authority_invalid", "provider_identity_changed", "runtime_unavailable", "provider_unavailable", "unsupported_target", "blocked_by_live_authority", "dirty_or_unknown", "authority_changed", ]; for (const category of categories) { const text = removalCause(category); assert(text !== removalCause(null), `missing category ${category}`); assert( text.length < 400 && !text.includes("/"), `unbounded or pathful category ${category}`, ); } for ( const untrusted of [ "/private/host/path", "token=synthetic-secret", "toString", "__proto__", "future_category", "x".repeat(10000), ] ) { const text = removalCause(untrusted); assert( text === removalCause(null) && !text.includes(untrusted), "echoed unknown category", ); } }); Deno.test("pending unknown cleanup permits ordinary removal while current dirty and live guards remain protected", () => { const workdir = { working_directory_id: "dir", status: "cleanup_pending", cleanliness: "unknown", source: { kind: "repository", repository_key: "main" }, materializer_kind: "runtime_git_clone", } as WorkingDirectorySummary; const candidate = { action: "workdir_clean_cleanup", blocking_reason: null, running_linked: false, pinned_linked: false, } as CleanupWorkdirCandidate; assert(canRemoveWorkdir(workdir, candidate)); for ( const guard of [ { action: "workdir_dirty_discard" }, { blocking_reason: "protected" }, { running_linked: true }, { pinned_linked: true }, ] ) { assert( !canRemoveWorkdir( workdir, { ...candidate, ...guard } as CleanupWorkdirCandidate, ), ); } assert(!canRemoveWorkdir({ ...workdir, cleanliness: "dirty" }, candidate)); assert( canRemoveWorkdir(workdir, { ...candidate, action: "workdir_record_delete", }), ); assert(!canRemoveWorkdir(workdir, { ...candidate, action: "worker_delete" })); assert(!canRemoveWorkdir(workdir, undefined)); assert( !canRemoveWorkdir({ ...workdir, occupied_by: { worker_id: "worker", runtime_id: "runtime", display_name: "Worker", linked_at: "now", }, }, candidate), ); }); Deno.test("ordinary retries send the same scoped DELETE body and expose only allowlisted HTTP causes", async () => { const requests: { path: string; body: string; method: string }[] = []; const fetchFn = (async (path: RequestInfo | URL, init?: RequestInit) => { requests.push({ path: String(path), body: String(init?.body), method: String(init?.method), }); return Response.json({ working_directory_id: "dir/x", disposition: "attention_required", retryable: true, failure_category: "mount_present", }); }) as typeof fetch; for (let i = 0; i < 2; i++) { const result = await removeWorkdir( fetchFn, "workspace/x", "runtime/x", "dir/x", ); assert(result.retryable && result.failure_category === "mount_present"); } assert( JSON.stringify(requests[0]) === JSON.stringify(requests[1]), "retry changed ordinary deletion request", ); assert( requests[0].path === "/api/w/workspace%2Fx/runtimes/runtime%2Fx/working-directories/dir%2Fx", ); assert( requests[0].method === "DELETE" && requests[0].body === JSON.stringify({ reason: "User requested Workdir deletion" }), ); for ( const [status, category] of [ [403, "permission_denied"], [409, "authority_changed"], [503, "provider_unavailable"], [500, null], ] as const ) { let message = ""; try { await removeWorkdir( (() => Promise.resolve( Response.json({ message: "/private/path token=synthetic-secret" }, { status, }), )) as typeof fetch, "workspace", "runtime", "dir", ); } catch (error) { message = error instanceof Error ? error.message : String(error); } assert( message === removalCause(category), `HTTP ${status} leaked provider text`, ); } });