From 6340901c9ca1f97d38d504b7b74cb121fe16572e Mon Sep 17 00:00:00 2001 From: Chaos Date: Tue, 4 Aug 2026 10:56:42 +0200 Subject: [PATCH] fix: exclude superseded memories from recall and classify all markdown as docs Two bugs in the memory and RAG indexers: 1. recall (internal/memory/read.go): entries marked as superseded_by (e.g. after a merge) were still returned as top semantic matches. They now stay invisible to recall while remaining visible to List/ListLightweight for maintenance tools. 2. markdown classification (internal/rag/documents.go): classifySourceType received empty content, so a plain .md file (not README, not under docs/) fell through and was silently skipped with 0 chunks. Every .md file is now classified as 'docs'. Adds regression test cases. --- .gitignore | 1 + internal/memory/read.go | 8 ++++++++ internal/rag/documents.go | 4 +--- internal/rag/rag_test.go | 2 ++ 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index a069947..f9882f3 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ logs/ # Go vendor/ +agent-memory-mcp-new diff --git a/internal/memory/read.go b/internal/memory/read.go index 98b9c77..dd7a17f 100644 --- a/internal/memory/read.go +++ b/internal/memory/read.go @@ -197,6 +197,14 @@ func (ms *Store) Recall(ctx context.Context, query string, filters Filters, limi continue } + // Superseded entries (temporal replacement, e.g. after a merge) are + // invisible to semantic recall — the successor carries the current + // knowledge. Kept in the DB for temporal history; List/ListLightweight + // still return them for maintenance tools. + if m.SupersededBy != "" { + continue + } + // T48 layer-aware filtering: when the flag is on, surface memories // are invisible outside their originating Context. This prevents // session scratch state from leaking into unrelated recall calls. diff --git a/internal/rag/documents.go b/internal/rag/documents.go index b15c3da..a5991db 100644 --- a/internal/rag/documents.go +++ b/internal/rag/documents.go @@ -237,9 +237,7 @@ func classifySourceType(docPath string, title string, content string) string { return "k8s" } case ext == ".md": - if baseLower == "readme.md" || strings.HasPrefix(pathLower, "docs/") || strings.Contains(pathLower, "/docs/") || strings.Contains(contentLower, "# ") { - return "docs" - } + return "docs" case ext == ".yaml" || ext == ".yml": if strings.Contains(contentLower, "apiVersion:") && strings.Contains(contentLower, "kind:") { return "k8s" diff --git a/internal/rag/rag_test.go b/internal/rag/rag_test.go index 85e2002..8fef67a 100644 --- a/internal/rag/rag_test.go +++ b/internal/rag/rag_test.go @@ -569,6 +569,8 @@ func TestClassifySourceType(t *testing.T) { {path: "k8s/ingress.yaml", want: "k8s"}, {path: "dead_ends/why-we-avoid-async-migration.md", want: "dead_end"}, {path: "notes/why-we-avoid-shared-mutable-state.md", want: "dead_end"}, + {path: "knowledge/mahoo-architecture.md", want: "docs"}, + {path: "plans/analysis.md", want: "docs"}, } for _, tc := range tests {