TL;DR
Asking an agent whether it read CLAUDE.md or AGENTS.md is the weakest check available, because the answer is the model describing itself. Use what each client records instead: Claude Code's /context and InstructionsLoaded hook, Codex's session log, Copilot's References list; Cursor currently has no reliable per-rule indicator. If edits must wait for loading, put a pre-edit hook in front of the editing tools, test that it fails closed, and write down the edit paths it cannot see.
The only evidence was the agent's own account
In May 2026 a developer on the Cursor forum set up a rule scoped to one folder, asked the agent to make an edit inside that folder, and watched it proceed without any sign of the rule. They asked how they could know the agent actually looked at it. A Cursor staff reply confirmed that folder-scoped rules were being picked up unreliably and that the interface had no reliable indicator at the time.
On Stack Overflow, someone who had added an AGENTS.md to steer GitHub Copilot asked why the agent sometimes reported that no instructions were found and offered to create some, even though the file was there. They asked whether the agent needed a particular format or location to detect it.
One agent gave no sign of a rule it may or may not have used; the other said it had no instructions when a file existed. Neither offered anything to check except its own word.
Why the agent's account is not evidence
A missing file-read call does not mean the file was not loaded. Instruction files are usually injected by the client rather than opened with a tool: Claude Code's documentation describes CLAUDE.md content as delivered as a user message after the system prompt, so no Read call appears in the transcript. The reverse also holds. An agent's statement that it read your rules is generated like any other output, and a model can summarize instructions it half-remembers or deny having ones it was given.
That leaves three separate questions. Did the file reach the model's context? Is there a record of that, made by something other than the model? Is an edit prevented from starting until that record exists? Each tool answers the first two differently, and the third needs a hook.
What each tool can actually show you
From each vendor's documentation as of 30 September 2026, ordered roughly from weakest to strongest evidence:
| Evidence | Claude Code | Codex | GitHub Copilot | Cursor |
|---|---|---|---|---|
| Ask the model | Possible, but a self-report | The docs suggest asking for a summary; still a self-report | Possible, but a self-report | Possible, but a self-report |
| Listing in the interface | /context shows loaded memory files; /memory lists an AGENTS.md it read directly from v2.1.280 | /status shows session settings, not instruction files | The References list on a response includes .github/copilot-instructions.md when it was used | The context breakdown shows a total for rules, not which ones |
| Record made by the client | InstructionsLoaded hook fires for each CLAUDE.md or rules file with its path and load reason | TUI log via -c log_dir=./.codex-log, or the session file | VS Code's agent debug logs show loading details and errors | No documented per-rule record |
| Exact model input | Not documented | codex debug prompt-input, marked experimental, shows the prompt input as JSON | Not documented in the pages checked | Not documented |
Sources: Claude Code memory and hooks documentation, Codex's AGENTS.md guide and command reference, GitHub's repository instructions page, VS Code's custom instructions page, and Cursor's prompting documentation.
Claude Code's InstructionsLoaded hook is the most useful record of the group because it covers files that load later. Its input includes the file path, the memory type and a load reason such as session start, nested traversal, a path-glob match, an include or a reload after compaction, plus the file that triggered a lazy load.
Where a tool gives you nothing better, a canary is a practical community technique: add an instruction that makes every reply begin with a fixed marker, then run the same prompt with and without the file. It shows that the file reached the model, not that later edits follow its other rules.

Make the edit wait for the record
A listing tells you afterwards. To make an edit wait, you need a hook that runs before the editing tool and refuses the call until a load record exists. In Claude Code that is a PreToolUse hook returning a deny decision or exiting with code 2; Codex and Cursor have equivalent pre-tool hooks.
Paqad ships such a gate. Its entry check refuses a covered edit until the agent has loaded the framework's entry file and written a small per-session record. A second record, rules-loaded.json, lists the project rules that apply to the changed files, and when the project has compiled rules, a covered source edit on the wired Claude Code and Codex paths is refused until it exists too. The first gate's pinned script at commit 29548baf was run against a scratch project with hand-written hook payloads.
The last row is the one to remember. Claude Code treats exit code 1 as a non-blocking error, so a host running that broken copy would have let the edit through. And like any such record, the load record acknowledges that loading happened; it does not show what the model understood.

Know which edit paths the check does not see
Every pre-edit gate covers the tools its matcher names and nothing else. Paqad registers its Claude Code gate for Edit, Write and NotebookEdit and its Codex gate for apply_patch, so a file changed with a shell command bypasses both, though its end-of-turn check still sees the result. Claude Code's hook documentation adds that PreToolUse does not fire for files pulled in with @ in the prompt, and Codex's hooks page describes tool hooks as a useful guardrail rather than a complete enforcement boundary.
Failure modes matter as much as coverage:
| Tool | When the hook errors or times out |
|---|---|
| Claude Code | Exit 1, a timeout or a missing script lets the action proceed |
| Cursor | Hooks fail open unless the script is marked failClosed |
| Codex | The tool call continues when a hook returns a decision it does not support |
| GitHub Copilot | Command hooks fail closed on errors but open on timeouts |
Test the gate once with an edit that should be blocked, and again after every upgrade. For the paths it cannot see, check the result instead of the action: review the diff, run the project's checks in CI, and in Claude Code consider permission rules, since its Edit deny rules also cover the shell file commands it recognizes. Write the uncovered paths down, so nobody reads a green pre-edit gate as proof that every edit waited for the instructions. Paqad can produce these load records and the gate on your own repository; its documentation lists the hosts it wires for the pre-edit check.
Loading is only half of it: for a rule that loaded and was still broken, the article on why a coding agent keeps ignoring the project rules covers the compliance side. A load record also belongs to one session; see what to save so a new AI coding session can continue accurately for what has to be recreated when work resumes.
Frequently Asked Questions
How can I check that an agent loaded the project instructions before editing?
Read the client's record for the current session, then make the edit depend on it. A listing checked once at the start of a session can go stale after compaction or a change to the instruction files, which is why Paqad's gate deletes its record when CLAUDE.md changes.
Does the absence of a visible file-read call mean the instructions were not loaded?
No. Clients inject instruction files directly, so a missing Read call is expected even when loading worked. The opposite signal is just as weak: a Read call on CLAUDE.md shows the agent opened the file as ordinary content; on its own it is not the client's load record.
What observable record distinguishes a loaded file from an agent merely saying it read it?
One written by the client or a hook at the moment of loading, with the file path and ideally the reason. The strongest form is the exact model input, which Codex exposes experimentally. A canary marker sits in between: it comes from model output, so it shows the file reached the model without being a record of loading.
How can the workflow stop a supported edit when the required loading record is missing?
With a pre-edit hook that denies the editing tools until the record exists. Three details decide whether it works: it must fail closed where the tool allows, it must invalidate the record when instruction files change, and it must be tested with an edit that should be refused.
Which alternative edit paths bypass that check, and how will we detect or restrict them?
Shell writes, @ file inclusion in Claude Code, hosted tools outside the hook system, editors without the hook, and a hook that crashes. Keep the list in the repository next to the hook configuration, so a reviewer can see what a green gate does not cover, and back each gap with CI or a permission rule.
