
























@@ -297,6 +297,52 @@ describe("Crestodian rescue message", () => {
297297expect(audit.details?.senderId).toBe("user:owner");
298298});
299299300+it("does not queue persistent rescue approval when expiry would exceed the Date range", async () => {
301+const tempDir = await makeStateDir("overflow-expiry-");
302+vi.stubEnv("OPENCLAW_STATE_DIR", tempDir);
303+vi.useFakeTimers();
304+vi.setSystemTime(new Date(8_640_000_000_000_000));
305+try {
306+const cfg: OpenClawConfig = { crestodian: { rescue: { enabled: true } } };
307+308+await expect(
309+runRescue("/crestodian restart gateway", cfg, commandContext()),
310+).resolves.toContain("expiry clock is invalid");
311+312+await expect(fs.readdir(path.join(tempDir, "crestodian", "rescue-pending"))).rejects.toThrow(
313+/ENOENT/,
314+);
315+} finally {
316+vi.useRealTimers();
317+}
318+});
319+320+it("rejects pending rescue approvals with invalid persisted expiry", async () => {
321+const tempDir = await makeStateDir("invalid-expiry-");
322+vi.stubEnv("OPENCLAW_STATE_DIR", tempDir);
323+const cfg: OpenClawConfig = { crestodian: { rescue: { enabled: true } } };
324+const deps = { runGatewayRestart: vi.fn(async () => {}) };
325+326+await expect(
327+runRescue("/crestodian restart gateway", cfg, commandContext(), deps),
328+).resolves.toContain("Reply /crestodian yes to apply");
329+const pendingDir = path.join(tempDir, "crestodian", "rescue-pending");
330+const [pendingFile] = await fs.readdir(pendingDir);
331+if (!pendingFile) {
332+throw new Error("expected pending rescue file");
333+}
334+const pendingPath = path.join(pendingDir, pendingFile);
335+const pending = JSON.parse(await fs.readFile(pendingPath, "utf8")) as { expiresAt?: string };
336+pending.expiresAt = "not-a-date";
337+await fs.writeFile(pendingPath, `${JSON.stringify(pending, null, 2)}\n`, "utf8");
338+339+await expect(runRescue("/crestodian yes", cfg, commandContext(), deps)).resolves.toBe(
340+"No pending Crestodian rescue change is waiting for approval.",
341+);
342+expect(deps.runGatewayRestart).not.toHaveBeenCalled();
343+await expect(fs.stat(pendingPath)).rejects.toThrow(/ENOENT/);
344+});
345+300346it("queues and applies agent creation through conversational approval", async () => {
301347const tempDir = await makeStateDir("agent-");
302348vi.stubEnv("OPENCLAW_STATE_DIR", tempDir);
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。