From 5a9d9cab3da216c4c290c9a5302bbf60e17ecbfd Mon Sep 17 00:00:00 2001 From: "LIve,Laugh,Lobotomy" Date: Thu, 17 Sep 2026 20:06:16 -0400 Subject: [PATCH 1/3] refactor: centralize memory persistence policy in base manager --- src/memory-manager.ts | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/memory-manager.ts b/src/memory-manager.ts index 9fe5d6d..c4e4ea4 100644 --- a/src/memory-manager.ts +++ b/src/memory-manager.ts @@ -1,29 +1,9 @@ import { MemoryManager as BaseMemoryManager } from './memory-manager-base.js'; -import type { Memory, MemorySaveOptions } from './types.js'; /** * Public MemoryManager facade. * - * Complete provenance metadata field-by-field before delegating to the legacy - * implementation. Caller-supplied provenance values always win, while missing - * fields receive the same defaults used for fully-unannotated memories. + * Persistence policy, including provenance completion, lives in the base + * implementation so every caller follows the same write path. */ -export class MemoryManager extends BaseMemoryManager { - override async saveMemory(options: MemorySaveOptions): Promise { - const currentMeta = options.metadata ?? {}; - const completedOptions: MemorySaveOptions = { - ...options, - metadata: { - source_kind: options.source === 'auto' ? 'transcript' : 'user_supplied', - evidence_strength: 'direct_original', - source_session_id: options.sessionId, - source_agent_id: 'opencode', - source_model_id: 'default', - source_surface: 'opencode', - ...currentMeta, - }, - }; - - return super.saveMemory(completedOptions); - } -} +export class MemoryManager extends BaseMemoryManager {} From e9550115f2ffe29eda651abd47495ccca63a53e7 Mon Sep 17 00:00:00 2001 From: "LIve,Laugh,Lobotomy" Date: Thu, 17 Sep 2026 20:06:18 -0400 Subject: [PATCH 2/3] test: lock facade to shared saveMemory implementation --- test/provenance-default-completion.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/provenance-default-completion.test.ts b/test/provenance-default-completion.test.ts index 0a0fd37..da9b97d 100644 --- a/test/provenance-default-completion.test.ts +++ b/test/provenance-default-completion.test.ts @@ -1,6 +1,7 @@ import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { MemoryManager } from '../src/memory-manager.js'; +import { MemoryManager as BaseMemoryManager } from '../src/memory-manager-base.js'; function makeHarness() { const pool = { @@ -62,6 +63,10 @@ async function saveWith(metadata: Record, source: 'manual' | 'a } describe('MemoryManager provenance default completion', () => { + it('inherits the base saveMemory implementation instead of duplicating persistence policy', () => { + assert.equal(MemoryManager.prototype.saveMemory, BaseMemoryManager.prototype.saveMemory); + }); + it('fills missing provenance fields when only source_kind is supplied', async () => { const governance = { failure_mode: 'repeat mistake', From 76c480f6627cc0a53ddbfca9cf394684e8f7afe6 Mon Sep 17 00:00:00 2001 From: "LIve,Laugh,Lobotomy" Date: Thu, 17 Sep 2026 20:09:06 -0400 Subject: [PATCH 3/3] docs: describe base manager as shared persistence boundary --- src/memory-manager-base.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/memory-manager-base.ts b/src/memory-manager-base.ts index 9ecb00f..a2578d0 100644 --- a/src/memory-manager-base.ts +++ b/src/memory-manager-base.ts @@ -183,9 +183,8 @@ export class MemoryManager { * Save a memory with dual-write (structured data + embeddings) */ async saveMemory(options: MemorySaveOptions): Promise { - // Complete provenance field-by-field so direct base-class callers get the - // same guarantees as the public MemoryManager facade. Caller-supplied - // values win; only missing fields receive defaults. + // Complete provenance field-by-field at the shared persistence boundary. + // Caller-supplied values win; only missing fields receive defaults. const currentMeta = options.metadata ?? {}; options = { ...options,