Claude Code Not Following CLAUDE.md? Enforce the Guardrail

Claude Code Not Following CLAUDE.md? Enforce the Guardrail

Aident AI

An amber ribbon passes through a violet gate into three turquoise rails that stop a coral shard on a midnight field.

Claude Code Not Following CLAUDE.md? Enforce the Guardrail

If Claude Code keeps apologizing for ignoring a rule in CLAUDE.md, stop making the same sentence louder. First prove that the right file loaded. Then remove conflicts and make the instruction specific. If the rule must block an action every time, move that part to a deterministic control such as a PreToolUse hook, a permission rule, a test, or CI.

That distinction comes directly from Anthropic's current documentation: Claude treats CLAUDE.md as context, not enforced configuration. A clear instruction can improve behavior, but it cannot turn a model decision into a hard boundary.

Use this guide to separate a missing instruction, a weak instruction, and a missing enforcement point.

Start with one failed rule

Do not debug an entire instruction hierarchy at once. Write down one observable failure:

Repository policy: use pnpm, not npm, for dependency changes.
Observed failure: Claude ran npm install and created package-lock.json

A useful failure statement names the expected behavior, the observed behavior, and the artifact or command that proves the difference. "Claude forgot my guardrails" is real frustration, but it is not yet a test.

Keep the working tree clean or save its current state before the diagnostic:

git status --short
git rev-parse --show-toplevel

The repository root matters because Claude Code loads project instructions relative to the directory where the session starts.

1. Confirm that the intended file loaded

Start a fresh Claude Code session from the same directory where the failure occurred. Run:

/context

Check the Memory files list for the exact project CLAUDE.md, any CLAUDE.local.md, and applicable files under .claude/rules/.

Anthropic documents several loading behaviors that often explain an apparent violation:

  • CLAUDE.md and CLAUDE.local.md in the current directory and its parents load at session start.

  • Instruction files in subdirectories load when Claude reads files in those directories.

  • All discovered instruction files are concatenated; a nearer file does not erase a broader one.

  • AGENTS.md is not read automatically unless a CLAUDE.md imports it through the supported @AGENTS.md syntax.

  • Conversation-only instructions can be summarized away, while the project-root CLAUDE.md is re-read after compaction.

If the file is missing from /context, fix its location or launch directory before rewriting it. Use /memory to open the files Claude knows about. For a difficult path-scoping problem, Anthropic also documents the InstructionsLoaded hook, which can log which instruction file loaded, when, and why.

2. Remove conflicts before adding more words

Search every instruction source that can apply to the same behavior:

find .. \( -name CLAUDE.md -o -name CLAUDE.local.md \) -print
find .claude/rules -type f -name '*.md' -print 2>/dev/null
rg -n -i 'npm|pnpm|package manager' CLAUDE.md .claude 2>/dev/null

Classify each matching statement:

Result

Meaning

Next move

The intended rule never loaded

Scope problem

Move it to the correct project or path scope

Two loaded rules disagree

Conflict problem

Choose one source of truth and remove the duplicate

The rule is vague

Specification problem

State one observable command or output

The rule is clear but occasionally ignored

Model-adherence limit

Add a deterministic control if the outcome is mandatory

Prefer this:

- Use `pnpm` for dependency changes. Do not run `npm install` or create `package-lock.json`

Over this:

- Always be careful to follow the repository's preferred package-management
  conventions and avoid unnecessary lockfile changes

Anthropic recommends concise, specific, non-conflicting instructions and currently suggests keeping each CLAUDE.md under 200 lines. Splitting a long file into unconditional imports may improve organization, but imported text still consumes context at launch.

For a full cleanup workflow, use How to Audit CLAUDE.md for Newer Claude Code Models. That guide owns instruction quality and scope. This guide owns the next decision: whether the rule needs enforcement.

3. Choose guidance or enforcement explicitly

Use CLAUDE.md for durable context that should guide judgment:

  • the package manager and normal commands;

  • architecture boundaries and sources of truth;

  • repository-specific review expectations;

  • where specialized procedures live.

Use a deterministic control when a failure must be stopped or detected:

  • a permission rule for a broad tool or path restriction;

  • a PreToolUse hook to inspect and deny a matching tool call before it runs;

  • a PostToolUse hook to run a check after a successful call;

  • a pre-commit check or CI job to reject an invalid repository outcome;

  • an operating-system or platform permission when the boundary is security-sensitive.

Do not call a prompt a security boundary. Also do not call one narrow string matcher a complete sandbox. The control must cover every route that can create the forbidden outcome.

4. Add one narrow PreToolUse hook

Suppose this repository uses pnpm and the immediate regression is npm install. Add a project hook in .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(npm install)",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/deny-npm-install.sh",
            "args": []
          },
          {
            "type": "command",
            "if": "Bash(npm install *)",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/deny-npm-install.sh",
            "args": []
          }
        ]
      }
    ]
  }
}

This macOS and Linux example requires jq on the hook process's PATH. Create .claude/hooks/deny-npm-install.sh:

#!/bin/bash

jq -n '{
  hookSpecificOutput: {
    hookEventName: "PreToolUse",
    permissionDecision: "deny",
    permissionDecisionReason: "This repository uses pnpm. Run the equivalent pnpm command."
  }
}'

Make it executable:

chmod +x .claude/hooks/deny-npm-install.sh

Start a fresh disposable session and ask Claude to run bare npm install, then one harmless example with a package argument. Expected result: both hook handlers return a deny decision before Bash executes, and Claude sees the repository-specific reason.

