diff --git a/graph/fixes/fix-decay-filter-bypass-in-semantic-recall-cognitive-memory-96a6c1.md b/graph/fixes/fix-decay-filter-bypass-in-semantic-recall-cognitive-memory-96a6c1.md new file mode 100644 index 00000000000..df00e74f731 --- /dev/null +++ b/graph/fixes/fix-decay-filter-bypass-in-semantic-recall-cognitive-memory-96a6c1.md @@ -0,0 +1,32 @@ +--- +id: 96a6c125-bb69-45af-b1b6-a9b48654fb7e +type: fix +title: "Fix: decay filter bypass in semantic_recall() — cognitive-memory" +tags: [cognitive-memory, python, fix, decay, embeddings, semantic-recall] +importance: 0.6 +confidence: 0.8 +created: "2026-03-03T05:07:32.495008+00:00" +updated: "2026-03-03T05:07:32.495008+00:00" +--- + +## Problem + +`semantic_recall()` in `embeddings.py` scored all memories in `_embeddings.json` against the query vector with no decay filter. Memories with `decay_score < THRESHOLD_DORMANT` (0.05) — archived/dormant — could re-surface if their semantic similarity was high enough, bypassing the decay system's intent. + +The keyword path in `recall()` (`client.py`) already applied this filter correctly. + +## Root Cause + +`EmbeddingsMixin.semantic_recall()` only loaded the index (`_load_index()`), not the state (`_load_state()`). The decay threshold guard was missing entirely. + +## Solution + +Added `THRESHOLD_DORMANT` to `embeddings.py` imports from `common`. In `semantic_recall()`, loaded `_state.json` via `self._load_state()` and added a `decay_score < THRESHOLD_DORMANT` skip before computing cosine similarity. + +## Files Changed + +- `embeddings.py` — 6-line change: import + state load + filter + +## PR + +https://git.manticorum.com/cal/cognitive-memory/pulls/7