From a1ee62d7a1fb5e193c82dd0ead51efd6e4bcf4b6 Mon Sep 17 00:00:00 2001 From: zerone0x Date: Wed, 4 Mar 2026 21:09:00 +0100 Subject: [PATCH] fix(memory-flush): ban timestamped variant files in default flush prompt Add an explicit instruction to DEFAULT_MEMORY_FLUSH_PROMPT prohibiting the creation of timestamped variant files (e.g. YYYY-MM-DD-HHMM.md) alongside the canonical daily log file (YYYY-MM-DD.md). Before this change, the default prompt only instructed the agent to append to existing files, which prevented overwrites (#6877 / PR #6878) but did not prevent agents from creating new timestamped variants instead of appending to the canonical file. This resulted in orphaned fragment files like `2026-03-03-1709.md` accumulating in the memory/ directory across dates. The updated prompt now contains two explicit guards: 1. Append-only: do not overwrite existing entries (existing, from #6878) 2. No variants: always use the canonical YYYY-MM-DD.md filename Also adds two tests to memory-flush.test.ts that verify both instructions are present in the default prompt, preventing future accidental removal. Fixes #34919 Co-Authored-By: Claude --- src/auto-reply/reply/memory-flush.test.ts | 15 ++++++++++++++- src/auto-reply/reply/memory-flush.ts | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/auto-reply/reply/memory-flush.test.ts b/src/auto-reply/reply/memory-flush.test.ts index e444b9e7a80..0e04e7e0ea3 100644 --- a/src/auto-reply/reply/memory-flush.test.ts +++ b/src/auto-reply/reply/memory-flush.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; -import { resolveMemoryFlushPromptForRun } from "./memory-flush.js"; +import { DEFAULT_MEMORY_FLUSH_PROMPT, resolveMemoryFlushPromptForRun } from "./memory-flush.js"; describe("resolveMemoryFlushPromptForRun", () => { const cfg = { @@ -36,3 +36,16 @@ describe("resolveMemoryFlushPromptForRun", () => { expect((prompt.match(/Current time:/g) ?? []).length).toBe(1); }); }); + +describe("DEFAULT_MEMORY_FLUSH_PROMPT", () => { + it("includes append-only instruction to prevent overwrites (#6877)", () => { + expect(DEFAULT_MEMORY_FLUSH_PROMPT).toMatch(/APPEND/i); + expect(DEFAULT_MEMORY_FLUSH_PROMPT).toContain("do not overwrite"); + }); + + it("includes anti-fragmentation instruction to prevent timestamped variant files (#34919)", () => { + // Agents must not create YYYY-MM-DD-HHMM.md variants alongside the canonical file + expect(DEFAULT_MEMORY_FLUSH_PROMPT).toContain("timestamped variant"); + expect(DEFAULT_MEMORY_FLUSH_PROMPT).toContain("YYYY-MM-DD.md"); + }); +}); diff --git a/src/auto-reply/reply/memory-flush.ts b/src/auto-reply/reply/memory-flush.ts index e23703c7b6c..c02fad5eca0 100644 --- a/src/auto-reply/reply/memory-flush.ts +++ b/src/auto-reply/reply/memory-flush.ts @@ -13,7 +13,8 @@ export const DEFAULT_MEMORY_FLUSH_FORCE_TRANSCRIPT_BYTES = 2 * 1024 * 1024; export const DEFAULT_MEMORY_FLUSH_PROMPT = [ "Pre-compaction memory flush.", "Store durable memories now (use memory/YYYY-MM-DD.md; create memory/ if needed).", - "IMPORTANT: If the file already exists, APPEND new content only and do not overwrite existing entries.", + "IMPORTANT: If the file already exists, APPEND new content only — do not overwrite existing entries.", + "Do NOT create timestamped variant files (e.g., YYYY-MM-DD-HHMM.md); always use the canonical YYYY-MM-DD.md filename.", `If nothing to store, reply with ${SILENT_REPLY_TOKEN}.`, ].join(" ");