This example is intentionally narrow. It does not catch aliases such as npm i, shell indirection, another tool that writes the lockfile, or a human running npm. If those routes matter, enumerate them deliberately or enforce the outcome with a repository check.

5. Add an outcome check that the model cannot reinterpret

For the package-manager example, a repository check can fail when package-lock.json appears:

test ! -e package-lock.json

Run it in the same validation path that protects normal changes, such as a checked-in test command, pre-commit hook, or required CI job. Also verify the expected lockfile remains present:

test -e pnpm-lock.yaml

The layers now have different jobs:

  1. CLAUDE.md tells Claude which tool to use and why.

  2. PreToolUse stops one known bad command before execution.

  3. The repository check detects the forbidden outcome regardless of who created it.

  4. CI protects the merge boundary for every contributor and automation path.

If the policy involves secrets, production access, destructive filesystem operations, or compliance, involve the system that actually owns that boundary. A local agent hook is useful defense in depth, not a replacement for service-side authorization or protected infrastructure.

6. Test the failure, not the apology

Use a disposable branch or worktree. Run three cases:

Test

Expected result

Ask for the approved pnpm command

The command is allowed

Ask for npm install

The hook denies it before execution

Create package-lock.json through another controlled test path

The repository check fails

Then inspect the evidence:

git status --short
test ! -e package-lock.json
test -e pnpm-lock.yaml

Success is not Claude saying it understands. Success is the approved path working, the known bad path being denied, and the invalid repository state failing independently.

Audit the guardrail from a pinned GitHub revision

Aident Loadout can read the instruction and enforcement files from a connected GitHub repository without changing them. Pin the review to a commit so the files cannot drift while you compare them.

Start with:

Follow https://aident.ai/SETUP.md

Then ask:

Confirm Aident Loadout authentication and Vault status. Search the current catalog for connected GitHub file and tree read Actions, inspect their schemas, and preflight a zero-write review. At one commit SHA, read CLAUDE.md, list .claude/rules, .claude/hooks, and relevant CI workflow paths, and classify each requirement as model guidance, pre-action enforcement, post-action verification, or merge-time enforcement. Flag mandatory rules that exist only as prose and conflicting instructions that can load together. Do not edit files, create issues, comment, open a pull request, change settings, or reveal secrets.

The result is measurable: one pinned revision, one inventory of loaded guidance and deterministic controls, and zero provider writes.

Set up Aident Loadout and audit Claude Code guardrails

Continue with Claude Code Hook Exit 127? Restore PATH Safely if the hook itself cannot find its command.

Sources

Community reports establish recurring user language, not a universal model defect. Refresh this guide when Anthropic changes instruction loading, hook matchers or decision output, compaction behavior, managed settings, or its official enforcement guidance.

Home

Home

Home

Integrations

Integrations

Integrations

Vault

Vault

Vault

Audit

Audit

Audit

Arana Grande

Arana Grande

Arana Grande

Free

Free

Free

30-day audit summary

30-day audit summary

30-day audit summary

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

Daily action-call volume and the latest receipts from the Loadout audit trail.

View Audit

View Audit

View Audit

Loadout usage

Loadout usage

Loadout usage

617 action calls in the last 30 days

617 action calls in the last 30 days

617 action calls in the last 30 days

May 19 - Jun 17

May 19 - Jun 17

May 19 - Jun 17

10 active days

10 active days

10 active days

Less

Less

Less

More

More

More

Recent activity

Recent activity

Recent activity

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Latest action-call receipts from connected agents

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Apr 23, 09:23 AM

Shopify

Shopify

Shopify

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Creates Or Updates An Asset For A Theme

Success

Success

Success

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Apr 23, 09:21 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Success

Success

Success

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Apr 23, 08:53 AM

Shopify

Shopify

Shopify

Update Products Param Product Id

Update Products Param Product Id

Update Products Param Product Id

Failed

Failed

Failed

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Apr 22, 22:13 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Apr 22, 22:12 PM

Shopify

Shopify

Shopify

Create Product Image

Create Product Image

Create Product Image

Success

Success

Success

Connected integration coverage

Connected integration coverage

Connected integration coverage

162

162

162

of 753 accessible connected

of 753 accessible connected

of 753 accessible connected

Callable actions

Callable actions

Callable actions

1,126

1,126

1,126

Vault credentials

Vault credentials

Vault credentials

8

8

8

Explore what's possible

Explore what's possible

Explore what's possible

See all Integrations

See all Integrations

See all Integrations

Google Ads

Google Ads

Google Ads

All available Goolge Ads tools via...

All available Goolge Ads tools via...

All available Goolge Ads tools via...

X (twitter)

X (twitter)

X (twitter)

All available X tools via...

All available X tools via...

All available X tools via...

Github

Github

Github

All available Github tools via...

All available Github tools via...

All available Github tools via...

Notion

Notion

Notion

All available Notion tools via...

All available Notion tools via...

All available Notion tools via...

Slack

Slack

Slack

All available Slack tools via...

All available Slack tools via...

All available Slack tools via...

Firecrawl

Firecrawl

Firecrawl

All available Firecrawl tools via...

All available Firecrawl tools via...

All available Firecrawl tools via...

753 integrations are available for loadouts.

753 integrations are available for loadouts.

753 integrations are available for loadouts.

The one tool

for every tool

your agent needs.

Give any AI agent real capabilities in seconds. Connect 27,000+ tools once, skip the setup headache, and let your agents execute.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.

Try Aident Loadout

Empower your Codex or OpenClaws to get real jobs done. Connect 27,000+ tools in one prompt, and let your agents deliver real results.