How to check what your coding agent actually remembered
An agent can say it remembers and still be guessing. The quiet failure is not an error message. The agent says "I remember", then uses a detail from your prompt. Or a hook — a shell command the agent runs at a lifecycle event — writes nothing while the status page stays green. Memory has three layers, and most checks stop at the first.
Checked against each tool's documentation on 26–27 October 2026.
Three layers#
| Layer | Question | Where it shows |
|---|---|---|
| Capture | Did anything get written? | A hook spool, a memory folder, a stored page |
| Load | Did it enter this session's context? | /context, the model-visible prompt, a session-start message |
| Use | Did the model act on it? | The answer, the command, the diff |
Passing one is not passing the next. A file can exist and never load. A memory page can load and be ignored. The check below tests all three.
The five-minute check#
- Write a fact that cannot be guessed. "The staging deploy key is in 1Password, item
staging-deploy. Added 2026-10-26." Do not write "we use staging". - Put it where the tool should remember it. An instruction file, the agent's built-in memory, or a shared page. Note the exact path.
- Start a new session in the same project. Do not paste the fact into the prompt.
- Ask for the fact and its source. "What is the staging deploy key location, and where did you read it?" The source is a file path and line, a page path and revision, or a tool result.
- Change one word in the source. Start another session. Ask again. If the answer changes, the source is live. If it does not, the agent was guessing or reading a cache.
- If it fails, classify it. Not captured, not loaded, or not used. The rest of this page is the per-tool version of those three.
"Does Claude Code remember between sessions?" is the same test: a new session plus a fact that only the store knows. A resumed conversation proves continuity, not memory.
Claude Code#
Run /memory. It lists CLAUDE.md, CLAUDE.local.md and the auto memory folder, and it opens any of them in your editor. Auto memory is Claude Code's own notes, written by the model and stored as markdown on your machine. If the fact is not in one of those files, Claude Code did not capture it.
Run /context. It shows which memory files loaded at launch. If a file is missing there, Claude Code cannot see it, and asking the model to "remember" will not change that. The same view shows what is using the window, which matters when a long instruction file is crowding out the task.
Watch for "Saved 2 memories" or "Recalled 2 memories". A save message is capture, not load. Auto memory stores MEMORY.md as an index; topic files load on demand. A fact in a topic file that the index does not point to is captured and loads only if Claude opens it. The files are machine-local, so a new laptop is a new memory.
For instruction files that look stale or contradictory, /doctor prompt-audit checks CLAUDE.md, CLAUDE.local.md, AGENTS.md, rules, skills and subagents (helper agents Claude can start), and reports problems before you edit. It needs Claude Code v2.1.283 or later. To see which files load and when, the InstructionsLoaded hook can log each load, including path-scoped rules and nested files.
/resume reloads an earlier conversation. It is not a memory check. The check is a fresh session that was never told the fact.
Did auto memory load?#
Run /memory to check that auto memory is on and which folder it opened. Then:
ls ~/.claude/projects/<project>/memory/
wc -l ~/.claude/projects/<project>/memory/MEMORY.md
wc -c ~/.claude/projects/<project>/memory/MEMORY.mdThe index is MEMORY.md; its first 200 lines or 25KB load at the start of a conversation, and topic files load on demand. Over either limit means the tail did not load. The worktree cases and the full check are in Claude Code auto memory.
Codex#
Codex builds its AGENTS.md chain once per run: the global file under CODEX_HOME (default ~/.codex/AGENTS.md), then one file per directory from the repository root down to the working directory. The project files share a 32 KiB budget by default. An edit made during a run may not reach that run. Start a new one.
The documentation gives two direct checks. From the repository root:
codex --ask-for-approval never "Summarize the current instructions."From a subdirectory, to see which files are active:
codex --cd services/payments --ask-for-approval never "Show which instruction files are active."For the exact model-visible prompt, run codex debug prompt-input in the CLI. It prints the prompt input as JSON, which is the closest thing to seeing what the model was handed. The TUI log — the terminal interface's log — is another route: start with codex -c log_dir=./.codex-log and read ./.codex-log/codex-tui.log; the docs also mention the most recent session-*.jsonl when session logging is on.
Codex memories are off by default, stored under the Codex home (by default ~/.codex/memories/), and the docs describe them as generated state. Inspect them when troubleshooting, but do not treat a hand edit as the primary control surface. If memories are off, AGENTS.md is the only memory.
Did Codex memories load?#
In the Codex TUI or the ChatGPT desktop app, start with /memories. It has two switches: one for reading existing memories, one for adding this chat to future memory generation. A chat can read without contributing. If the read switch is off, the store can be full and the chat still sees nothing.
Then look at the store:
ls "${CODEX_HOME:-$HOME/.codex}/memories/"The docs describe summaries, durable entries, recent inputs and supporting evidence. The store is one directory per Codex home, not one per repository. A fact in a file there was captured. That is not proof this chat loaded it.
Status, 26 October 2026: two open reports matter for this check. A CLI report says the model-visible prompt can still tell the model it may only read memories, not update them, when the feature flag is on, so "enabled" does not prove a chat can contribute (#19195, last updated 7 July 2026). A desktop-app report says the injected memory summary (memory_summary.md) is cut in the middle at 2,500 tokens, with the newest entries dropped and no warning (#48679, last updated 24 October 2026). If the agent quotes an old memory but not the one you just added, that cut is a likely reason.
Ask for the memory line and the file or chat it came from. A memory generated from another repository is a likely false positive because the store is one directory per Codex home, not per repository; ask which project the fact came from.
Hooks are a third path, and a silent one. In the CLI, /hooks lists configured hooks and marks new or changed ones for review. Codex skips a non-managed hook until you trust it. A capture hook that is waiting for review is a zero with no error in the transcript, the saved conversation record. In the CLI, /status shows the session's model, approval policy and token use.
Gemini CLI: `/memory show` is the load check#
Run gemini --version first; this section describes v0.65.0 (20 October 2026). Gemini CLI's /memory is a viewer, not a store. The question "did the agent capture the fact?" is a file question, and "did this session load it?" has a direct answer: /memory show prints the text that loaded at startup, under the labels Global, Private Project Memory, Extension and Project. If a startup context file's line is not there, it was not loaded at startup. A subdirectory file loaded just-in-time appears in the tool output, not in /memory show; check /memory list and the tool output. /memory list prints the paths that loaded, and /memory reload re-reads them after an edit. The footer shows how many context files loaded; the number is a count, not a list of what is in them.
Capture is a write to one of four places. A team rule goes to GEMINI.md in the repository root or a subdirectory; a private note goes to the private project folder, indexed by ~/.gemini/tmp/<project>/memory/MEMORY.md; a personal preference goes to ~/.gemini/GEMINI.md. The system prompt tells the model to pick one tier per fact and to ask when it is unsure. Check the tier you expected:
git status --short
git diff -- GEMINI.md
find ~/.gemini/tmp -maxdepth 3 -name MEMORY.md -printThe private folder has a second trap. MEMORY.md is the index, and only the index is loaded. A longer note in the same folder is a file the agent has to open on purpose. A fact can be captured (the sibling file exists) and not loaded (the index has no pointer, or the agent never opens it). /memory show proves the index; it does not prove the note was read.
Did the private index load?#
/memory list shows whether MEMORY.md is in the loaded set. /memory show shows its text. A sibling note appears in neither; if the fact lives there, open it yourself (cat ~/.gemini/tmp/<project>/memory/<note>.md) and search it; if the agent quotes it, check the quote against the file. If /memory show has no Private Project Memory block, the project has no private index yet.
Auto Memory is a capture path, not a load path. It is off by default; when experimental.autoMemory is on, it writes .patch files under the project memory folder's .inbox and lists them in /memory inbox. A candidate you have not applied is not memory yet. Applying one updates the file and reloads memory for the current session, but a new session is still the honest check.
The old /memory add command and save_memory tool are gone; the agent writes files directly now.
The full command and file map is in what the memory command shows in Gemini CLI.
Qwen Code: the panel is not the load check#
Qwen Code's /memory opens a panel, not a text dump, so it does not show what loaded. The panel details here are from 0.26.2, the npm latest on 27 October 2026. In the CLI the panel shows the auto-memory and cleanup switches and two entries, User memory and Project memory, which open ~/.qwen/memories/ and ~/.qwen/projects/<project>/memory/ when managed auto-memory is on (the default); with memory.enableManagedAutoMemory: false, both entries open the user and project QWEN.md files instead (memory panel source). The panel does not print your loaded QWEN.md files. The /memory show line in older tutorials is not a subcommand in current builds; they answer it with Usage: /memory migrate-team (command source).
/context detail is the load check. Its Memory files section lists one row per loaded context file with a token count, and a separate auto memory row when the managed memory layer is present. A file missing there did not load. The footer's context indicator is a percentage of the declared window, not a file count (formatter); use /context detail for the file list.
For capture, look at both private memory folders, plus the team folder when team memory is on:
ls ~/.qwen/projects/<project>/memory/
wc -l ~/.qwen/projects/<project>/memory/MEMORY.md
ls ~/.qwen/memories/
ls .qwen/team-memory/ # when team memory is enabledMEMORY.md is the index; its generated body and the part loaded into prompts are capped at 200 lines and 25,000 UTF-16 code units, and an entry that does not fit is skipped whole. The topic files it links load only when Qwen opens them. /remember <text> does not append to a file itself: it submits a prompt, and the model chooses the user or project tier, or the team tier when team memory is enabled, so check both private folders, and .qwen/team-memory/ if team memory is on, after it runs.
Status, 27 October 2026: in the Web Shell the panel does not list auto-memory entries at all (#13396, open, 4 October 2026); read the folders above instead. On a memory file with CRLF line endings, /forget can delete the whole file instead of one entry (#14642, open, 19 October 2026), so check the file after a forget.
Then the new-session test is the same as everywhere else: ask for the fact and the path it came from, and confirm that path in /context detail or in the memory folder.
GitHub Copilot CLI: the store is not on your disk#
Copilot Memory is a GitHub-side store in public preview, so the first check is not a folder. There is no memory file under ~/.copilot to list; the facts live on GitHub. Run copilot --version first; /memory arrived in 1.0.49; /memory show gained the documentation links in 1.0.51, and the current release is 1.0.104 (27 October 2026).
The CLI's /memory show command reports the status and documentation links. It is a switch and a pointer, not an inventory. The facts are in GitHub:
- Repository facts: the repository's Settings → Copilot → Memory. A repository owner can review and delete them.
- Your preferences: your personal Copilot settings → Copilot → Memory. Each user can see and delete their own.
For the three layers:
| Layer | Check | What it proves |
|---|---|---|
| Capture | The fact appears on one of those GitHub pages | The model called store_memory and the write succeeded |
| Load | A proxy or prompt log of a new session contains the reported repository_memories block for owner/repo; the CLI has no command that prints it, and user preferences have no documented block name | The service injected it (reported, not documented) |
| Use | The answer, command or diff matches the fact | The model acted on it |
Capture fails more often than it looks. Only the root agent can call store_memory; a subagent's write fails by design, because subagents get read_memories but not the write tool (command reference). In prompt mode (copilot -p) memory is off unless you pass --enable-memory. A report says a repository whose origin is not on github.com fails every write (#3060, open, 30 April 2026); reads of old memories can still work. A managed-policy report ties a session-wide store_memory failure to the settings flap (#4602, open, 25 August 2026).
The load check is the weak one. The CLI has no documented command that prints the injected memory block. A report describes it as a repository_memories block in the system prompt (#1443, open, 13 February 2026). To prove it yourself, capture the request with a proxy or read the session log if your build records the prompt. Do not ask the model whether it remembers; a model describes its context from the conversation, not from a transcript of the prompt.
A captured fact can also stop being used without an error. Repository facts carry citations checked against the current branch, and only validated facts are used. A fact that goes unused for 28 days is deleted. So "it was stored" is not "this session loaded it", and neither is "it was loaded once".
In long sessions, the CLI refreshes memory context after 30 minutes (changelog 1.0.71), so a fact stored mid-session is not a same-turn check. Start a new session, or wait for the refresh, before you conclude the write failed.
OpenCode#
OpenCode has no memory store to inspect. The check is the instruction file. Both lines load instructions; V2 loads AGENTS.md only, and V1 falls back to CLAUDE.md when no AGENTS.md is on the path. There is no /memory or opencode memory command.
The direct V2 check is the session's instruction record: the list of instruction files the session stored. opencode session list gives the ID; the OpenCode AGENTS.md guide has the SQL that prints the recorded paths. opencode debug config is a config check, not a load check: in V2 it shows the instructions entry (V1 prints the resolved config), but it does not show whether the file was read. The instruction record or the Instructions from: line is the load check. If neither shows the file, it did not load.
Do not ask the model whether it read the file. A model describes its context from the conversation, not from a transcript of the prompt. The Instructions from: <path> prefix in the rendered prompt is the evidence; a logging proxy or plugin can capture it.
Status, 27 October 2026: V2's instructions array was inert from 2.0.16 through at least 2.0.28; the issue closed as completed on 14 October 2026 (#51341). On an earlier 2.0.x, a rule in AGENTS.md worked while the same rule in instructions did not. Update, or keep the rule in AGENTS.md.
If the check fails: the wrong filename (V2 does not read CLAUDE.md), the wrong config directory (opencode debug paths), a workspace outside the repository, or a nested file the agent never read. The AGENTS page lists them.
Cursor: the editor has no store, so check the rule#
Run Cursor → About Cursor in the editor, or agent --version in the CLI. Cursor 3.27 was the newest editor build on 27 October 2026.
Cursor's editor has no memory store in Customize to inspect; old Memories data can still be injected. The old Memories feature was retired in Cursor 2.1 (staff, 7 January 2026, #148254). What carries a standing instruction is a root AGENTS.md or CLAUDE.md, a project rule in .cursor/rules, or User Rules in Customize → Rules. Chat history is a transcript; a new chat does not inherit it.
The inventory is Customize → Rules in the editor. It lists project, user, team and plugin rules and the type Cursor thinks each one is. A missing rule was not discovered; a rule with the wrong badge may be delivered as a different type. Neither proves the model received it. For that, run a canary: put a unique line in an alwaysApply: true project rule and start a new Agent chat; if the marker appears only after you @-mention it, the rule is requestable rather than always-applied. The CLI has no documented rules panel; there, treat the files as the inventory and run the same test. The Cursor rules guide covers the type badge, the canary and the loaded-but-not-followed ladder in full.
For AGENTS.md, the check depends on the file's place. A root file is treated as always applied; @AGENTS.md in a new chat attaches the file to that message (prompting docs), and if the rule is followed only then, the automatic path is the problem. In the editor, a nested file attaches when the agent reads a file in that folder; in the CLI since v2026.10.22, an edit or create also attaches nested AGENTS.md (CLI changelog). Ask it to read one before you conclude it is missing. After summarization a nested file can drop out and not come back; the compaction guide covers that. The Cursor AGENTS.md guide has the full check.
Two things can outlive the feature. Stored Memories data can still be injected without a UI, and old account rules can still apply. If instructions you cannot find keep appearing, open a new window with no folder and look at Customize → Rules; staff say this is most likely on accounts that used the old Memories feature, where the rules can be injected while the panel leaves them out (#174724, 26 October 2026). If they appear there, delete them.
Then the new-session test is the same as everywhere else: put a fact in the rule that nothing else knows, start a new chat, and ask for the fact and where it came from. Compare the answer with the rule text. The answer tests use. Customize → Rules and the canary test delivery.
ai-memory#
Check three things, in this order.
- The process.
curl -sS http://127.0.0.1:49374/healthzon the default port, or your port, andai-memory status. A healthy process is not a captured session. - Coverage.
ai-memory doctorcompares each harness's local session store with what the server captured. In our test it printed a line per harness, such asclaude-code 0 local (0 recent) -> 1 capturedandcodex 0 local (0 recent) -> 6 captured.install-hooks --check-capturechecks the wiring. - One real event. Send a prompt, then call
memory_read_session_observationswith the session id. The observation should carry the prompt and the tool body. After the session ends,memory_recentshould list the session page.
One trap from our test of v3.2.5: the default SessionStart packet was empty when there was no pending handoff and no [briefing] opt-in, so a 200 from the server did not mean the agent was told anything. Check /healthz and the process, not the success message.
Hooks are fire-and-forget and spooled. A hook can exit 0 and still deliver nothing. doctor, the spool and the server counts are the checks that catch it.
What proves capture is a page with the expected path and body. What proves load is a session-start packet that quotes it. memory_briefing lists recent pages; memory_query finds the body; memory_read_page returns it. Without a handoff or a brief, the agent has to call one of them.
What a false green looks like#
| The green thing | What it proves | What it does not prove |
|---|---|---|
The server answers /healthz | The process runs | A hook captured anything |
| A memory file exists | Something wrote it | It loads in the next session |
The private Gemini CLI MEMORY.md exists | Capture | That its lines loaded in this session; a sibling note with no pointer did not |
Qwen Code's /memory shows auto-memory on | The switch is on | That an entry exists, or that this session loaded one |
| Customize → Rules lists a Cursor rule | It was discovered, and has a badge | It was included in this chat, or followed |
| "Saved 2 memories" | Capture | The index points to them, or the model uses them |
| The agent says "I remember" | Nothing | It read the source |
/context lists the file | Load | The model follows it |
/memory show says enabled | The Copilot Memory switch is on | A fact exists, or this session loaded one |
| A fact is on the GitHub Memory page | Capture | The service injected it into this session |
| The agent read the page | Load | The page is right, or the agent acts on it |
Only the last layer is use. A model can read the right line and still take the wrong action. For use, check the diff, the command or the answer against the source. That is also why "the agent said it remembered" is not evidence.
If the check fails#
| What you see | Likely layer | Next step |
|---|---|---|
| Nothing was written | Capture | Claude Code: open /memory; Codex: check /hooks in the CLI and /memories in the TUI or desktop app; ai-memory: doctor and the spool. |
| The file exists but the session does not see it | Load | Claude Code: /context and the auto memory index; Codex: debug prompt-input, the 32 KiB project budget, and the /memories switches in the TUI or desktop app; ai-memory: the startup packet or the tool call. |
| The session sees it but does wrong | Use | Look for a conflicting instruction, a correction below the fold, or a model that ignored the line. A hook is enforcement; a page is context. |
| The session sees the old version | Load, wrong source | Correct the source and put the correction first. The correction guide has the per-tool steps. |
| Copilot Memory has nothing to capture | Capture | /memory show for the switch, then the GitHub Memory pages. In prompt mode, add --enable-memory. |
| OpenCode has nothing to capture | Capture | There is no memory store; put the fact in AGENTS.md or instructions. |
| OpenCode has the file but the session does not see it | Load | debug config for an instructions entry; V2 instruction record or a prompt log for the file. |
| Gemini CLI has nothing to capture | Capture | Check the expected tier: git diff -- GEMINI.md, ~/.gemini/GEMINI.md, and the private MEMORY.md. /memory add no longer exists; ask the agent to save the fact again. |
Gemini CLI has the file but /memory show does not | Load | For a startup file, /memory list for the path, /memory reload, then /memory show again. For a just-in-time file, re-run the tool that touched its directory and read the appended --- Newly Discovered Project Context --- block; /memory show will not print it. |
| Gemini CLI loaded the index but not the detail | Load | The detail is probably in a sibling note with no pointer. Add a line to MEMORY.md, open the note, and check the pointer and the note text yourself. |
| Qwen Code has nothing to capture | Capture | Open /memory and check both switches, then ls ~/.qwen/projects/<project>/memory/ and ~/.qwen/memories/. /remember chooses the tier, so check both private folders, and .qwen/team-memory/ if team memory is enabled. |
| Qwen Code has the file but the session does not see it | Load | /context detail under Memory files. A nested QWEN.md below the working directory is not discovered, and context.fileName may have replaced the default names. |
| Cursor has nothing to capture | Capture | The editor and CLI have no memory store; put the fact in AGENTS.md or User Rules. |
| Cursor lists the rule but the chat ignores it | Load or use | Check the rule's badge, then run the canary. After a summary, re-read the nested file or reattach the skill. |
The shortest reliable check#
Write one fact that only the store knows. Start a new session. Ask for the fact and its source. Change the source. Ask again. If the answer tracks the source, the loop is live. If it does not, you have found the layer that is broken, and no amount of asking the agent to "remember" will fix it.
This guide is part of Persistent memory for Claude Code and Codex.