From 962d1096d492524b3f6f55c8dcd91cd3ba385890 Mon Sep 17 00:00:00 2001 From: Alix-007 Date: Tue, 7 Jul 2026 02:16:26 +0800 Subject: [PATCH] fix(memory-core): keep daily ingestion outside session repair (#93389) * fix(memory-core): clear daily-ingestion sqlite namespace on dreaming repair repairDreamingArtifacts() cleared the dreaming-session-ingestion-files and dreaming-session-ingestion-seen namespaces but not the migrated dreaming-daily-ingestion namespace. After #92020 taught auditDreamingArtifacts() to treat all three ingestion namespaces as ingestion state, the repair path became asymmetric: the memory status --fix re-audit still reported sessionIngestionExists=true from the surviving daily rows, and the daily ingestion bookkeeping leaked past repair so daily memory files were not re-ingested on the next sweep. Clear DREAMING_DAILY_INGESTION_NAMESPACE alongside the session files/seen namespaces so repair fully resets dreaming ingestion state, matching the audit. * chore: retrigger CI for real behavior proof check * fix(memory-core): keep daily ingestion outside session repair Co-authored-by: Vincent Koc Co-authored-by: Alix-007 --------- Co-authored-by: Peter Steinberger Co-authored-by: Vincent Koc --- .../memory-core/src/dreaming-repair.test.ts | 43 ++++++++++++++++++- extensions/memory-core/src/dreaming-repair.ts | 4 +- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/extensions/memory-core/src/dreaming-repair.test.ts b/extensions/memory-core/src/dreaming-repair.test.ts index f130188db471..7228e203a88f 100644 --- a/extensions/memory-core/src/dreaming-repair.test.ts +++ b/extensions/memory-core/src/dreaming-repair.test.ts @@ -199,6 +199,10 @@ describe("dreaming artifact repair", () => { }), ]); + await expect( + auditDreamingArtifacts({ workspaceDir }).then((audit) => audit.sessionIngestionExists), + ).resolves.toBe(true); + const repair = await repairDreamingArtifacts({ workspaceDir }); expect(repair.archivedSessionCorpus).toBe(true); @@ -214,6 +218,41 @@ describe("dreaming artifact repair", () => { workspaceDir, }), ).resolves.toEqual([]); + await expect( + auditDreamingArtifacts({ workspaceDir }).then((audit) => audit.sessionIngestionExists), + ).resolves.toBe(false); + }); + + it("preserves sqlite daily ingestion state when archiving session corpus", async () => { + const workspaceDir = await createWorkspace(); + const sessionCorpusDir = path.join(workspaceDir, "memory", ".dreams", "session-corpus"); + await fs.mkdir(sessionCorpusDir, { recursive: true }); + await fs.writeFile(path.join(sessionCorpusDir, "2026-04-11.txt"), "corpus\n", "utf-8"); + await writeMemoryCoreWorkspaceEntries({ + namespace: DREAMING_DAILY_INGESTION_NAMESPACE, + workspaceDir, + entries: [ + { + key: "2026-06-10", + value: { ingestedAt: 1_000, lastDreamingDayIngested: "2026-06-10" }, + }, + ], + }); + + const repair = await repairDreamingArtifacts({ workspaceDir }); + + expect(repair.archivedSessionCorpus).toBe(true); + await expect( + readMemoryCoreWorkspaceEntries({ + namespace: DREAMING_DAILY_INGESTION_NAMESPACE, + workspaceDir, + }), + ).resolves.toEqual([ + { + key: "2026-06-10", + value: { ingestedAt: 1_000, lastDreamingDayIngested: "2026-06-10" }, + }, + ]); }); it("reports ingestion state present from SQLite when legacy JSON is absent", async () => { @@ -235,7 +274,7 @@ describe("dreaming artifact repair", () => { expect(audit.sessionIngestionExists).toBe(true); }); - it("reports ingestion state present from SQLite daily namespace", async () => { + it("does not report session ingestion from the SQLite daily namespace", async () => { const workspaceDir = await createWorkspace(); // Only daily ingestion namespace has rows await writeMemoryCoreWorkspaceEntries({ @@ -251,6 +290,6 @@ describe("dreaming artifact repair", () => { const audit = await auditDreamingArtifacts({ workspaceDir }); - expect(audit.sessionIngestionExists).toBe(true); + expect(audit.sessionIngestionExists).toBe(false); }); }); diff --git a/extensions/memory-core/src/dreaming-repair.ts b/extensions/memory-core/src/dreaming-repair.ts index c24c79ef5891..644f924fde5b 100644 --- a/extensions/memory-core/src/dreaming-repair.ts +++ b/extensions/memory-core/src/dreaming-repair.ts @@ -5,7 +5,6 @@ import path from "node:path"; import { extractErrorCode } from "openclaw/plugin-sdk/error-runtime"; import { clearMemoryCoreWorkspaceNamespace, - DREAMING_DAILY_INGESTION_NAMESPACE, DREAMING_SESSION_INGESTION_FILES_NAMESPACE, DREAMING_SESSION_INGESTION_SEEN_NAMESPACE, readMemoryCoreWorkspaceEntries, @@ -213,10 +212,11 @@ export async function auditDreamingArtifacts(params: { // Fall back to SQLite plugin state when the legacy JSON file was archived by migration. if (!sessionIngestionExists) { try { + // Daily ingestion tracks memory/*.md independently; session repair must not + // report or clear that healthy bookkeeping when rebuilding the session corpus. const ingestionNamespaces = [ DREAMING_SESSION_INGESTION_FILES_NAMESPACE, DREAMING_SESSION_INGESTION_SEEN_NAMESPACE, - DREAMING_DAILY_INGESTION_NAMESPACE, ] as const; for (const namespace of ingestionNamespaces) { const entries = await readMemoryCoreWorkspaceEntries({