diff --git a/packages/server/src/server/agent/agent-storage.test.ts b/packages/server/src/server/agent/agent-storage.test.ts index aea52e118..ba51f3dc5 100644 --- a/packages/server/src/server/agent/agent-storage.test.ts +++ b/packages/server/src/server/agent/agent-storage.test.ts @@ -162,6 +162,32 @@ describe("AgentStorage", () => { expect(updatedRecord?.lastStatus).toBe("running"); }); + test("applySnapshot preserves archivedAt (soft-delete) status", async () => { + const agentId = "agent-archived"; + await storage.applySnapshot( + createManagedAgent({ + id: agentId, + lifecycle: "idle", + }) + ); + + const archivedAt = "2025-01-03T00:00:00.000Z"; + const recordBeforeArchive = await storage.get(agentId); + expect(recordBeforeArchive).not.toBeNull(); + await storage.upsert({ ...recordBeforeArchive!, archivedAt }); + + await storage.applySnapshot( + createManagedAgent({ + id: agentId, + lifecycle: "running", + updatedAt: new Date("2025-01-04T00:00:00.000Z"), + }) + ); + + const recordAfterSnapshot = await storage.get(agentId); + expect(recordAfterSnapshot?.archivedAt).toBe(archivedAt); + }); + test("stores titles independently of snapshots", async () => { await storage.applySnapshot( createManagedAgent({ diff --git a/packages/server/src/server/agent/agent-storage.ts b/packages/server/src/server/agent/agent-storage.ts index a29d00bd5..c405b0885 100644 --- a/packages/server/src/server/agent/agent-storage.ts +++ b/packages/server/src/server/agent/agent-storage.ts @@ -230,6 +230,13 @@ export class AgentStorage { ? options?.internal : (agent.internal ?? existing?.internal), }); + + // Preserve soft-delete/archive status across snapshot flushes. + // `archivedAt` is not part of the ManagedAgent snapshot, so a naive projection + // would wipe it during normal persistence (including on daemon restart). + if (existing && existing.archivedAt !== undefined) { + record.archivedAt = existing.archivedAt; + } await this.upsert(record); }