The issue, as reported
It is one of the most widely reported complaints about coding agents: you write the house rules into CLAUDE.md (or AGENTS.md), the agent follows them for a while, and then it doesn't. Well over a hundred developers have described it across dozens of threads on the Claude Code, Codex and OpenCode trackers, some open for more than a year.
The reports fall into a few patterns:
What developers report
AGENTS.md silently not read in some modes, versions or setups.People have started calling the file "advisory". That is closer to the truth than it sounds.
Why it happens
There are three different failures here, and they need different fixes.
- The rule was never in the context. Claude Code loads
CLAUDE.mdfrom your working folder and every folder above it at launch, but files in subfolders load only when Claude reads a file in that folder, and rules in.claude/rules/with apaths:line only when a matching file is read (memory docs). Widely reported: when the agent reads through shell commands instead of its Read tool, those files never load.AGENTS.mdis read only when there is noCLAUDE.md,.claude/CLAUDE.mdorCLAUDE.local.mdin your folder or above it, so adding a personalCLAUDE.local.mdquietly switches it off. Codex stops adding instruction files once they reach 32 KiB by default (Codex docs); OpenCode uses the first file it finds and readsCLAUDE.mdonly if there is noAGENTS.md(OpenCode docs). - The rule was loaded, then compacted away. After compaction Claude Code re-reads the project-root
CLAUDE.mdand unscoped rules from disk. Nested files and path-scoped rules were part of the message history, so they are summarised away with everything else until a matching file is read again (context window docs). A rule you gave only in chat is gone. - The rule was there, and the model weighed it against everything else. The docs are plain about this: Claude treats
CLAUDE.mdas "context, not enforced configuration". It arrives as a user message after the system prompt, and there is "no guarantee of strict compliance, especially for vague or conflicting instructions". Files over about 200 lines "consume more context and reduce adherence", and if two instructions contradict each other, Claude "may pick one arbitrarily".

How to fix it today
Steps are for Claude Code unless noted.
- Check what actually loaded
Run
/contextand look under Memory files. If a file isn't listed, Claude can't see it./memorylists every location and opens the files. In Codex, runcodex --ask-for-approval never "Summarize the current instructions.". If Claude Code skipsAGENTS.md, check you're on v2.1.281 or later and have noCLAUDE.mdorCLAUDE.local.mdon the path, or set Project instructions in/configtoclaude-md-and-agents-md. - Cut the file to what every session needs
Target under 200 lines. Keep build commands, conventions and "always do X" rules, written so they can be checked: "Run
npm testbefore committing", not "test your changes". Remove contradictions. Imports with@pathtidy a long file but don't shrink it, because imported files load at launch too. From v2.1.283,/doctor prompt-auditlists outdated and conflicting instructions and proposes edits. - Move part-specific rules into path-scoped files
Rules that only matter for one area go in
.claude/rules/with apaths:line, so they load when Claude reads a matching file. The trade-off: they don't survive a compact until a matching file is read again. Anything that must hold all session belongs in the rootCLAUDE.md, withoutpaths:.--- paths: - "src/api/**/*.ts" --- - Every endpoint validates its input with the shared schema. - Turn every "never" into a hook
For rules that must hold regardless of what the model decides, the docs point to hooks. A
PreToolUsehook that exits with code 2 blocks the call, and what it writes to stderr is passed to Claude as the reason. Save as.claude/hooks/no-push.shand make it executable (chmod +x); it needsjq:#!/bin/bash COMMAND=$(jq -r '.tool_input.command') if echo "$COMMAND" | grep -Eq 'git push.*(main|master)'; then echo "Blocked: never push to main. Open a pull request." >&2 exit 2 fi exit 0 - Register the hook
Add it to
.claude/settings.jsonin the project, matching the Bash tool (hooks guide):{ "hooks": { "PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/no-push.sh" }] }] } } - Re-state the essentials after every compact
A
SessionStarthook with thecompactmatcher runs after compaction and its output is added to the context. Use it for the two or three rules that keep slipping; keep.claude/keep.mdshort.{ "hooks": { "SessionStart": [{ "matcher": "compact", "hooks": [{ "type": "command", "command": "cat \"$CLAUDE_PROJECT_DIR\"/.claude/keep.md" }] }] } } - Use one file for every tool
Put the shared rules in
AGENTS.md, an open format that Codex and OpenCode read. If you also keep aCLAUDE.md, start it with an import so Claude Code reads both in every session, with Claude-only rules underneath:@AGENTS.md ## Claude Code only Use plan mode for changes under src/billing/.
What the fix doesn't cover
The example above stops git push origin main, but not a plain git push while you're on main, or a push done through a script. Hooks are exact, and most rules ("keep functions small", "don't add dependencies without asking") can't be written as a pattern at all. Those stay advisory, and a shorter, sharper file is the best you can do.
The other gap is what the file gets used for. Rules files bloat because they become the only place a project's history can live: why the API is versioned that way, which approach was tried and dropped, what was decided last Tuesday. Every such line loads in every session and dilutes the rules that matter, and when a decision changes, the old line often stays.
How Axiom Lift helps (partly)
Axiom Lift doesn't make a model follow rules, and nothing here replaces hooks or a good CLAUDE.md. What it does is take the project's history off the rules file's hands, so the file can go back to being short.
A small helper on your computer reads the conversations Claude Code, Codex and OpenCode already save, and picks out the requirements, decisions and corrections as you work. The next session asks Axiom over MCP and gets back the few lines that are true now on that subject, not the whole history.
The free fix
CLAUDE.mdorAGENTS.mdholds the rules, and often the project's history too- Every line loads into every session, relevant or not
- When a decision changes, someone has to find and edit the old line
- Hooks enforce the few rules that can be written as a pattern
With Axiom
- The rules file keeps the rules; decisions and their reasons live in Axiom
- Before each prompt, Axiom adds a few lines about what's already decided on that subject
- Change your mind and the old decision is struck through, not erased, linked to when it was said
- On Pro, it notices when a later conversation changed an earlier decision

What it doesn't do here:
- It doesn't enforce, block or check anything. A rule the model ignores is still ignored.
- It doesn't read or edit your
CLAUDE.mdorAGENTS.md. - It covers Claude Code, Codex and OpenCode only, not browser chats.
It installs with one command in a desktop terminal, on Mac, with Linux and Windows in beta (it needs Python 3), and shows you what it found before anything is sent. The free plan covers one computer; Pro is £12.99 a month.
One command in the terminal where you use Claude Code, Codex or OpenCode. Free, no card.
Try it free →Claude, Codex and OpenCode are trademarks of their owners; Axiom works alongside them and is not affiliated.
