Repository navigation
Memory read path ignores cwd and injects entire global memory_summary.md into initial context for new sessions #17496
Description
What issue are you seeing?
Codex's memory write path is cwd-aware, but the memory read/injection path is not.
Today, phase 2 consolidation explicitly preserves cwd/project boundaries in the memory artifacts:
MEMORY.mdblocks requireapplies_to: cwd=...in the schema incodex-rs/core/templates/memories/consolidation.md:197- the consolidation instructions say to separate similar tasks across different cwd contexts by default in
codex-rs/core/templates/memories/consolidation.md:293 - the summary/index is organized first by cwd/project scope in
codex-rs/core/templates/memories/consolidation.md:546
However, when Codex builds the initial context for a fresh conversation / baseline, the runtime prompt injection path reads and injects the entire global ~/.codex/memories/memory_summary.md without any cwd/project filtering:
- the initial context builder appends the memory developer prompt in
codex-rs/core/src/codex.rs:3764 build_memory_tool_developer_instructions(...)reads the wholememory_summary.mdincodex-rs/core/src/memories/prompts.rs:234- the read prompt injects
{{ memory_summary }}wholesale incodex-rs/core/templates/memories/read_path.md:124 - the full initial context is used when
reference_context_item.is_none()incodex-rs/core/src/codex.rs:3928
Steady-state turns appear to use the settings-diff path instead of rebuilding the full initial context, so this is specifically an initial-context / new-conversation boundary issue rather than a claim that the full memory summary is re-injected on every turn.
This still creates a real failure mode for multi-repo users: a fresh session in one repo gets irrelevant memory from other repos injected into context before the model starts working. That is both noisy and architecturally inconsistent with the cwd-aware write/consolidation design.
Concretely, I have a generated memory_summary.md that contains both /Users/georgepickett/polyscraper and unrelated /Users/georgepickett/explore-computer sections. A fresh polyscraper session would get both injected, even though only the polyscraper section is relevant.
This also makes multiple memories_extensions/*/instructions.md files indirectly compete over one shared global summary: phase 2 reads all extension instructions and rewrites one global memory_summary.md, but the runtime still injects that single shared summary into fresh initial context everywhere.
Why this matters:
- irrelevant context can bias the model toward the wrong workflow
- unrelated memory competes for the limited injected summary budget
- the injected summary is truncated to 5,000 tokens in
codex-rs/core/src/memories/mod.rs:46, so unrelated repo memory can crowd out the repo that actually matters - the system is storing project boundaries in the data model but not respecting them in retrieval/injection
What steps can reproduce the bug?
- Enable memories and allow the startup memory pipeline to run. The startup trigger is in
codex-rs/core/src/memories/start.rs:14. - Use Codex across at least two distinct repos/cwds so phase 1 and phase 2 build cross-project memory.
- Let phase 2 consolidate those memories into a shared
~/.codex/memories/memory_summary.md. Phase 2's global consolidation pass is incodex-rs/core/src/memories/phase2.rs:80. - Confirm that
memory_summary.mdnow contains multiple cwd/project sections. - Start a new top-level session in one repo (for example,
/Users/georgepickett/polyscraper). - Observe from the code path that the initial context builder reads the entire
memory_summary.mdand injects it without filtering to the current cwd/project.
This is easiest to see from the code rather than a single UI screenshot:
- injection gate:
codex-rs/core/src/codex.rs:3764 - full-file read:
codex-rs/core/src/memories/prompts.rs:234 - prompt template includes the whole summary:
codex-rs/core/templates/memories/read_path.md:124 - fresh baseline path:
codex-rs/core/src/codex.rs:3928
What is the expected behavior?
The read path should respect the same repo/cwd boundary that the write/consolidation path is already trying to preserve.
A better architecture would be a hybrid model:
- maintain a tiny global user profile for genuinely cross-project preferences
- maintain per-repo/per-cwd
memory_summaryandMEMORYartifacts for repo-specific workflow, status, runbooks, and history - on a new session / fresh baseline, inject:
- the tiny global profile, plus
- only the matching repo/cwd summary for the current session
- keep repo-specific detailed memory (
MEMORY.md, rollout summaries, skills) scoped to that repo/cwd for later lookup
At minimum, build_memory_tool_developer_instructions(...) should filter or select the relevant section(s) of the summary by current cwd/project before injection, instead of pasting the entire global file.
Additional information
A few related design tensions surfaced while tracing this locally:
- Phase 2 reads all
memories_extensions/*/instructions.mdfiles in the consolidation prompt incodex-rs/core/src/memories/prompts.rs:55, so multiple extensions currently influence one sharedmemory_summary.md. - Because the runtime injects one global summary into fresh initial context, those extensions indirectly compete for a single prompt budget over time.
- This makes
instructions.mda mitigation for summary quality, but not a real fix for retrieval/injection scope.
Suggested implementation directions:
- add cwd/project-aware selection inside
build_memory_tool_developer_instructions(...) - or split artifacts into:
- global profile summary
- per-repo/per-cwd summary
- per-repo/per-cwd detailed memory
- use current cwd/project root as the primary routing key, with global profile as a fallback/overlay
Activity
[-]Memory injection ignores repo/cwd boundaries and injects unrelated global summary into new sessions[/-][+]Memory read path ignores cwd and injects entire global memory_summary.md into new sessions[/+]github-actions commentedon Apr 11, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
[-]Memory read path ignores cwd and injects entire global memory_summary.md into new sessions[/-][+]Memory read path ignores cwd and injects entire global memory_summary.md into initial context for new sessions[/+]raye-deng commentedon Apr 12, 2026
This is a sharp observation — the asymmetry between write-path and read-path cwd awareness is exactly the kind of inconsistency that causes subtle, hard-to-reproduce failures in agent workflows.
The practical impact is worse than "wrong context gets loaded." When global memory from project A gets injected into a session for project B, the agent may:
Import packages that exist in project A but not project B — the agent "knows" about
project-a-utilsfrom memory and generates an import. Compiles fine if types are cached. Fails at runtime with MODULE_NOT_FOUND.Apply architecture patterns from one project to another — project A uses hexagonal architecture with dependency injection, project B is a simple Express CRUD. The agent generates DI containers and interface abstractions for project B because global memory tells it "this team uses hexagonal architecture." Code review approves because it looks clean. But now a simple feature takes 7 files instead of 2.
Generate API calls to wrong endpoints — memory contains "API base is /api/v2" from project A, but project B uses /api/v1. The agent generates correct-looking fetch calls that hit 404s or, worse, silently hit the wrong data.
The reason this is hard to catch: none of these failures look like bugs in isolation. Each one looks like "the developer made a reasonable choice that happened to be wrong for this specific project." Traditional linters and SonarQube can't distinguish between a correct import and a correct-looking-but-contextually-wrong import.
The cwd-aware read path fix you're proposing is the right approach. On our side, we handle this by validating imports and API references against the actual project context (not global state) as part of the PR pipeline.
npx @opencodereview/cli scan . --sla L1if you want to see what context-aware import validation looks like in practice.jif-oai commentedon Apr 13, 2026
This is by design for the current models