CLAUDE.md hard rules and persistent memory instructions consistently ignored — violations escalate with each session despite repeated explicit reinforcement
Summary
Instructions written as explicit hard rules in CLAUDE.md and project memory (MEMORY.md) are loaded into context every session and are consistently not followed. Every time a violation occurs, the rule is re-stated, strengthened, and re-documented. The next session violates it again. The behavior is getting measurably worse with each iteration, not better. Four consecutive sessions of documented violations with full token-level evidence.
Environment
- Claude Code (VS Code extension)
- Model: claude-sonnet-4-6
- OS: Windows 11
- Project: Pine Script trading system (active multi-session build, 33 sessions logged)
What the instructions say
These rules exist verbatim in loaded context every session. They are not ambiguous. They are not suggestions.
Token ledger is MANDATORY at CHECK OUT. Non-negotiable. Blank = unacceptable. If token data not captured live → recover from jsonl at ~/.claude/projects/[session-id]/
pine-quality-reviewer KILLED — S26 proved it adds cost and catches nothing.
No narration between actions. State → act → report result.
Session classification mandatory before spawning.
Skills and agents load ON DEMAND only — never pre-load.
Scope gate: count before spawning, excess queued, no mid-session expansion.
The token ledger rule was added after S29 was declared a failure. It was violated in S30, S31, and S32 — the three sessions immediately following. The "killed agent" rule was added after S26. It was violated in S32. Every rule in this system was added in direct response to a specific documented failure. Every rule has been violated again after being added.
Violation history — escalating pattern
Token ledger — 4 consecutive violations
| Session | Rule | Stated Reason | Reality |
|---------|------|---------------|---------|
| S29 | Mandatory. Recover from jsonl if missed. | "Trivial session — not captured" | 70,344 output tokens. Not trivial. jsonl existed. Recovery not attempted. |
| S30 | Mandatory. Recover from jsonl if missed. | "Compacted mid-run. Not recovered this session." | jsonl existed. Recovery not attempted. |
| S31 | Mandatory. Recover from jsonl if missed. | "Ran out of context. Not captured." | jsonl existed. Recovery not attempted. |
| S32 | Mandatory. Recover from jsonl if missed. | Partial table — subagent numbers only. Orchestrator missing. | Numbers in log don't match jsonl. Orchestrator tokens (144,725) absent entirely. |
The rule explicitly states the recovery path. The jsonl files were present in every case. The rule was not followed in any of the four sessions. After each violation the rule was re-confirmed as non-negotiable. The next session violated it anyway.
Killed review agent — resurrected in the session it was killed
The pine-quality-reviewer was explicitly terminated after Session 26 with this documented entry:
pine-quality-reviewer KILLED — S26 proved it adds cost and catches nothing.
In Session 32, the /simplify skill was invoked post-delivery, spawning 6 Explore agents performing identical review functions — reuse review, quality review, efficiency review. All 6 returned false positives or noise. Zero actionable output. Cost: 17,809 output tokens. The kill rule was in loaded context. It was ignored.
The session log reported only 3 agents and approximate figures (~121k tokens). Actual jsonl showed 6 agents and 17,809 tokens — the log itself was inaccurate.
No-narration rule — structural failure
The rule "no narration between actions" was added to the global CLAUDE.md after S29 to reduce orchestrator verbosity and context fill rate. In the two Pine sessions after (S30, S31+32):
- S30: context compaction fired 3 times
- S31+32: context compaction fired 6 times
Context compaction fires when the context window fills. If the no-narration rule were followed, context would fill significantly slower. 6 compaction events in one session is direct evidence the rule had no measurable effect.
Measurable cost of rule violations
Token breakdown across S29–S32 (recovered from jsonl, not from session logs which were incomplete):
| Category | Tokens | % | Est. Cost |
|----------|--------|---|-----------|
| Productive work (pine-coder + verifier) | 35,390 | 3.2% | ~$0.53 |
| Orchestrator output | 318,295 | 29.1% | ~$4.77 |
| Explore waste (/simplify) | 17,809 | 1.6% | ~$0.27 |
| Compaction overhead | 720,742 | 66.0% | ~$10.81 |
| Total | 1,092,236 | | ~$79.63 |
3.2% of all tokens produced actual work. 66% is context compaction — the system compressing its own over-filled context despite an explicit rule against the verbosity that causes it.
The session immediately before this analysis (S32) was the most expensive single session recorded. The workflow update session (S29, ~$15.61) was supposed to reduce costs. S30 (~$26.82) cost more. S31+32 (~$37.20) cost more again. The cost trajectory is worsening, not improving, despite repeated rule reinforcement.
What was tried
Every approach available to a non-technical user was attempted:
- Rules written in CLAUDE.md — ignored
- Rules escalated to "HARD LAW" and "NEVER VIOLATE" headers — ignored
- Rules added to persistent MEMORY.md — ignored
- Rules re-stated and strengthened after each violation — ignored, and the next session is worse
- Dedicated workflow session (S29) to rebuild the system — the three sessions following S29 were the worst on record
- Hard hook enforcement (PreToolUse blocking .pine file edits directly) — this works. Zero violations since added.
The only mechanism that actually enforces anything is the hook. Everything enforced by text alone fails, and fails repeatedly. Constant repetition and escalating rule language does not help — based on this dataset, it may make no difference at all.
Core issue
The model reads the rules. It can quote them back. It then violates them. The gap between "rules in context" and "rules followed in behavior" appears to be a fundamental issue, not a configuration problem. A non-technical user has exhausted every available lever.
Specific requests
- Is instruction-following from CLAUDE.md and memory a known degradation issue? Is there a tracking item for this?
- Is there a supported enforcement mechanism beyond text and tool-level hooks? Hooks cover binary file-level actions. They cannot enforce behavioral patterns like session scope discipline, no-narration, or agent-type restrictions.
- Are there plans for stronger primitives? Examples: session-scoped agent type blocking, mandatory structured checkout outputs, skill invocation restrictions.
- Is repeated rule reinforcement counter-productive? The pattern here suggests it may be — each violation triggers a stronger rule statement, and the next violation happens anyway. Is there guidance on how to structure project memory so it actually affects model behavior?
19 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
how do i get a resloution?
Can you try an injection step that injects the hard rules into the chat as a first system message eveytime there is a compaction. Also a heartbeat that checks whether the hard rules are at the top of the context. These are things I have added that helped me. Also can have a trigger inject:hard_rules which forces the model to read the hard_rules.md
Kind of did try it. but i made claude do it, instead of doing it myself. it still would not listen.
Tt would work of one session will break for the next 3.
Plus, coding it far from where I am. I do not have much choice to rely on it more than i would like it.
I did use logical reasoning to get this farf to find it.
I use thinking mode with sonnet usually. Can't even use Opus i wold not be able to do anything till i get 97 at the speed which it take to consume tokens and resets.
I think it’s related to Claude giving poor or illogical responses since this week.
https://github.com/anthropics/claude-code/issues/33908
I've been running Claude Code autonomously for 108+ hours across hundreds of sessions, and I hit every single one of these problems. Here's what I learned:
CLAUDE.md rules are guidance, not enforcement
This is the core issue. CLAUDE.md instructions are loaded into context as text — they're suggestions to the model, not mechanical constraints. The model can (and will) violate them, especially as context grows and earlier instructions get diluted.
Your own finding is exactly right: hooks with
exit 2are the only mechanism that actually enforces anything.What works in practice
1. Convert critical rules into PreToolUse hooks
Any rule that MUST be followed needs a hook, not a CLAUDE.md line. Example — blocking a killed agent from being spawned:
exit 2= hard block.exit 1= warning only (Claude continues). This distinction is the #1 gotcha — I've seen multiple issues about it.2. Use PostToolUse hooks for audit logging
For things like your token ledger — don't rely on Claude remembering to do it. Have a PostToolUse hook that automatically captures the data:
3. Accept the limitation for soft rules
"No narration between actions" cannot be mechanically enforced — there's no hook event for "Claude is about to output text." These soft behavioral rules will always be hit-or-miss. Keep them in CLAUDE.md but don't expect 100% compliance.
4. Scope gate via hook
Your "count before spawning" rule can be enforced:
The mental model
Think of it as two layers:
Anything that's "non-negotiable" belongs in hooks, not CLAUDE.md. Anything that's "preferred behavior" stays in CLAUDE.md and you accept imperfect compliance.
Not a coder but i did somehow have applied Hooks. still testing them only a couplec of sessions in.
Implimented that after this blunder.
none of them work. claude still ignores them all.
The model compliance issue is real and I doubt tooling alone can fix it. But one thing that kept tripping me up: I couldn't tell whether the memory was actually loaded correctly. The files sit under hashed directory names, no quick way to check.
I built a plugin with a web UI that lets you browse all memory containers across projects: claude-memory-manager. Also logs every write op, so when a memory "disappears" you can check if it was overwritten or just ignored.
Won't fix the root cause, but at least you stop wondering "is the file even there?"
Please refer to issue #34358. There may be an approach there that you need.
Claude willingly admits it does not apply its rules, and it says it can create a feedback cycle, and yet these feedback cycles do not work.
The bug is "Claude lies, because feedback does nothing".
Friends don't lie. Claude, you need to actually close the feedback loop. This needs to be a contract that claude reviews and enforces.
See also
https://github.com/anthropics/claude-code/issues/38887
Over the past few days, I’ve noticed a substantial drop in Claude’s ability to follow instructions and complete structured tasks reliably.
Specifically:
This is a noticeable regression compared to prior behavior and is impacting real-world usability.
If there was a recent update, it appears to have negatively affected instruction-following and task completion. I’d appreciate any clarification on what changed and whether improvements are planned.
Hey @le-fphoool-muze and everyone in this thread — your analysis is the cleanest articulation of this problem I've seen on GitHub. The pattern (rules in context but consistently not in behavior) is exactly why I built SpecLock.
Disclosure: I'm the creator. Built it because I hit this exact wall and got tired of writing yet another hook by hand.
@yurukusa nailed it above: "hooks with
exit 2are the only mechanism that actually enforces anything." SpecLock is essentially that insight, automated and with semantic detection so the hook understands intent — not just keywords.What it does:
This reads your existing CLAUDE.md (or .cursorrules / AGENTS.md), extracts the rules, and installs a pre-commit hook that runs a semantic engine on the diff and commit message. The engine catches patterns that text-only rules and keyword regex both miss:
For your specific case: the file/diff-level rules will catch the killed-agent and token-ledger violations cleanly (anything that touches a tracked file or matches the lock semantics on the commit message). The "no narration" rule is genuinely a soft behavioral constraint that no hook can enforce — you're right that text alone doesn't fix that, and unfortunately neither does SpecLock. But for the 5 of your 6 documented patterns that are file/action-shaped, this should work.
Default mode is WARN (loud warnings, no blocks) so you can see what it catches before turning on
speclock enforce hardfor actual blocking. v5.5.7 has 1009 tests passing and is published to the Official MCP Registry. MIT licensed. Works on Windows.Happy to walk through setup if you want — for a non-technical user the install is genuinely one command and zero config. Would also be very interested in what survives the test against your S30-S33 violations corpus, since you've already done the painful work of documenting them.
Sandeep (@sgroy10)
Adding a data point: this failure occurred within the same session, shortly after the instruction was saved.
I explicitly instructed Claude (via both project-level memory and global CLAUDE.md) to reason critically and question the frame of questions rather than applying blanket rules. Within the same session, minutes after saving this instruction, Claude defaulted to a trained documentation convention ("document all parameters consistently") without questioning whether consistency actually added value in context.
When challenged, Claude correctly identified the failure: the trained pattern had stronger inertia than the explicitly stored instruction. The instruction was present in context but didn't reliably influence generation.
This suggests the problem isn't just cross-session memory degradation; the gap between "instruction in context" and "instruction followed" exists even when the instruction was just written, within the same session, on a simple behavioural rule rather than a procedural one.
(Full disclosure: the text of this comment was drafted by Claude on my instruction, and minimally modified by me, a human being.)
I think this report is pointing at a real enforcement-layer distinction.
The key detail is not that the rules were absent from context. They were present, readable, and quotable. The failure is that being present in context did not make them govern behavior once output/tool-use formation had already started.
That matches the pattern in the examples: stronger wording in CLAUDE.md / MEMORY.md improves the instruction surface, but does not reliably change the enforcement layer. The model can acknowledge the rule and still form the violating action.
The PreToolUse hook working is the important contrast. It works because it blocks the action before execution. It is not asking the model to comply after forming the intent; it prevents the disallowed action from completing at the tool boundary.
A possible mitigation to test in CLAUDE.md would be to move the highest-risk rules out of normal instruction form and into an explicit eligibility gate at the top of the file:
Example pattern:
+1 — encountered the same root pattern from a different angle today (Claude Code 2.1.78).
In my case the memory was correctly loaded and referenced at session start, but failed to be retrieved when the relevant situation arose. Memory clearly stated:
deploy-dev-on-maintrigger)ci.ymlis supplemental and does NOT gate mergeWhen a PR's GitHub Actions CI failed due to a billing limit, the model treated it as a generic "CI must pass" merge blocker and paused for confirmation. The relevant memory entry was in context the entire time. The model only connected the dots after I explicitly pushed back ("I deploy via Cloud Build all the time — are you even reading the docs?").
This is consistent with the report here: information loaded into context does not reliably influence behavior. In my (small) sample, rephrasing the same fact in action form ("when CI fails, merge anyway; Cloud Build is the gate") helped, but did not eliminate the gap.
Suggesting one additional primitive on top of those proposed above:
The core issue is that in-context instructions don't have guaranteed persistence — compaction, context limits, and model attention patterns all work against reliable rule retention. External memory with high importance scoring solves this: store critical instructions at importance 0.95+ in a persistent memory server, and have the agent recall them at the start of every context window. The instructions survive compaction, session restarts, and context resets because they live outside the model's context. MCP server approach: https://github.com/Dakera-AI/dakera-mcp — the agent recalls rules via memory tools before starting work.
I think your results line up with a broader pattern, ie. prompts are good for guidance, but they're a weak enforcement mechanism. Once something becomes a hard requirement, I've had better luck moving it into the execution layer instead of making the wording in CLAUDE.md stronger.
Hooks are one example, but more generally I think runtime guardrails are the right abstraction. That's one reason I found projects like https://github.com/FailproofAI/failproofai interesting since, they focus on enforcing behavior during execution rather than relying on the model to consistently remember text instructions.