diff --git a/src/agents/subagent-registry.persistence.test.ts b/src/agents/subagent-registry.persistence.test.ts index 3cb1e4a2ea3..36663b709b0 100644 --- a/src/agents/subagent-registry.persistence.test.ts +++ b/src/agents/subagent-registry.persistence.test.ts @@ -499,6 +499,45 @@ describe("subagent registry persistence", () => { expect(listSubagentRunsForRequester("agent:main:main")).toHaveLength(0); }); + it("removes attachments when pruning orphaned restored runs", async () => { + const persisted = createPersistedEndedRun({ + runId: "run-orphan-attachments", + childSessionKey: "agent:main:subagent:ghost-attachments", + task: "orphan attachments", + cleanup: "delete", + }); + const registryPath = await writePersistedRegistry(persisted, { + seedChildSessions: false, + }); + if (!tempStateDir) { + throw new Error("tempStateDir not initialized"); + } + const attachmentsRootDir = path.join(tempStateDir, "attachments"); + const attachmentsDir = path.join(attachmentsRootDir, "ghost"); + await fs.mkdir(attachmentsDir, { recursive: true }); + await fs.writeFile(path.join(attachmentsDir, "artifact.txt"), "artifact", "utf8"); + const parsed = JSON.parse(await fs.readFile(registryPath, "utf8")) as { + runs?: Record>; + }; + if (!parsed.runs?.["run-orphan-attachments"]) { + throw new Error("expected orphaned run in persisted registry"); + } + parsed.runs["run-orphan-attachments"] = { + ...parsed.runs["run-orphan-attachments"], + attachmentsRootDir, + attachmentsDir, + }; + await fs.writeFile(registryPath, `${JSON.stringify(parsed)}\n`, "utf8"); + + await restartRegistryAndFlush(); + + await expect(fs.access(attachmentsDir)).rejects.toMatchObject({ code: "ENOENT" }); + const after = JSON.parse(await fs.readFile(registryPath, "utf8")) as { + runs?: Record; + }; + expect(after.runs?.["run-orphan-attachments"]).toBeUndefined(); + }); + it("prefers active runs and can resolve them from persisted registry snapshots", async () => { const childSessionKey = "agent:main:subagent:disk-active"; await writePersistedRegistry( diff --git a/src/agents/subagent-registry.ts b/src/agents/subagent-registry.ts index 2e5967550dd..8ec9459b3b8 100644 --- a/src/agents/subagent-registry.ts +++ b/src/agents/subagent-registry.ts @@ -287,6 +287,11 @@ function reconcileOrphanedRun(params: { params.entry.cleanupCompletedAt = now; changed = true; } + const shouldDeleteAttachments = + params.entry.cleanup === "delete" || !params.entry.retainAttachmentsOnKeep; + if (shouldDeleteAttachments) { + void safeRemoveAttachmentsDir(params.entry); + } const removed = subagentRuns.delete(params.runId); resumedRuns.delete(params.runId); if (!removed && !changed) {