{"slug": "your-claude-md-might-not-be-loading-i-built-a-check-up-for-that", "title": "Your CLAUDE.md Might Not Be Loading — I Built a Check-Up for That", "summary": "A developer built rules-doctor, a zero-dependency Python CLI that statically simulates Claude Code's rule-loading pipeline to diagnose why CLAUDE.md and AGENTS.md rule files silently fail to load. The tool runs three check suites covering @import resolution up to four hops deep, AGENTS.md files shadowed by a neighboring CLAUDE.md, and oversized rule files, returning a 0-100 score with concrete fix suggestions and a --fail-on error flag for CI. The author cautions it is a heuristic simulation rather than the actual loader, since Anthropic does not publish the loading algorithm.", "body_md": "You spent an hour writing the perfect `CLAUDE.md`. Project conventions, the commands that actually work, the gotchas that burned you last month. You open Claude Code, ask it to do the thing, and it does the exact thing your rules told it not to do.\n\nBefore you blame the model, consider a more embarrassing possibility: **your rules were never loaded.**\n\n**1. The `@import` inside a code block.** Claude Code expands `@path/to/file` references in your rule files. But if you documented the import *inside a fenced code block* — showing someone the syntax, for example — it's rendered as literal text and never expanded. Silent no-op. Same story for imports pointing at files that don't exist, or chains nested so deep they get dropped.\n\n**2. The shadowed `AGENTS.md`.** When `CLAUDE.md` and `AGENTS.md` sit in the same directory, only `CLAUDE.md` is loaded. Your carefully maintained `AGENTS.md`? Ignored completely, no warning. (This one bit enough people that it got its own blog post: *\"Fix: Claude Code ignores AGENTS.md\"*.)\n\n**3. The 300-line rule file.** Past a certain size, models start dropping or deprioritizing rules. Nobody knows the exact cliff — it varies by model — but a rule file with 150+ instructions is asking to be skimmed.\n\nI kept hitting variants of all three, so I built **rules-doctor**: a tiny zero-dependency Python CLI that statically simulates Claude Code's rule-loading pipeline and gives your project a check-up.\n\n```\npip install rules-doctor\nrules-doctor ~/my-project\n```\n\nIt discovers every rule file (`CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md`, `.claude/`, plus other-ecosystem files for awareness), then runs three check suites:\n\n`@import` s up to 4 hops deep; flags dead imports inside code fences, broken paths, circular chains, and imports escaping the project root.`AGENTS.md` shadowed by a neighboring `CLAUDE.md`, plus stray nested rule files that only load when that subdirectory is your cwd.`len // 4` rule of thumb) and counts instruction lines; warns past ~150 lines or ~8k tokens of always-loaded rules.\nEvery finding comes with a concrete fix suggestion, and you get a 0–100 score with a letter grade. There's a `--fail-on error` flag for CI if you want to keep your team's rule files honest.\n\n```\nrules-doctor report: /home/hao/my-project\nScore: 70/100 (C)\n\n[ERROR] SHADOWED_AGENTS_MD -- AGENTS.md\n  (project root): AGENTS.md is shadowed by CLAUDE.md -- when both exist,\n  only CLAUDE.md is loaded and AGENTS.md is silently ignored.\n  Fix: Keep a single source of truth: merge the AGENTS.md rules into\n  CLAUDE.md (or vice versa) and delete the other file.\n\n[WARN] DEAD_IMPORT -- CLAUDE.md\n  Dead @import at CLAUDE.md:42: '@rules/deploy.md' sits inside a fenced\n  code block, so it is rendered as literal text and never expanded.\n  Fix: Move the import out of the code fence onto its own line.\n```\n\nThis is a **static heuristic simulation, not the Claude Code loader**. Anthropic doesn't publish the exact loading algorithm, and it changes between versions — so the shadowing model is inferred from observed behavior, the 4-hop limit is a best-effort guess, and the ~150-line bloat line is a heuristic, not a measured cliff. The README has a full \"Honest limitations\" section. When a finding looks suspicious, verify with the real thing (`--debug` shows what was actually loaded).\n\nThat said: in practice, the failure modes it catches are the boring, embarrassing ones — the typo'd import path, the duplicated `AGENTS.md` nobody deleted, the rule file that quietly tripled in size. Those are exactly the ones worth automating away.\n\n`pip install rules-doctor`\nIf it catches something real in your project, I'd love to hear about it — that's how the heuristics get better. And if you know the actual loader semantics for an edge case I got wrong, open an issue with a minimal repro.", "url": "https://wpnews.pro/news/your-claude-md-might-not-be-loading-i-built-a-check-up-for-that", "canonical_source": "https://dev.to/haoli/your-claudemd-might-not-be-loading-i-built-a-check-up-for-that-4a6a", "published_at": "2026-10-02 09:56:22+00:00", "updated_at": "2026-10-02 10:07:46.449348+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-tools", "ai-products"], "entities": ["Claude Code", "Anthropic", "rules-doctor"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/your-claude-md-might-not-be-loading-i-built-a-check-up-for-that", "markdown": "https://wpnews.pro/news/your-claude-md-might-not-be-loading-i-built-a-check-up-for-that.md", "text": "https://wpnews.pro/news/your-claude-md-might-not-be-loading-i-built-a-check-up-for-that.txt", "jsonld": "https://wpnews.pro/news/your-claude-md-might-not-be-loading-i-built-a-check-up-for-that.jsonld"}}