From a60f7f828cbcaf8fc540205fa1b2aa4b9743ac7f Mon Sep 17 00:00:00 2001 From: "Claude (scheduled routine)" Date: Thu, 30 Jul 2026 00:09:56 +0000 Subject: [PATCH] Fix #94: admit promoted reflections in the project namespace on retrieve _fetch_reflection_buckets restricted the project namespace admit set to {active} while reflection_list and the migrator both use {active, promoted}: migrated confirmed reflections (scope=project, body status= promoted) were parsed and then silently dropped, so every memory.retrieve returned only pending_review rows. Widen the project admit set to match. --- better_memory/storage/agentcore.py | 8 ++++--- tests/storage/test_agentcore_unit.py | 32 ++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/better_memory/storage/agentcore.py b/better_memory/storage/agentcore.py index f407743..e3dbfee 100644 --- a/better_memory/storage/agentcore.py +++ b/better_memory/storage/agentcore.py @@ -446,9 +446,11 @@ def _fetch_reflection_buckets( project_ns = resolve_namespace(actor_id, "reflections") general_ns = resolve_namespace("general", "reflections") allowed_general = frozenset({"active", "promoted"}) - allowed_project = ( - allowed_general if actor_id == "general" else frozenset({"active"}) - ) + # Same admit set as ``reflection_list`` — a migrated ``confirmed`` + # reflection lives in ``projects/{p}/reflections/`` with body status + # ``promoted`` (see agentcore_migrate: confirmed→promoted, scope→ns); + # narrower vocabularies here silently drop the reviewed corpus. + allowed_project = allowed_general namespaces: list[tuple[str, frozenset[str]]] = [ (project_ns, allowed_project) ] diff --git a/tests/storage/test_agentcore_unit.py b/tests/storage/test_agentcore_unit.py index a5ff2f1..2f4c913 100644 --- a/tests/storage/test_agentcore_unit.py +++ b/tests/storage/test_agentcore_unit.py @@ -662,12 +662,12 @@ def stub(**kwargs): assert [r["id"] for r in result["dont"]] == ["rec-promoted"] -def test_retrieve_excludes_non_active_status_in_project_namespace( +def test_retrieve_excludes_retired_in_project_namespace( backend, mock_data_client ) -> None: - """A project-namespace record whose status is explicitly not active - (e.g. retired, or promoted served stale by the lagging index) is - excluded — promoted records are only admitted via general/.""" + """Retired reflections in the project namespace are excluded on + retrieve — the admit set is ``{active, promoted}``, matching the + ``reflection_list`` vocabulary (see #94).""" def stub(**kwargs): if kwargs["namespace"] == "projects/testproj/reflections/": return {"memoryRecordSummaries": [ @@ -676,17 +676,37 @@ def stub(**kwargs): namespace="/projects/testproj/reflections/", status="retired", ), + ]} + return {"memoryRecordSummaries": []} + + mock_data_client.list_memory_records.side_effect = stub + result = backend.retrieve(project="testproj") + assert result == {"do": [], "dont": [], "neutral": []} + + +def test_retrieve_includes_promoted_records_in_project_namespace( + backend, mock_data_client +) -> None: + """Migrated ``confirmed`` reflections land in ``projects/{p}/reflections/`` + with body status ``promoted`` (see ``agentcore_migrate``: confirmed → + promoted, scope drives namespace). The project-namespace admit set must + surface them — a narrower ``{active}`` silently drops the entire + reviewed corpus. See #94.""" + def stub(**kwargs): + if kwargs["namespace"] == "projects/testproj/reflections/": + return {"memoryRecordSummaries": [ _reflection_summary( - "rec-stale-promoted", + "rec-migrated-confirmed", namespace="/projects/testproj/reflections/", status="promoted", + polarity="do", ), ]} return {"memoryRecordSummaries": []} mock_data_client.list_memory_records.side_effect = stub result = backend.retrieve(project="testproj") - assert result == {"do": [], "dont": [], "neutral": []} + assert [r["id"] for r in result["do"]] == ["rec-migrated-confirmed"] def test_retrieve_defaults_missing_status_and_polarity(