CLAUDE.md hard rules and persistent memory instructions consistently ignored — violations escalate with each session despite repeated explicit reinforcement

Open 💬 19 comments Opened Mar 12, 2026 by le-fphoool-muze

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:

  1. Rules written in CLAUDE.md — ignored
  2. Rules escalated to "HARD LAW" and "NEVER VIOLATE" headers — ignored
  3. Rules added to persistent MEMORY.md — ignored
  4. Rules re-stated and strengthened after each violation — ignored, and the next session is worse
  5. Dedicated workflow session (S29) to rebuild the system — the three sessions following S29 were the worst on record
  6. 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

  1. Is instruction-following from CLAUDE.md and memory a known degradation issue? Is there a tracking item for this?
  2. 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.
  3. Are there plans for stronger primitives? Examples: session-scoped agent type blocking, mandatory structured checkout outputs, skill invocation restrictions.
  4. 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?

View original on GitHub ↗

19 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/32554
  2. https://github.com/anthropics/claude-code/issues/19471
  3. https://github.com/anthropics/claude-code/issues/32193

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

le-fphoool-muze · 4 months ago

how do i get a resloution?

idoneo · 4 months ago

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

le-fphoool-muze · 4 months ago

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.

le-fphoool-muze · 4 months ago

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.

mehulparmariitr · 4 months ago

I think it’s related to Claude giving poor or illogical responses since this week.
https://github.com/anthropics/claude-code/issues/33908

yurukusa · 4 months ago

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 2 are 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:

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Agent",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); AGENT_NAME=$(echo \"$INPUT\" | jq -r \".tool_input.prompt // empty\"); if echo \"$AGENT_NAME\" | grep -qi \"pine-quality-reviewer\"; then echo \"BLOCKED: pine-quality-reviewer was killed in S26\"; exit 2; fi'"
      }]
    }]
  }
}

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:

#!/bin/bash
# PostToolUse hook — auto-capture token usage
TOOL=$(cat | jq -r '.tool_name // empty')
if [ "$TOOL" = "Bash" ] || [ "$TOOL" = "Agent" ]; then
  echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) | $TOOL" >> "$HOME/.claude/token-log.jsonl"
fi
exit 0

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:

#!/bin/bash
# PreToolUse:Agent — limit concurrent agents
COUNT_FILE="/tmp/cc-agent-count-$$"
COUNT=$(cat "$COUNT_FILE" 2>/dev/null || echo 0)
COUNT=$((COUNT + 1))
echo "$COUNT" > "$COUNT_FILE"
if [ "$COUNT" -gt 3 ]; then
  echo "BLOCKED: Agent limit reached ($COUNT). Queue remaining work."
  exit 2
fi

The mental model

Think of it as two layers:

  • CLAUDE.md = guidance (like code comments — helpful, frequently ignored under pressure)
  • Hooks with exit 2 = enforcement (like CI checks — mechanically prevents violations)

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.

le-fphoool-muze · 4 months ago

Not a coder but i did somehow have applied Hooks. still testing them only a couplec of sessions in.
Implimented that after this blunder.

le-fphoool-muze · 4 months ago

none of them work. claude still ignores them all.

WhymustIhaveaname · 3 months ago

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?"

marlvinvu · 3 months ago

Please refer to issue #34358. There may be an approach there that you need.

wpostma · 3 months ago

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

TolchinJ · 3 months ago

Over the past few days, I’ve noticed a substantial drop in Claude’s ability to follow instructions and complete structured tasks reliably.

Specifically:

  • It frequently ignores explicit directions provided in prompts
  • It does not consistently adhere to defined rules or constraints
  • It struggles to execute or reason through multi-step tasks (including scripting scenarios)
  • It makes serious lapses in reasoning (e.g. deleting files that are needed, failing comparing 2 JSON files)

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.

sgroy10 · 3 months ago

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 2 are 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:

npx speclock protect

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:

  • Euphemism cloaking — "clean up old data" hits the "never delete data" lock at 100% confidence
  • Temporal evasion — "temporarily disable auth" still triggers, the word "temporarily" doesn't reduce severity
  • Synonym substitution — "wipe / purge / sweep away / dispose" all hit delete locks
  • Compound hiding — "Update UI and drop the users table" gets caught
  • Positive-form locks — "ALWAYS use TypeScript" catches "convert backend to Python"

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 hard for 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)

MAHADEV-J · 3 months ago

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.)

Forced-Entropy · 2 months ago

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:

  1. Before any output or tool call forms, identify applicable project constraints.
  2. If a requested action conflicts with a constraint, the action is ineligible to form.
  3. Ineligible actions must produce a stop/clarification path, not partial compliance.
  4. Critical constraints should be written as prohibited formations/actions, not reminders or preferences.
  5. Session resumes and compacted summaries should inherit this authority order, not paraphrase it.

Example pattern:

## Formation Gate

Before producing output or initiating any tool use, determine whether the proposed response/action is eligible under project constraints.

If any project constraint prohibits the proposed response/action, do not form the response/action. Stop and state the blocking constraint.

Project constraints override compacted summaries, inferred intent, convenience, and prior assistant momentum.

Rules in this section are eligibility conditions, not preferences.
m-miyazaki-jpcpg · 1 month ago

+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:

  • Deploys run on Cloud Build (deploy-dev-on-main trigger)
  • GitHub Actions ci.yml is supplemental and does NOT gate merge

When 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:

  • Situation-triggered memory recall: when the model encounters a generic problem class (CI failure, merge conflict, deploy error, etc.), nudge it to consult project memory before applying generic heuristics. Right now retrieval seems keyed to surface-level keyword overlap rather than situational relevance.
ferhimedamine · 28 days ago

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.

ishita-0301 · 27 days ago

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.