Skip to content

Session-start and per-prompt injection ignore the project: memories of other projects reach every session #604

Closed

Description

@cdeust

Observed

A Claude Code session started under ~/Developments/anthropic-partnership received, at SessionStart, memories tagged japonais-2027 and IRODORI, two unrelated projects (observed 2026-09-17, session 00f3678f). The Agent Memory Atlas review of Cortex (https://neoneye.github.io/agent-memory-atlas/systems/cortex-hypermnesia/, commit 1e58077) names the same scoping gap.

Where

On main bba138ab:

  • mcp_server/hooks/auto_recall.py:122-151 (_recall_memories, PostgreSQL) and :207-232 (SQLite path): the query filters NOT m.is_benchmark and m.superseded_by_id IS NULL, nothing about the project.
  • mcp_server/hooks/session_start.py:145-160 (_fetch_anchors, is_protected = TRUE), :195-235 (_fetch_team_decisions, is_protected AND is_global), :242-281 (_fetch_hot_memories, heat_base >= %s): no project predicate either.

The store already knows how to scope: memories.directory_context exists on both backends (pg_schema.py:35, sqlite_schema.py:26) and the PostgreSQL recall function applies (p_directory IS NULL OR m.directory_context = p_directory) together with (p_include_globals AND m.is_global = TRUE) (pg_schema.py:1024-1025). The two hooks bypass that rule.

Expected

Both hooks inject only memories whose directory_context is the session's project (the event cwd, or CLAUDE_PROJECT_ROOT, and its ancestors), plus memories with is_global = TRUE. Team decisions stay global by design (session_start.py:200). A memory with an empty directory_context is not a project memory and must not be treated as matching every project.

Acceptance

  • A test per query (PostgreSQL and SQLite) that fails on main: a memory with directory_context = /other/project is injected today and must not be after the fix; a memory with is_global = TRUE and one whose directory_context is an ancestor of the session cwd still are.
  • The existing recall tool behaviour is unchanged.
  • CHANGELOG entry and ADR via wiki_adr.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Cz7A6goxVzfKL9NT7k4zDH

Metadata

Metadata

Assignees

No one assigned

    Labels

    audit-findingFinding from the project's audit cycle (.github/ISSUE_TEMPLATE/audit-finding.yml)bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions