Skip to content

fix: preserve exact namespace filter in semantic search fallback#334

Open
ns-jlizarraga wants to merge 2 commits into
redis:mainfrom
ns-jlizarraga:fix/preserve-eq-namespace-filter-in-fallback
Open

fix: preserve exact namespace filter in semantic search fallback#334
ns-jlizarraga wants to merge 2 commits into
redis:mainfrom
ns-jlizarraga:fix/preserve-eq-namespace-filter-in-fallback

Conversation

@ns-jlizarraga

@ns-jlizarraga ns-jlizarraga commented Jul 4, 2026

Copy link
Copy Markdown

Problem

When a semantic search returns zero results and the server falls back to a broader query, the existing code unconditionally strips the namespace filter along with topics, entities, memory_type, and extraction_strategy.

This is correct for broad filters (any/all), but wrong for exact filters (eq). If the caller passed namespace: {eq: "troubleshooting:service-a"}, they are asking a precise, scoped question. Returning a memory from a completely different namespace in the fallback is more harmful than returning zero results — it silently crosses a trust boundary the caller explicitly set.

Change

Instead of always dropping the namespace filter in the fallback, we now check its type:

  • No namespace filter or broad filter (any/all) → drop it in the fallback (existing behavior, correct)
  • Exact filter (eq) → preserve it in the fallback so results stay scoped to the namespace the caller asked for
ns_filter = filters.get("namespace") if filters else None
if ns_filter is None or getattr(ns_filter, "eq", None) is None:
    fallback_kwargs.pop("namespace", None)

Why not just always preserve namespace?

Because the fallback exists precisely to widen the search when strict filters yield nothing. A broad namespace filter like any: ["troubleshooting:service-a", "troubleshooting:service-b"] is still a reasonable thing to relax. Only an exact eq match represents a hard scope boundary that should survive the fallback.


Note

Medium Risk
Search fallback behavior changes what clients see when strict filters return no hits (scope vs empty results). Dockerfile healthcheck removal shifts responsibility to compose/orchestration.

Overview
Semantic search fallback no longer always strips namespace. When the zero-hit fallback widens other strict filters, an exact namespace eq is kept so results stay in the caller’s scope; broad or missing namespace filters are still dropped as before.

Docker images (standard and aws) no longer define a HEALTHCHECK against /v1/health, since the same image runs API, MCP, and task-worker with different needs. Health checks are expected per service in docker-compose.yml.

Reviewed by Cursor Bugbot for commit a3ae51e. Bugbot is set up for automated code reviews on this repo. Configure here.

Copilot AI review requested due to automatic review settings July 4, 2026 15:31
@jit-ci

jit-ci Bot commented Jul 4, 2026

Copy link
Copy Markdown

Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset.

In case there are security findings, they will be communicated to you as a comment inside the PR.

Hope you’ll enjoy using Jit.

Questions? Comments? Want to learn more? Get in touch with us.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts long-term semantic search fallback behavior to respect exact namespace scoping and updates the Docker image to avoid embedding a single healthcheck in a multi-purpose runtime image.

Changes:

  • Preserve namespace when it is an exact eq filter during semantic-search soft-filter fallback, while still relaxing other strict filters.
  • Remove the baked-in Docker HEALTHCHECK from shared runtime stages, relying on per-service healthchecks (e.g., in docker-compose.yml).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
Dockerfile Removes image-level HEALTHCHECK because the image is used for multiple process types with different health semantics.
agent_memory_server/api.py Changes soft-filter fallback to keep exact namespace.eq scoping instead of always dropping namespace.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread agent_memory_server/api.py Outdated
Comment on lines +783 to +785
ns_filter = filters.get("namespace") if filters else None
if ns_filter is None or getattr(ns_filter, "eq", None) is None:
fallback_kwargs.pop("namespace", None)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants